diff options
Diffstat (limited to 'vcl/source/app')
-rw-r--r-- | vcl/source/app/brand.cxx | 81 | ||||
-rw-r--r-- | vcl/source/app/dbggui.cxx | 2032 | ||||
-rw-r--r-- | vcl/source/app/dndhelp.cxx | 184 | ||||
-rw-r--r-- | vcl/source/app/help.cxx | 790 | ||||
-rw-r--r-- | vcl/source/app/i18nhelp.cxx | 190 | ||||
-rw-r--r-- | vcl/source/app/idlemgr.cxx | 153 | ||||
-rw-r--r-- | vcl/source/app/makefile.mk | 71 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 146 | ||||
-rw-r--r-- | vcl/source/app/session.cxx | 372 | ||||
-rw-r--r-- | vcl/source/app/settings.cxx | 2103 | ||||
-rw-r--r-- | vcl/source/app/solarmutex.cxx | 57 | ||||
-rw-r--r-- | vcl/source/app/sound.cxx | 54 | ||||
-rw-r--r-- | vcl/source/app/stdtext.cxx | 69 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 2087 | ||||
-rw-r--r-- | vcl/source/app/svdata.cxx | 534 | ||||
-rw-r--r-- | vcl/source/app/svmain.cxx | 631 | ||||
-rw-r--r-- | vcl/source/app/svmainhook.cxx | 119 | ||||
-rw-r--r-- | vcl/source/app/timer.cxx | 381 | ||||
-rw-r--r-- | vcl/source/app/unohelp.cxx | 241 | ||||
-rw-r--r-- | vcl/source/app/unohelp2.cxx | 115 | ||||
-rw-r--r-- | vcl/source/app/vclevent.cxx | 153 |
21 files changed, 10563 insertions, 0 deletions
diff --git a/vcl/source/app/brand.cxx b/vcl/source/app/brand.cxx new file mode 100644 index 000000000000..0a6e9241e3a2 --- /dev/null +++ b/vcl/source/app/brand.cxx @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is + * Novell, Inc. + * Portions created by the Initial Developer are Copyright (C) 2010 the + * Initial Developer. All Rights Reserved. + * + * Contributor(s): Michael Meeks <michael.meeks@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include <rtl/ustring.hxx> +#include <rtl/bootstrap.hxx> +#include <rtl/locale.hxx> +#include <osl/process.h> +#include <tools/urlobj.hxx> +#include <tools/stream.hxx> +#include <vcl/pngread.hxx> +#include <vcl/svapp.hxx> + +namespace { + static bool loadPng(const char *pPath, const rtl::OUString &rName, BitmapEx &rBitmap) + { + rtl::OUString uri = rtl::OUString::createFromAscii( pPath ) + rName; + rtl::Bootstrap::expandMacros( uri ); + INetURLObject aObj( uri ); + SvFileStream aStrm( aObj.PathToFileName(), STREAM_STD_READ ); + if ( !aStrm.GetError() ) { + vcl::PNGReader aReader( aStrm ); + rBitmap = aReader.Read(); + return !rBitmap.IsEmpty(); + } + else + return false; + } +} + +bool Application::LoadBrandBitmap (const char* pName, BitmapEx &rBitmap) +{ + // TODO - if we want more flexibility we could add a branding path + // in an rc file perhaps fallback to "about.bmp" + rtl::OUString aBaseName = ( rtl::OUString::createFromAscii( "/" ) + + rtl::OUString::createFromAscii( pName ) ); + rtl::OUString aPng( RTL_CONSTASCII_USTRINGPARAM(".png") ); + + rtl_Locale *pLoc = NULL; + osl_getProcessLocale (&pLoc); + rtl::OLocale aLoc( pLoc ); + + rtl::OUString aName = aBaseName + aPng; + rtl::OUString aLocaleName = ( aBaseName + rtl::OUString::createFromAscii ("-") + + aLoc.getLanguage() + + rtl::OUString::createFromAscii ("_") + + aLoc.getCountry() + aPng ); + + return ( loadPng ("$BRAND_BASE_DIR/program/edition", aLocaleName, rBitmap) || + loadPng ("$BRAND_BASE_DIR/program", aLocaleName, rBitmap) || + loadPng ("$BRAND_BASE_DIR/program/edition", aName, rBitmap) || + loadPng ("$BRAND_BASE_DIR/program", aName, rBitmap) ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/dbggui.cxx b/vcl/source/app/dbggui.cxx new file mode 100644 index 000000000000..9bfb6d2d5bab --- /dev/null +++ b/vcl/source/app/dbggui.cxx @@ -0,0 +1,2032 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include <sal/config.h> + +#ifdef DBG_UTIL + +#include <cstdio> +#include <cstring> +#include <cmath> +#include <limits.h> + +#include <vcl/svdata.hxx> +#include <svsys.h> + +#ifdef WNT +#undef min +#endif +#include <tools/debug.hxx> +#include <vcl/svdata.hxx> +#include <vcl/svapp.hxx> +#include <vcl/event.hxx> +#include <vcl/lstbox.hxx> +#include <vcl/button.hxx> +#include <vcl/edit.hxx> +#include <vcl/fixed.hxx> +#include <vcl/group.hxx> +#include <vcl/field.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/sound.hxx> +#include <vcl/threadex.hxx> +#include <vcl/dbggui.hxx> +#include <com/sun/star/i18n/XCharacterClassification.hpp> + +#include <vcl/unohelp.hxx> +#include <vcl/unohelp2.hxx> +#include <osl/mutex.hxx> + +#include <map> +#include <algorithm> + +using namespace ::com::sun::star; + +// ======================================================================= + +static const sal_Char* pDbgHelpText[] = +{ +"Object Test\n", +"------------------------------------------\n", +"\n", +"--- Macros ---\n", +"DBG_NAME( aName )\n", +"Defines the administration data for a class. This macro may only be used " +" in a source file with the same name.\n", +"\n", +"DBG_NAMEEX( aName )\n", +"Like DBG_NAME, only for other source files.\n", +"\n", +"DBG_CTOR( aName, fTest )\n", +"Must be used in all constructors of a class (also in the CopyCtor). " +"The first parameter must be the registered name (best would be the " +"class name) and the second parameter the test function or 0.\n", +"\n", +"DBG_DTOR( aName, fTest )\n", +"Must be used in the destructor of the class. The first parameter is " +"the registered name and the second parameter is the test function or " +"0.\n", +"\n", +"DBG_CHKTHIS( aName, fTest )\n", +"Can be used in methods of the class when constructors and the " +"desctructor of the class are equiped with the corresponding macros. " +"The first parameter is the registered name, the second parameter is " +"the test function or 0.\n", +"\n", +"DBG_CHKOBJ( pObj, aName, fTest )\n", +"Can be used on instances of a class where the constructors and the " +"destructor of the class are equiped with the corresponding macros. " +"The first parameter is the registered name, the second parameter is " +"the test function or 0.\n", +"\n", +"To make the macros work DBG_UTIL must be defined.\n", +"\n", +"--- Options ---\n", +"This\n", +"The This pointer is validated. This way all objects that are equiped " +"with it can be tested to make sure one is working with existing objects. " +"This way it's easier to find bugs in case of multiple inheritence, " +"alignment or compiler errors. Since almost all standard classes of SV " +"(String, List, Pen, Brush, Polygon, ...) are equiped with DBG_CHKTHIS() " +"a lot of errors are found, although this test will impact performance " +"accordingly.\n", +"\n", +"Function\n", +"When a function is passed with macros, it will be called.\n", +"\n", +"Exit\n", +"This- and Func-Test will also run when exiting the function.\n", +"\n", +"Report\n", +"At the end of the program the number of generated objects is produced " +"as output. Because all important SV classes have at least DBG_CTOR() / " +"DBG_DTOR() it can checked so called resource leaks (system objects which " +" are not freed) exist. These include OutputDevice, Window, VirtualDevice, " +" Printer and Menu. Note: Dtor calls of static objects are not taken into " +" account. Therefor each SV program leaves 2 strings and a bitmap behind.\n", +"\n", +"Trace\n", +"Creation, destruction and usage of objects which are equiped with " +"DBG_XTOR is logged.\n", +"\n", +"\n", +"Memory Test\n", +"------------------------------------------\n", +"\n", +"--- Macros ---\n", +"DBG_MEMTEST()\n", +"Run the specified memory tests.\n", +"\n", +"DBG_MEMTEST_PTR( p )\n", +"Runs the specified memory tests and validates the pointer that was " +"passed if the pointer test is enabled.\n", +"\n", +"--- Options ---\n", +"Initialize\n", +"Allocated memory is initialized with 0x77 and free or freed memory " +"is initialized with 0x33. This option has almost no impact on performance " +"and should thus always be enabled during development. This will also " +"make crashes more often reproducable.\n", +"\n", +"Overwrite\n", +"This test check whether writes occur before or after the blocks. Before " +"and after the block memory is initialized with 0x55. This option costs " +"performance, but should be enabled once in a while to test for common " +"memory overwrites (+-1 errors). This option should also be enabled if the " +"program crashes in a new or delete operator.\n", +"\n", +"Free\n", +"This checks whether writes occur in free memory. This option costs lots " +" of performance and should thus only be used to test memory overwrites. " +" This option should perhaps also be enabled when the program crashes " +" in the new or delete operator.\n", +"\n", +"Pointer\n", +"The pointer is tested with delete and DBG_MEMTEST_PTR() to see if it was " +"created by new or SvMemAlloc(). When this option is enabled errors such as " +"double deletes, deletes on stack objects or invalid pointers will be found. " +"This option has an impact on performance and should therefor not be enabled " +"all the time. However, testing should be done with this option enabled once " +"in a while, because the memory manager does not always crash with delete and " +"invalid pointers. This option should also be enabled if the program crashes " +"in new or delete operators.\n", +"\n", +"Report\n", +"At the end of the program a small statistic and memory that was not freed are " +"output. Note: memory that is freed by global objects is also included in " +"the leak list.\n", +"\n", +"Trace\n", +"Allocating and freeing memory is logged.\n", +"\n", +"Leak report\n", +"Produces under WNT at the end of the program a list of memory leaks with " +"stack trace. Only blocks which were created inside Application::Execute() " +"are included. When this option and Overwrite are both enabled a memory " +"overwrite results in an attempt to output the stack where the block was " +"created. The output is included in the log file after the error message.\n" +"\n", +"New/Delete\n", +"Memory tests are performed on the entire memory with every new/delet. " +"Warning: this option makes programs very slow and should only be enabled " +"to track memory overwrites. Otherwise it is sufficient to enable " +"seperate options because (if no leak is present) every detectable " +"memory overwrite during run time should be found.\n", +"\n", +"Object Test\n", +"Memory test are performed on the entire memory with every object test. " +"Warning: this option makes programs very slow and should only be enabled " +"to track memory overwrite. Otherwise it is sufficient to enable " +"seperate options because (if no leak is present) every detectable " +"memory overwrite during run time should be found.\n", +"\n", +"Windows 16-bit and debug tests\n", +"Warning: when memory test are enabled (except for Initialize) memory with " +"offset 0 is never (even not in case of >= 64KB) returned. If necessary the " +"tests can be performed with 32-bit versions of the programs. To a certain " +"extend it is sufficient to create 64KB - 64 bytes instead of 64KB because " +"it will never come to a segment overflow.\n", +"Memory and object test should only be enabled when only one SV application " +"is running at one time. Otherwise uncontrolled errors may occur. In this " +"case only the use of 32-bit programs can help." +"\n", +"\n", +"\nOther tests and macros\n", +"------------------------------------------\n", +"\n", +"Profiling\n", +"DBG_PROFSTART() / DBG_PROFSTOP() / DBG_PROFCONTINUE() / DBG_PROFPAUSE() " +"are evaluated and at the end of the program the number of run throughs " +"and the time this took (including calls to children) in milliseconds is " +"output. These macros can be used to check the same function runs over the " +"entire development period, for example the startup speed. The registered name " +"which was registered with DBG_NAME() must be passed to the macros.\n", +"\n", +"Resources\n", +"In case of resource errors an error dialog is produced before the " +"exception handler is called.\n", +"\n", +"Dialog\n", +"FixedTexts, CheckBoxes, TriStateBoxes and RadioButtons are equiped with " +"a different background color to determine the size of the controls. This " +"test also shows whether controls overlap, whether the tab order is correct " +"and whether the mnemonic characters are correctly assigned. With dialogs " +"it is indicated when no default button or no OK/CancelButton is present. " +"These tests are not 100% correct (e.g. too many warnings are given) and " +"do not form any guarantee that all problematic cases are covered. For " +"example only initial and only visible controls are tested. No errors are " +"found which will occur during the use of a dialog.\n", +"\n", +"Bold AppFont\n", +"The application font is set to bold to see if the position of texts is " +"sufficient for other systems or other system settings. With very narrow " +"fonts the dialogs are made wider because they otherwise appear too narrow.\n", +"\n", +"Trace output\n", +"DBG_TRACE() can be use to produce TRACE output. DBG_TRACEFILE() also outputs " +"the file and line number where the macro is located. DBG_TRACE1() to " +"DBG_TRACE5() can be used to produce formatted output (printf format string) " +"Trace output is enabled when the corresponding option is selected in the " +"dropdown list.\n" +"\n", +"Warnings\n", +"DBG_WARNING() can be used to output warnings. DBG_WARNINGFILE() also outputs " +"the file and the line number where the macro is located. DBG_WARNING1() to " +"DBG_WARNING5() can be used to produce formatted output (printf format string). " +"In case you want to have conditional warnings DBG_ASSERTWARNING() can be " +"used. The warning will be produced if the condition was not met. The first " +"parameter is the condition and the second parameter is the message to be " +"produced. Warnings are enabled if the corresponding option is selected in the " +"dropdown box. When none are selected the condition with DBG_ASSERTWARNING() " +"is not evaluated.\n", +"\n", +"Errors\n", +"DBG_ERROR() can be used to produce error messages. DBG_ERRORFILE() also " +"produces the file and the line number where the macro is located. " +"DBG_ERROR1() bis DBG_ERROR5() can be used to produce formatted output " +"(print format string). " +"In case you want to have conditional warnings DBG_ASSERT() can be " +"used. The warning will be produced if the condition was not met. The first " +"parameter is the condition and the second parameter is the message to be " +"produced. Warnings are enabled if the corresponding option is selected in the " +"dropdown box. When none are selected the condition with DBG_ASSERT() " +"is not evaluated.\n", +"\n", +"\n", +"Output\n", +"------------------------------------------\n", +"\n", +"Overwrite - CheckBox\n", +"With every new program start the log file is overwritten if output has been " +"generated.\n", +"\n", +"Include ObjectTest filters\n", +"Only classes which contain one of the indicated filters are evaluated with " +"the object test. Filters are seperated by ';' and are case sensitive. " +"Wildcards are not supported. If no text is indicated the filters are not " +"active.\n", +"\n", +"Exclude ObjectTest filters\n", +"Only classes which do not contain one of the indicated filters are evaluated " +"with the object test. Filters are seperated by ';' and are case sensitive. " +"Wildcards are not supported. If no text is indicated the filters are not " +"active.\n", +"\n", +"Include filters\n", +"Only those texts which include the indicated filters are output. " +"Filters are seperated by ';' and are case sensitive. " +"Wildcards are not supported. The filter is used for all output (except for " +"errors). If no text is indicated the filters are not active.\n", +"\n", +"Exclude filters\n", +"Only those texts which do not include the indicated filters are output. " +"Filters are seperated by ';' and are case sensitive. " +"Wildcards are not supported. The filter is used for all output (except for " +"errors). If no text is indicated the filters are not active.\n", +"\n", +"Furthermore you can indicate where the data will be output:\n", +"\n", +"None\n", +"Output is surpressed.\n", +"\n", +"File\n", +"Outputi n debug file. Filename can be entered in the Editfield.\n", +"\n", +"Window\n", +"Output to a small debug window. The window size is stored if the debug " +"dialog is closed with OK and if the window is visible. Each assertion text can " +"be copied to the clipboard via the context menu of the respective entry.\n", +"\n", +"Shell\n", +"Output to a debug system (Windows debug window) when available or under " +"Unix in the shell window. Otherwise the same as Window.\n", +"\n", +"MessageBox\n", +"Output to a MessageBox. In this case you can select whether the program " +"must be continued, terminated (Application::Abort) or interrupted with " +"CoreDump. Additionally on some systems you get a \"Copy\" button pressing which " +"copies the text of the MessageBox to the clipboard. Because a MessageBox allows " +"further event processing other errors caused by Paint, Activate/Deactivate, " +"GetFocus/LoseFocus can cause more errors or incorrect errors and messages. " +"Therefor the message should also be directed to a file/debugger in case of " +"problems in order to produce the (right) error messages.\n", +"\n", +"TestTool\n", +"When the TestTool runs messages will be redirected inside the TestTool.\n", +"\n", +"Debugger\n", +"Attempt to activate the debugger and produce the message there, in order to " +"always obtain the corresponding stack trace in the debugger.\n", +"\n", +"CoreDump\n", +"Causes a crash\n", +"\n", +"\n", +"Reroute osl messages - Checkbox\n", +"OSL_ASSERT and similar messages can be intercepted by the general DBG GUI\n", +"or handled system specific as per normal handling in the sal library.\n", +"default is to reroute osl assertions\n", +"\n", +"\n", +"Settings\n", +"------------------------------------------\n", +"\n", +"Where by default the INI and LOG file is read and written the following " +"can be set:\n", +"\n", +"WIN/WNT (WIN.INI, Group SV, Default: dbgsv.ini and dbgsv.log):\n", +"INI: dbgsv\n", +"LOG: dbgsvlog\n", +"\n", +"OS2 (OS2.INI, Application SV, Default: dbgsv.ini and dbgsv.log):\n", +"INI: DBGSV\n", +"LOG: DBGSVLOG\n", +"\n", +"UNIX (Environment variable, Default: .dbgsv.init and dbgsv.log):\n", +"INI: DBGSV_INIT\n", +"LOG: DBGSV_LOG\n", +"\n", +"MAC (Default: dbgsv.ini and dbgsv.log):\n", +"INI: not possible\n", +"LOG: only debug dialog settings\n", +"\n", +"The path and file name must always be specified. The name of the log " +"file that was entered in the debug dialog has always priority.\n", +"\n", +"\n", +"Example\n", +"------------------------------------------\n", +"\n", +"DBG_NAME( String );\n", +"\n", +"#ifdef DBG_UTIL\n", +"const sal_Char* DbgCheckString( const void* pString )\n", +"{\n", +" String* p = (String*)pString;\n", +"\n", +" if ( p->mpData->maStr[p->mpData->mnLen] != 0 )\n", +" return \"String damaged: aStr[nLen] != 0\";\n", +"\n", +" return NULL;\n", +"}\n", +"#endif\n", +"\n", +"String::String()\n", +"{\n", +" DBG_CTOR( String, DbgCheckString );\n", +" // ...\n", +"}\n", +"\n", +"String::~String()\n", +"{\n", +" DBG_DTOR( String, DbgCheckString );\n", +" //...\n", +"}\n", +"\n", +"char& String::operator [] ( USHORT nIndex )\n", +"{\n", +" DBG_CHKTHIS( String, DbgCheckString );\n", +" DBG_ASSERT( nIndex <= pData->nLen, \"String::[] : nIndex > Len\" );\n", +"\n", +" //...\n", +"}\n", +"\n", +"USHORT String::Search( const String& rStr, USHORT nIndex ) const\n", +"{\n", +" DBG_CHKTHIS( String, DbgCheckString );\n", +" DBG_CHKOBJ( &rStr, String, DbgCheckString );\n", +"\n", +" //...\n", +"}", +"\n", +NULL +}; + +// ======================================================================= + +namespace +{ + // ------------------------------------------------------------------- + typedef ::std::map< XubString, DbgChannelId > UserDefinedChannels; + UserDefinedChannels& ImplDbgGetUserDefinedChannels() + { + static UserDefinedChannels s_aChannels; + return s_aChannels; + } + + // ------------------------------------------------------------------- + void ImplAppendUserDefinedChannels( ListBox& rList ) + { + const UserDefinedChannels& rChannels = ImplDbgGetUserDefinedChannels(); + for ( UserDefinedChannels::const_iterator channel = rChannels.begin(); + channel != rChannels.end(); + ++channel + ) + { + USHORT nEntryPos = rList.InsertEntry( channel->first ); + rList.SetEntryData( nEntryPos, reinterpret_cast< void* >( channel->second ) ); + } + } + + // ------------------------------------------------------------------- + void ImplSelectChannel( ListBox& rList, ULONG nChannelToSelect, USHORT nPositionOffset ) + { + if ( nChannelToSelect < DBG_OUT_USER_CHANNEL_0 ) + rList.SelectEntryPos( (USHORT)( nChannelToSelect - nPositionOffset ) ); + else + { + for ( USHORT pos = 0; pos < rList.GetEntryCount(); ++pos ) + { + DbgChannelId nChannelId = static_cast< DbgChannelId >( reinterpret_cast<sal_IntPtr>(rList.GetEntryData( pos )) ); + if ( nChannelId == nChannelToSelect ) + { + rList.SelectEntryPos( pos ); + return; + } + } + } + } + // ------------------------------------------------------------------- + DbgChannelId ImplGetChannelId( const ListBox& rList, USHORT nPositionOffset ) + { + USHORT nSelectedChannelPos = rList.GetSelectEntryPos(); + DbgChannelId nSelectedChannel = static_cast< DbgChannelId >( reinterpret_cast<sal_IntPtr>(rList.GetEntryData( nSelectedChannelPos )) ); + if ( nSelectedChannel == 0) + return (DbgChannelId)( nSelectedChannelPos + nPositionOffset ); + return nSelectedChannel; + } +} + +// ======================================================================= + +// ------------- +// - DbgWindow - +// ------------- + +#define DBGWIN_MAXLINES 100 + +class DbgWindow : public WorkWindow +{ +private: + ListBox maLstBox; + +public: + DbgWindow(); + + virtual BOOL Close(); + virtual void Resize(); + virtual long PreNotify( NotifyEvent& rNEvt ); + void InsertLine( const XubString& rLine ); + void Update() { WorkWindow::Update(); maLstBox.Update(); } + +private: + void GetAssertionEntryRange( USHORT nInbetweenEntry, USHORT& nFirst, USHORT& nLast ); +}; + +// ----------------- +// - DbgInfoDialog - +// ----------------- + +class DbgInfoDialog : public ModalDialog +{ +private: + ListBox maListBox; + OKButton maOKButton; + BOOL mbHelpText; + +public: + DbgInfoDialog( Window* pParent, BOOL bHelpText = FALSE ); + + void SetInfoText( const XubString& rStr ); +}; + +// ------------- +// - DbgDialog - +// ------------- + +class DbgDialog : public ModalDialog +{ +private: + CheckBox maXtorThis; + CheckBox maXtorFunc; + CheckBox maXtorExit; + CheckBox maXtorReport; + CheckBox maXtorTrace; + GroupBox maBox1; + + CheckBox maMemInit; + CheckBox maMemOverwrite; + CheckBox maMemOverwriteFree; + CheckBox maMemPtr; + CheckBox maMemReport; + CheckBox maMemTrace; + CheckBox maMemLeakReport; + CheckBox maMemNewDel; + CheckBox maMemXtor; + GroupBox maBox2; + + CheckBox maProf; + CheckBox maRes; + CheckBox maDialog; + CheckBox maBoldAppFont; + GroupBox maBox3; + + Edit maDebugName; + CheckBox maOverwrite; + FixedText maInclClassText; + Edit maInclClassFilter; + FixedText maExclClassText; + Edit maExclClassFilter; + FixedText maInclText; + Edit maInclFilter; + FixedText maExclText; + Edit maExclFilter; + FixedText maTraceText; + ListBox maTraceBox; + FixedText maWarningText; + ListBox maWarningBox; + FixedText maErrorText; + ListBox maErrorBox; + CheckBox maHookOSLBox; + GroupBox maBox4; + + OKButton maOKButton; + CancelButton maCancelButton; + PushButton maInfoButton; + HelpButton maHelpButton; + USHORT mnErrorOff; + +public: + DbgDialog(); + + DECL_LINK( ClickHdl, Button* ); + void RequestHelp( const HelpEvent& rHEvt ); +}; + +// ======================================================================= + +static sal_Char aDbgInfoBuf[12288]; +static sal_Char aDbgOutBuf[DBG_BUF_MAXLEN]; + +// ======================================================================= + +DbgWindow::DbgWindow() : + WorkWindow( NULL, WB_STDWORK ), + maLstBox( this, WB_AUTOHSCROLL ) +{ + DbgData* pData = DbgGetData(); + + maLstBox.Show(); + maLstBox.SetPosPixel( Point( 0, 0 ) ); + + SetOutputSizePixel( Size( 600, 480 ) ); + if ( pData->aDbgWinState ) + { + ByteString aState( pData->aDbgWinState ); + SetWindowState( aState ); + } + + SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "StarView Debug Window" ) ) ); + Show(); + Update(); +} + +// ----------------------------------------------------------------------- + +BOOL DbgWindow::Close() +{ + // remember window position + ByteString aState( GetWindowState() ); + DbgData* pData = DbgGetData(); + strncpy( pData->aDbgWinState, + aState.GetBuffer(), + std::min( sizeof( pData->aDbgWinState ), + size_t(aState.Len() + 1U )) ); + pData->aDbgWinState[ sizeof( pData->aDbgWinState ) - 1 ] = 0; + // and save for next session + DbgSaveData( *pData ); + + delete this; + ImplGetSVData()->maWinData.mpDbgWin = NULL; + return TRUE; +} + +// ----------------------------------------------------------------------- + +void DbgWindow::Resize() +{ + maLstBox.SetSizePixel( GetOutputSizePixel() ); +} + +// ----------------------------------------------------------------------- + +void DbgWindow::GetAssertionEntryRange( USHORT nInbetweenEntry, USHORT& nFirst, USHORT& nLast ) +{ + nFirst = nInbetweenEntry; + while ( nFirst > 0 ) + { + if ( maLstBox.GetEntryData( nFirst ) != NULL ) + break; + --nFirst; + } + USHORT nEntryCount = maLstBox.GetEntryCount(); + nLast = nInbetweenEntry + 1; + while ( nLast < nEntryCount ) + { + if ( maLstBox.GetEntryData( nLast ) != NULL ) + break; + ++nLast; + } +} + +// ----------------------------------------------------------------------- + +long DbgWindow::PreNotify( NotifyEvent& rNEvt ) +{ + if ( rNEvt.GetType() == EVENT_COMMAND ) + { + if ( maLstBox.IsWindowOrChild( rNEvt.GetWindow() ) ) + { + const CommandEvent& rCommand = *rNEvt.GetCommandEvent(); + if ( rCommand.GetCommand() == COMMAND_CONTEXTMENU ) + { + PopupMenu aMenu; + aMenu.InsertItem( 1, String::CreateFromAscii( "copy to clipboard" ) ); + + Point aPos; + if ( rCommand.IsMouseEvent() ) + aPos = rCommand.GetMousePosPixel(); + else + { + Rectangle aEntryRect( maLstBox.GetBoundingRectangle( maLstBox.GetSelectEntryPos() ) ); + aPos = aEntryRect.Center(); + } + USHORT nSelected = aMenu.Execute( rNEvt.GetWindow(), aPos ); + if ( nSelected == 1 ) + { + // search all entries which belong to this assertion + USHORT nAssertionFirst = 0; + USHORT nAssertionLast = 0; + GetAssertionEntryRange( maLstBox.GetSelectEntryPos(), nAssertionFirst, nAssertionLast ); + + // build the string to copy to the clipboard + String sAssertion; + String sLineFeed = String::CreateFromAscii( "\n" ); + sLineFeed.ConvertLineEnd( GetSystemLineEnd() ); + while ( nAssertionFirst < nAssertionLast ) + { + sAssertion += maLstBox.GetEntry( nAssertionFirst++ ); + sAssertion += sLineFeed; + } + + ::vcl::unohelper::TextDataObject::CopyStringTo( sAssertion, GetClipboard() ); + } + } + return 1; // handled + } + } + return WorkWindow::PreNotify( rNEvt ); +} + +// ----------------------------------------------------------------------- + +void DbgWindow::InsertLine( const XubString& rLine ) +{ + XubString aStr = rLine; + aStr.ConvertLineEnd( LINEEND_LF ); + xub_StrLen nPos = aStr.Search( _LF ); + BOOL bFirstEntry = TRUE; + while ( nPos != STRING_NOTFOUND ) + { + if ( maLstBox.GetEntryCount() >= DBGWIN_MAXLINES ) + maLstBox.RemoveEntry( 0 ); + + USHORT nInsertionPos = maLstBox.InsertEntry( aStr.Copy( 0, nPos ) ); + if ( bFirstEntry ) + maLstBox.SetEntryData( nInsertionPos, reinterpret_cast< void* >( 0x00000001 ) ); + bFirstEntry = FALSE; + + aStr.Erase( 0, nPos+1 ); + nPos = aStr.Search( _LF ); + } + if ( maLstBox.GetEntryCount() >= DBGWIN_MAXLINES ) + maLstBox.RemoveEntry( 0 ); + USHORT nInsertionPos = maLstBox.InsertEntry( aStr ); + if ( bFirstEntry ) + maLstBox.SetEntryData( nInsertionPos, reinterpret_cast< void* >( 0x00000001 ) ); + maLstBox.SetTopEntry( DBGWIN_MAXLINES-1 ); + maLstBox.Update(); +} + +// ======================================================================= + +DbgDialog::DbgDialog() : + ModalDialog( NULL, WB_STDMODAL | WB_SYSTEMWINDOW ), + maXtorThis( this ), + maXtorFunc( this ), + maXtorExit( this ), + maXtorReport( this ), + maXtorTrace( this ), + maBox1( this ), + maMemInit( this ), + maMemOverwrite( this ), + maMemOverwriteFree( this ), + maMemPtr( this ), + maMemReport( this ), + maMemTrace( this ), + maMemLeakReport( this ), + maMemNewDel( this ), + maMemXtor( this ), + maBox2( this ), + maProf( this ), + maRes( this ), + maDialog( this ), + maBoldAppFont( this ), + maBox3( this ), + maDebugName( this ), + maOverwrite( this ), + maInclClassText( this ), + maInclClassFilter( this ), + maExclClassText( this ), + maExclClassFilter( this ), + maInclText( this ), + maInclFilter( this ), + maExclText( this ), + maExclFilter( this ), + maTraceText( this ), + maTraceBox( this, WB_DROPDOWN ), + maWarningText( this ), + maWarningBox( this, WB_DROPDOWN ), + maErrorText( this ), + maErrorBox( this, WB_DROPDOWN ), + maHookOSLBox( this ), + maBox4( this ), + maOKButton( this, WB_DEFBUTTON ), + maCancelButton( this ), + maInfoButton( this ), + maHelpButton( this ) +{ + DbgData* pData = DbgGetData(); + MapMode aAppMap( MAP_APPFONT ); + Size aButtonSize = LogicToPixel( Size( 60, 12 ), aAppMap ); + + { + maXtorThis.Show(); + maXtorThis.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "T~his" ) ) ); + if ( pData->nTestFlags & DBG_TEST_XTOR_THIS ) + maXtorThis.Check( TRUE ); + maXtorThis.SetPosSizePixel( LogicToPixel( Point( 10, 15 ), aAppMap ), + aButtonSize ); + } + + { + maXtorFunc.Show(); + maXtorFunc.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Function" ) ) ); + if ( pData->nTestFlags & DBG_TEST_XTOR_FUNC ) + maXtorFunc.Check( TRUE ); + maXtorFunc.SetPosSizePixel( LogicToPixel( Point( 75, 15 ), aAppMap ), + aButtonSize ); + } + + { + maXtorExit.Show(); + maXtorExit.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "E~xit" ) ) ); + if ( pData->nTestFlags & DBG_TEST_XTOR_EXIT ) + maXtorExit.Check( TRUE ); + maXtorExit.SetPosSizePixel( LogicToPixel( Point( 140, 15 ), aAppMap ), + aButtonSize ); + } + + { + maXtorReport.Show(); + maXtorReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Report" ) ) ); + if ( pData->nTestFlags & DBG_TEST_XTOR_REPORT ) + maXtorReport.Check( TRUE ); + maXtorReport.SetPosSizePixel( LogicToPixel( Point( 205, 15 ), aAppMap ), + aButtonSize ); + } + + { + maXtorTrace.Show(); + maXtorTrace.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) ); + if ( pData->nTestFlags & DBG_TEST_XTOR_TRACE ) + maXtorTrace.Check( TRUE ); + maXtorTrace.SetPosSizePixel( LogicToPixel( Point( 270, 15 ), aAppMap ), + aButtonSize ); + } + + { + maBox1.Show(); + maBox1.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Object Tests" ) ) ); + maBox1.SetPosSizePixel( LogicToPixel( Point( 5, 5 ), aAppMap ), + LogicToPixel( Size( 330, 30 ), aAppMap ) ); + } + + { + maMemInit.Show(); + maMemInit.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Initialize" ) ) ); + if ( pData->nTestFlags & DBG_TEST_MEM_INIT ) + maMemInit.Check( TRUE ); + maMemInit.SetPosSizePixel( LogicToPixel( Point( 10, 50 ), aAppMap ), + aButtonSize ); + } + + { + maMemOverwrite.Show(); + maMemOverwrite.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Overwrite" )) ); + if ( pData->nTestFlags & DBG_TEST_MEM_OVERWRITE ) + maMemOverwrite.Check( TRUE ); + maMemOverwrite.SetPosSizePixel( LogicToPixel( Point( 75, 50 ), aAppMap ), + aButtonSize ); + } + + { + maMemOverwriteFree.Show(); + maMemOverwriteFree.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Free" ) ) ); + if ( pData->nTestFlags & DBG_TEST_MEM_OVERWRITEFREE ) + maMemOverwriteFree.Check( TRUE ); + maMemOverwriteFree.SetPosSizePixel( LogicToPixel( Point( 140, 50 ), aAppMap ), + aButtonSize ); + } + + { + maMemPtr.Show(); + maMemPtr.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Pointer" ) ) ); + if ( pData->nTestFlags & DBG_TEST_MEM_POINTER ) + maMemPtr.Check( TRUE ); + maMemPtr.SetPosSizePixel( LogicToPixel( Point( 205, 50 ), aAppMap ), + aButtonSize ); + } + + { + maMemReport.Show(); + maMemReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Report" ) ) ); + if ( pData->nTestFlags & DBG_TEST_MEM_REPORT ) + maMemReport.Check( TRUE ); + maMemReport.SetPosSizePixel( LogicToPixel( Point( 270, 50 ), aAppMap ), + aButtonSize ); + } + + { + maMemTrace.Show(); + maMemTrace.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) ); + if ( pData->nTestFlags & DBG_TEST_MEM_TRACE ) + maMemTrace.Check( TRUE ); + maMemTrace.SetPosSizePixel( LogicToPixel( Point( 10, 65 ), aAppMap ), + aButtonSize ); + } + + { + maMemLeakReport.Show(); + maMemLeakReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Leak-Report" ) ) ); + if ( pData->nTestFlags & DBG_TEST_MEM_LEAKREPORT ) + maMemLeakReport.Check( TRUE ); + maMemLeakReport.SetPosSizePixel( LogicToPixel( Point( 75, 65 ), aAppMap ), + aButtonSize ); + } + + { + maMemNewDel.Show(); + maMemNewDel.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~New/Delete" ) ) ); + if ( pData->nTestFlags & DBG_TEST_MEM_NEWDEL ) + maMemNewDel.Check( TRUE ); + maMemNewDel.SetPosSizePixel( LogicToPixel( Point( 140, 65 ), aAppMap ), + aButtonSize ); + } + + { + maMemXtor.Show(); + maMemXtor.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Ob~ject Test" ) ) ); + if ( pData->nTestFlags & DBG_TEST_MEM_XTOR ) + maMemXtor.Check( TRUE ); + maMemXtor.SetPosSizePixel( LogicToPixel( Point( 205, 65 ), aAppMap ), + aButtonSize ); + } + + { + maBox2.Show(); + maBox2.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Memory Tests" ) ) ); + maBox2.SetPosSizePixel( LogicToPixel( Point( 5, 40 ), aAppMap ), + LogicToPixel( Size( 330, 40 ), aAppMap ) ); + } + + { + maProf.Show(); + maProf.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Profiling" ) ) ); + if ( pData->nTestFlags & DBG_TEST_PROFILING ) + maProf.Check( TRUE ); + maProf.SetPosSizePixel( LogicToPixel( Point( 10, 95 ), aAppMap ), + aButtonSize ); + } + + { + maRes.Show(); + maRes.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Resourcen" ) ) ); + if ( pData->nTestFlags & DBG_TEST_RESOURCE ) + maRes.Check( TRUE ); + maRes.SetPosSizePixel( LogicToPixel( Point( 75, 95 ), aAppMap ), + aButtonSize ); + } + + { + maDialog.Show(); + maDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Dialog" ) ) ); + if ( pData->nTestFlags & DBG_TEST_DIALOG ) + maDialog.Check( TRUE ); + maDialog.SetPosSizePixel( LogicToPixel( Point( 140, 95 ), aAppMap ), + aButtonSize ); + } + + { + maBoldAppFont.Show(); + maBoldAppFont.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Bold AppFont" ) ) ); + if ( pData->nTestFlags & DBG_TEST_BOLDAPPFONT ) + maBoldAppFont.Check( TRUE ); + maBoldAppFont.SetPosSizePixel( LogicToPixel( Point( 205, 95 ), aAppMap ), + aButtonSize ); + maBoldAppFont.SaveValue(); + } + + { + maBox3.Show(); + maBox3.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Test Options" ) ) ); + maBox3.SetPosSizePixel( LogicToPixel( Point( 5, 85 ), aAppMap ), + LogicToPixel( Size( 330, 30 ), aAppMap ) ); + } + + { + maDebugName.Show(); + maDebugName.SetText( XubString( pData->aDebugName, RTL_TEXTENCODING_UTF8 ) ); + maDebugName.SetMaxTextLen( sizeof( pData->aDebugName ) ); + maDebugName.SetPosSizePixel( LogicToPixel( Point( 10, 130 ), aAppMap ), + LogicToPixel( Size( 185, 14 ), aAppMap ) ); + } + + { + maOverwrite.Show(); + maOverwrite.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Overwrite ~File" ) ) ); + if ( pData->bOverwrite ) + maOverwrite.Check( TRUE ); + maOverwrite.SetPosSizePixel( LogicToPixel( Point( 205, 130 ), aAppMap ), + aButtonSize ); + } + + { + maHookOSLBox.Show(); + maHookOSLBox.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Reroute osl debug ~messages" ) ) ); + if ( pData->bHookOSLAssert ) + maHookOSLBox.Check( TRUE ); + maHookOSLBox.SetPosSizePixel( LogicToPixel( Point( 10, 240 ), aAppMap ), + LogicToPixel( Size( 100, 12 ), aAppMap ) ); + } + + { + maInclClassText.Show(); + maInclClassText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Include-ObjectTest-Filter" ) ) ); + maInclClassText.SetPosSizePixel( LogicToPixel( Point( 10, 150 ), aAppMap ), + LogicToPixel( Size( 95, 9 ), aAppMap ) ); + } + + { + maInclClassFilter.Show(); + maInclClassFilter.SetText( XubString( pData->aInclClassFilter, RTL_TEXTENCODING_UTF8 ) ); + maInclClassFilter.SetMaxTextLen( sizeof( pData->aInclClassFilter ) ); + maInclClassFilter.SetPosSizePixel( LogicToPixel( Point( 10, 160 ), aAppMap ), + LogicToPixel( Size( 95, 14 ), aAppMap ) ); + } + + { + maExclClassText.Show(); + maExclClassText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Exclude-ObjectTest-Filter" ) ) ); + maExclClassText.SetPosSizePixel( LogicToPixel( Point( 115, 150 ), aAppMap ), + LogicToPixel( Size( 95, 9 ), aAppMap ) ); + } + + { + maExclClassFilter.Show(); + maExclClassFilter.SetText( XubString( pData->aExclClassFilter, RTL_TEXTENCODING_UTF8 ) ); + maExclClassFilter.SetMaxTextLen( sizeof( pData->aExclClassFilter ) ); + maExclClassFilter.SetPosSizePixel( LogicToPixel( Point( 115, 160 ), aAppMap ), + LogicToPixel( Size( 95, 14 ), aAppMap ) ); + } + + { + maInclText.Show(); + maInclText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Include-Filter" ) ) ); + maInclText.SetPosSizePixel( LogicToPixel( Point( 10, 180 ), aAppMap ), + LogicToPixel( Size( 95, 9 ), aAppMap ) ); + } + + { + maInclFilter.Show(); + maInclFilter.SetText( XubString( pData->aInclFilter, RTL_TEXTENCODING_UTF8 ) ); + maInclFilter.SetMaxTextLen( sizeof( pData->aInclFilter ) ); + maInclFilter.SetPosSizePixel( LogicToPixel( Point( 10, 190 ), aAppMap ), + LogicToPixel( Size( 95, 14 ), aAppMap ) ); + } + + { + maExclText.Show(); + maExclText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Exclude-Filter" ) ) ); + maExclText.SetPosSizePixel( LogicToPixel( Point( 115, 180 ), aAppMap ), + LogicToPixel( Size( 95, 9 ), aAppMap ) ); + } + + { + maExclFilter.Show(); + maExclFilter.SetText( XubString( pData->aExclFilter, RTL_TEXTENCODING_UTF8 ) ); + maExclFilter.SetMaxTextLen( sizeof( pData->aExclFilter ) ); + maExclFilter.SetPosSizePixel( LogicToPixel( Point( 115, 190 ), aAppMap ), + LogicToPixel( Size( 95, 14 ), aAppMap ) ); + } + + { + maTraceText.Show(); + maTraceText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) ); + maTraceText.SetPosSizePixel( LogicToPixel( Point( 10, 210 ), aAppMap ), + LogicToPixel( Size( 95, 9 ), aAppMap ) ); + } + + { + maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) ); + maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) ); + maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) ); + maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) ); + maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) ); + maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) ); + maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) ); + maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "CoreDump" ) ) ); + ImplAppendUserDefinedChannels( maTraceBox ); + ImplSelectChannel( maTraceBox, pData->nTraceOut, 0 ); + maTraceBox.Show(); + maTraceBox.SetPosSizePixel( LogicToPixel( Point( 10, 220 ), aAppMap ), + LogicToPixel( Size( 95, 80 ), aAppMap ) ); + } + + { + maWarningText.Show(); + maWarningText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Warning" ) ) ); + maWarningText.SetPosSizePixel( LogicToPixel( Point( 115, 210 ), aAppMap ), + LogicToPixel( Size( 95, 9 ), aAppMap ) ); + } + + { + maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) ); + maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) ); + maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) ); + maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) ); + maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) ); + maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) ); + maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) ); + maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "CoreDump" ) ) ); + ImplAppendUserDefinedChannels( maWarningBox ); + ImplSelectChannel( maWarningBox, pData->nWarningOut, 0 ); + maWarningBox.Show(); + maWarningBox.SetPosSizePixel( LogicToPixel( Point( 115, 220 ), aAppMap ), + LogicToPixel( Size( 95, 80 ), aAppMap ) ); + } + + { + maErrorText.Show(); + maErrorText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Error" ) ) ); + maErrorText.SetPosSizePixel( LogicToPixel( Point( 220, 210 ), aAppMap ), + LogicToPixel( Size( 95, 9 ), aAppMap ) ); + } + + { + if ( DbgIsAllErrorOut() ) + { + maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) ); + maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) ); + maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) ); + maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) ); + mnErrorOff = 0; + } + else + mnErrorOff = 4; + maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) ); + maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) ); + maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) ); + maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "CoreDump" ) ) ); + ImplAppendUserDefinedChannels( maErrorBox ); + ImplSelectChannel( maErrorBox, pData->nErrorOut, mnErrorOff ); + maErrorBox.Show(); + maErrorBox.SetPosSizePixel( LogicToPixel( Point( 220, 220 ), aAppMap ), + LogicToPixel( Size( 95, 80 ), aAppMap ) ); + } + + { + maBox4.Show(); + maBox4.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Output" ) ) ); + maBox4.SetPosSizePixel( LogicToPixel( Point( 5, 120 ), aAppMap ), + LogicToPixel( Size( 330, 135 ), aAppMap ) ); + } + + { + maOKButton.Show(); + maOKButton.SetClickHdl( LINK( this, DbgDialog, ClickHdl ) ); + maOKButton.SetPosSizePixel( LogicToPixel( Point( 10, 260 ), aAppMap ), + LogicToPixel( Size( 50, 15 ), aAppMap ) ); + } + { + maCancelButton.Show(); + maCancelButton.SetPosSizePixel( LogicToPixel( Point( 70, 260 ), aAppMap ), + LogicToPixel( Size( 50, 15 ), aAppMap ) ); + } + { + maInfoButton.Show(); + maInfoButton.SetClickHdl( LINK( this, DbgDialog, ClickHdl ) ); + maInfoButton.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Info..." ) ) ); + maInfoButton.SetPosSizePixel( LogicToPixel( Point( 130, 260 ), aAppMap ), + LogicToPixel( Size( 50, 15 ), aAppMap ) ); + } + { + maHelpButton.Show(); + maHelpButton.SetPosSizePixel( LogicToPixel( Point( 190, 260 ), aAppMap ), + LogicToPixel( Size( 50, 15 ), aAppMap ) ); + } + + { + SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "VCL Debug Options" ) ) ); + SetOutputSizePixel( LogicToPixel( Size( 340, 280 ), aAppMap ) ); + } +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( DbgDialog, ClickHdl, Button*, pButton ) +{ + if ( pButton == &maOKButton ) + { + DbgData aData; + + memcpy( &aData, DbgGetData(), sizeof( DbgData ) ); + aData.nTestFlags = 0; + + aData.nTraceOut = ImplGetChannelId( maTraceBox, 0 ); + aData.nWarningOut = ImplGetChannelId( maWarningBox, 0 ); + aData.nErrorOut = ImplGetChannelId( maErrorBox, mnErrorOff ); + + strncpy( aData.aDebugName, ByteString( maDebugName.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aDebugName ) ); + strncpy( aData.aInclClassFilter, ByteString( maInclClassFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aInclClassFilter ) ); + strncpy( aData.aExclClassFilter, ByteString( maExclClassFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aExclClassFilter ) ); + strncpy( aData.aInclFilter, ByteString( maInclFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aInclFilter ) ); + strncpy( aData.aExclFilter, ByteString( maExclFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aExclFilter ) ); + aData.aDebugName[sizeof( aData.aDebugName )-1] = '\0'; + aData.aInclClassFilter[sizeof( aData.aInclClassFilter )-1] = '\0'; + aData.aExclClassFilter[sizeof( aData.aExclClassFilter )-1] = '\0'; + aData.aInclFilter[sizeof( aData.aInclFilter )-1] = '\0'; + aData.aExclFilter[sizeof( aData.aExclFilter )-1] = '\0'; + + aData.bOverwrite = maOverwrite.IsChecked() ? TRUE : FALSE; + aData.bHookOSLAssert = maHookOSLBox.IsChecked() ? TRUE : FALSE; + + if ( maXtorThis.IsChecked() ) + aData.nTestFlags |= DBG_TEST_XTOR_THIS; + + if ( maXtorFunc.IsChecked() ) + aData.nTestFlags |= DBG_TEST_XTOR_FUNC; + + if ( maXtorExit.IsChecked() ) + aData.nTestFlags |= DBG_TEST_XTOR_EXIT; + + if ( maXtorReport.IsChecked() ) + aData.nTestFlags |= DBG_TEST_XTOR_REPORT; + + if ( maXtorTrace.IsChecked() ) + aData.nTestFlags |= DBG_TEST_XTOR_TRACE; + + if ( maMemInit.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_INIT; + + if ( maMemOverwrite.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_OVERWRITE; + + if ( maMemOverwriteFree.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_OVERWRITEFREE; + + if ( maMemPtr.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_POINTER; + + if ( maMemReport.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_REPORT; + + if ( maMemTrace.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_TRACE; + + if ( maMemLeakReport.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_LEAKREPORT; + + if ( maMemNewDel.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_NEWDEL; + + if ( maMemXtor.IsChecked() ) + aData.nTestFlags |= DBG_TEST_MEM_XTOR; + + if ( maProf.IsChecked() ) + aData.nTestFlags |= DBG_TEST_PROFILING; + + if ( maRes.IsChecked() ) + aData.nTestFlags |= DBG_TEST_RESOURCE; + + if ( maDialog.IsChecked() ) + aData.nTestFlags |= DBG_TEST_DIALOG; + + if ( maBoldAppFont.IsChecked() ) + aData.nTestFlags |= DBG_TEST_BOLDAPPFONT; + + // Daten speichern + DbgSaveData( aData ); + + // Umschalten der Laufzeitwerte + DBG_INSTOUTTRACE( aData.nTraceOut ); + DBG_INSTOUTWARNING( aData.nWarningOut ); + DBG_INSTOUTERROR( aData.nErrorOut ); + DbgUpdateOslHook( &aData ); + + DbgData* pData = DbgGetData(); + #define IMMEDIATE_FLAGS (DBG_TEST_MEM_INIT | DBG_TEST_RESOURCE | DBG_TEST_DIALOG | DBG_TEST_BOLDAPPFONT) + pData->nTestFlags &= ~IMMEDIATE_FLAGS; + pData->nTestFlags |= aData.nTestFlags & IMMEDIATE_FLAGS; + strncpy( pData->aInclClassFilter, aData.aInclClassFilter, sizeof( pData->aInclClassFilter ) ); + strncpy( pData->aExclClassFilter, aData.aExclClassFilter, sizeof( pData->aExclClassFilter ) ); + strncpy( pData->aInclFilter, aData.aInclFilter, sizeof( pData->aInclFilter ) ); + strncpy( pData->aExclFilter, aData.aExclFilter, sizeof( pData->aExclFilter ) ); + if ( maBoldAppFont.GetSavedValue() != maBoldAppFont.IsChecked() ) + { + AllSettings aSettings = Application::GetSettings(); + StyleSettings aStyleSettings = aSettings.GetStyleSettings(); + Font aFont = aStyleSettings.GetAppFont(); + if ( maBoldAppFont.IsChecked() ) + aFont.SetWeight( WEIGHT_BOLD ); + else + aFont.SetWeight( WEIGHT_NORMAL ); + aStyleSettings.SetAppFont( aFont ); + aSettings.SetStyleSettings( aStyleSettings ); + Application::SetSettings( aSettings ); + } + if( (aData.nTestFlags & ~IMMEDIATE_FLAGS) != (pData->nTestFlags & ~IMMEDIATE_FLAGS) ) + { + InfoBox aBox( this, String( RTL_CONSTASCII_USTRINGPARAM( + "Some of the changed settings will only be active after " + "restarting the process" + ) ) ); + aBox.Execute(); + } + EndDialog( TRUE ); + } + else if ( pButton == &maInfoButton ) + { + DbgInfoDialog aInfoDialog( this ); + aDbgInfoBuf[0] = '\0'; + DbgMemInfo( aDbgInfoBuf ); + DbgXtorInfo( aDbgInfoBuf ); + XubString aInfoText( aDbgInfoBuf, RTL_TEXTENCODING_UTF8 ); + aInfoDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug InfoReport" ) ) ); + aInfoDialog.SetInfoText( aInfoText ); + aInfoDialog.Execute(); + } + + return 0; +} + +// ----------------------------------------------------------------------- + +void DbgDialog::RequestHelp( const HelpEvent& rHEvt ) +{ + if ( rHEvt.GetMode() & HELPMODE_CONTEXT ) + { + DbgInfoDialog aInfoDialog( this, TRUE ); + XubString aHelpText; + const sal_Char** pHelpStrs = pDbgHelpText; + while ( *pHelpStrs ) + { + aHelpText.AppendAscii( *pHelpStrs ); + pHelpStrs++; + } + aInfoDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug Hilfe" ) ) ); + aInfoDialog.SetInfoText( aHelpText ); + aInfoDialog.Execute(); + } +} + +// ======================================================================= + +DbgInfoDialog::DbgInfoDialog( Window* pParent, BOOL bHelpText ) : + ModalDialog( pParent, WB_STDMODAL ), + maListBox( this, WB_BORDER | WB_AUTOHSCROLL ), + maOKButton( this, WB_DEFBUTTON ) +{ + mbHelpText = bHelpText; + + if ( !bHelpText ) + { + Font aFont = GetDefaultFont( DEFAULTFONT_FIXED, LANGUAGE_ENGLISH_US, 0 ); + aFont.SetHeight( 8 ); + aFont.SetPitch( PITCH_FIXED ); + maListBox.SetControlFont( aFont ); + } + maListBox.SetPosSizePixel( Point( 5, 5 ), Size( 630, 380 ) ); + maListBox.Show(); + + maOKButton.SetPosSizePixel( Point( 290, 390 ), Size( 60, 25 ) ); + maOKButton.Show(); + + SetOutputSizePixel( Size( 640, 420 ) ); +} + +// ----------------------------------------------------------------------- + +void DbgInfoDialog::SetInfoText( const XubString& rStr ) +{ + maListBox.SetUpdateMode( FALSE ); + maListBox.Clear(); + XubString aStr = rStr; + aStr.ConvertLineEnd( LINEEND_LF ); + USHORT nStrIndex = 0; + USHORT nFoundIndex; + do + { + nFoundIndex = aStr.Search( _LF, nStrIndex ); + XubString aTextParagraph = aStr.Copy( nStrIndex, nFoundIndex-nStrIndex ); + if ( mbHelpText ) + { + long nMaxWidth = maListBox.GetOutputSizePixel().Width()-30; + USHORT nLastIndex = 0; + USHORT nIndex = aTextParagraph.Search( ' ' ); + while ( nIndex != STRING_NOTFOUND ) + { + if ( maListBox.GetTextWidth( aTextParagraph, 0, nIndex ) > nMaxWidth ) + { + if ( !nLastIndex ) + nLastIndex = nIndex+1; + XubString aTempStr = aTextParagraph.Copy( 0, nLastIndex ); + aTextParagraph.Erase( 0, nLastIndex ); + maListBox.InsertEntry( aTempStr ); + nLastIndex = 0; + } + else + nLastIndex = nIndex+1; + nIndex = aTextParagraph.Search( ' ', nLastIndex ); + } + + if ( maListBox.GetTextWidth( aTextParagraph, 0, nIndex ) > nMaxWidth ) + { + if ( !nLastIndex ) + nLastIndex = nIndex+1; + XubString aTempStr = aTextParagraph.Copy( 0, nLastIndex ); + aTextParagraph.Erase( 0, nLastIndex ); + maListBox.InsertEntry( aTempStr ); + } + } + maListBox.InsertEntry( aTextParagraph ); + nStrIndex = nFoundIndex+1; + } + while ( nFoundIndex != STRING_NOTFOUND ); + maListBox.SetUpdateMode( TRUE ); +} + +// ======================================================================= + +void DbgDialogTest( Window* pWindow ) +{ + BOOL aAccelBuf[65536]; + USHORT nChildCount = pWindow->GetChildCount(); + Window* pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); + Window* pChild; + Point aTabPos; + + if ( !pGetChild ) + return; + + Rectangle* pRectAry = (Rectangle*)new long[(sizeof(Rectangle)*nChildCount)/sizeof(long)]; + memset( aAccelBuf, 0, sizeof( aAccelBuf ) ); + memset( pRectAry, 0, sizeof(Rectangle)*nChildCount ); + + if ( pWindow->IsDialog() ) + { + BOOL bOKCancelButton = FALSE; + BOOL bDefPushButton = FALSE; + BOOL bButton = FALSE; + pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); + while ( pGetChild ) + { + pChild = pGetChild->ImplGetWindow(); + + if ( pChild->ImplIsPushButton() ) + { + bButton = TRUE; + if ( (pChild->GetType() == WINDOW_OKBUTTON) || (pChild->GetType() == WINDOW_CANCELBUTTON) ) + bOKCancelButton = TRUE; + if ( pChild->GetStyle() & WB_DEFBUTTON ) + bDefPushButton = TRUE; + } + + pGetChild = pGetChild->GetWindow( WINDOW_NEXT ); + } + + if ( bButton ) + { + if ( !bOKCancelButton ) + DbgError( "Dialogs should have a OK- or CancelButton" ); + if ( !bDefPushButton ) + DbgError( "Dialogs should have a Button with WB_DEFBUTTON" ); + } + } + + USHORT i = 0; + pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); + while ( pGetChild ) + { + pChild = pGetChild->ImplGetWindow(); + + if ( (pChild->GetType() != WINDOW_TABCONTROL) && + (pChild->GetType() != WINDOW_TABPAGE) && + (pChild->GetType() != WINDOW_GROUPBOX) ) + { + XubString aText = pChild->GetText(); + XubString aErrorText = aText; + USHORT nAccelPos = STRING_NOTFOUND; + xub_Unicode cAccel = 0; + if ( aErrorText.Len() > 128 ) + { + aErrorText.Erase( 128 ); + aErrorText.AppendAscii( "..." ); + } + if ( aText.Len() && (aText.Len() < 1024) ) + { + nAccelPos = aText.Search( '~' ); + if ( nAccelPos != STRING_NOTFOUND ) + { + const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetLocale(); + uno::Reference < i18n::XCharacterClassification > xCharClass = vcl::unohelper::CreateCharacterClassification(); + XubString aUpperText = xCharClass->toUpper( aText, 0, aText.Len(), rLocale ); + cAccel = aUpperText.GetChar( nAccelPos+1 ); + if ( pChild->IsVisible() ) + { + if ( aAccelBuf[cAccel] ) + DbgOutTypef( DBG_OUT_ERROR, "Double mnemonic char: %c", cAccel ); + else + aAccelBuf[cAccel] = TRUE; + } + } + } + + if ( (pChild->GetType() == WINDOW_RADIOBUTTON) || + (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) || + (pChild->GetType() == WINDOW_CHECKBOX) || + (pChild->GetType() == WINDOW_TRISTATEBOX) || + (pChild->GetType() == WINDOW_PUSHBUTTON) ) + { + if ( aText.Len() && !aText.EqualsAscii( "..." ) ) + { + const char* pClass; + if ( pChild->GetType() == WINDOW_RADIOBUTTON ) + pClass = "RadioButton"; + else if ( pChild->GetType() == WINDOW_IMAGERADIOBUTTON ) + pClass = "ImageRadioButton"; + else if ( pChild->GetType() == WINDOW_CHECKBOX ) + pClass = "CheckBox"; + else if ( pChild->GetType() == WINDOW_TRISTATEBOX ) + pClass = "TriStateBox"; + else if ( pChild->GetType() == WINDOW_PUSHBUTTON ) + pClass = "PushButton"; + else + pClass = "Dontknow"; + if( !cAccel ) + DbgOutTypef( DBG_OUT_ERROR, + "%s should have a mnemonic char (~): %s", + pClass, + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + + // check text width + int aWidth=0; + switch( pChild->GetType() ) + { + case WINDOW_RADIOBUTTON: + case WINDOW_IMAGERADIOBUTTON: + aWidth = ((RadioButton*)pChild)->CalcMinimumSize(0).Width(); + break; + case WINDOW_CHECKBOX: + case WINDOW_TRISTATEBOX: + aWidth = ((CheckBox*)pChild)->CalcMinimumSize(0).Width(); + break; + case WINDOW_PUSHBUTTON: + aWidth = ((PushButton*)pChild)->CalcMinimumSize(0).Width(); + break; + default: break; + } + if( pChild->IsVisible() && pChild->GetSizePixel().Width() < aWidth ) + DbgOutTypef( DBG_OUT_ERROR, + "%s exceeds window width: %s", + pClass, + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + } + + if ( pChild->GetType() == WINDOW_FIXEDLINE ) + { + if ( pChild->GetSizePixel().Width() < pChild->GetTextWidth( aText ) ) + DbgOutTypef( DBG_OUT_ERROR, + "FixedLine exceeds window width: %s", + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + + if ( pChild->GetType() == WINDOW_FIXEDTEXT ) + { + if ( (pChild->GetSizePixel().Height() >= pChild->GetTextHeight()*2) && + !(pChild->GetStyle() & WB_WORDBREAK) ) + { + DbgOutTypef( DBG_OUT_ERROR, + "FixedText greater than one line, but WordBreak is not set: %s", + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + + if ( pChild->IsVisible() ) + { + int aWidth=0; + if( nAccelPos != STRING_NOTFOUND ) + { + aWidth = pChild->GetTextWidth( aText, 0, nAccelPos ) + + pChild->GetTextWidth( aText, nAccelPos+1, aText.Len() - nAccelPos - 1); + } + else + aWidth = pChild->GetTextWidth( aText ); + + if ( pChild->GetSizePixel().Width() < aWidth && !(pChild->GetStyle() & WB_WORDBREAK) ) + { + DbgOutTypef( DBG_OUT_ERROR, + "FixedText exceeds window width: %s", + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + } + + if ( (i+1 < nChildCount) && aText.Len() ) + { + Window* pTempChild = pGetChild->GetWindow( WINDOW_NEXT )->ImplGetWindow(); + if ( (pTempChild->GetType() == WINDOW_EDIT) || + (pTempChild->GetType() == WINDOW_MULTILINEEDIT) || + (pTempChild->GetType() == WINDOW_SPINFIELD) || + (pTempChild->GetType() == WINDOW_PATTERNFIELD) || + (pTempChild->GetType() == WINDOW_NUMERICFIELD) || + (pTempChild->GetType() == WINDOW_METRICFIELD) || + (pTempChild->GetType() == WINDOW_CURRENCYFIELD) || + (pTempChild->GetType() == WINDOW_DATEFIELD) || + (pTempChild->GetType() == WINDOW_TIMEFIELD) || + (pTempChild->GetType() == WINDOW_LISTBOX) || + (pTempChild->GetType() == WINDOW_MULTILISTBOX) || + (pTempChild->GetType() == WINDOW_COMBOBOX) || + (pTempChild->GetType() == WINDOW_PATTERNBOX) || + (pTempChild->GetType() == WINDOW_NUMERICBOX) || + (pTempChild->GetType() == WINDOW_METRICBOX) || + (pTempChild->GetType() == WINDOW_CURRENCYBOX) || + (pTempChild->GetType() == WINDOW_DATEBOX) || + (pTempChild->GetType() == WINDOW_TIMEBOX) ) + { + if ( !cAccel ) + { + DbgOutTypef( DBG_OUT_ERROR, + "Labels befor Fields (Edit,ListBox,...) should have a mnemonic char (~): %s", + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + if ( !pTempChild->IsEnabled() && pChild->IsEnabled() ) + { + DbgOutTypef( DBG_OUT_ERROR, + "Labels befor Fields (Edit,ListBox,...) should be disabled, when the field is disabled: %s", + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + } + } + } + + if ( pChild->GetType() == WINDOW_MULTILINEEDIT ) + { + if ( ( 0 == ( pChild->GetStyle() & WB_IGNORETAB ) ) + && ( 0 == ( pChild->GetStyle() & WB_READONLY ) ) + ) + { + DbgError( "editable MultiLineEdits in Dialogs should have the Style WB_IGNORETAB" ); + } + } + + if ( (pChild->GetType() == WINDOW_RADIOBUTTON) || + (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) || + (pChild->GetType() == WINDOW_CHECKBOX) || + (pChild->GetType() == WINDOW_TRISTATEBOX) || + (pChild->GetType() == WINDOW_FIXEDTEXT) ) + { + pChild->SetBackground( Wallpaper( Color( COL_LIGHTGREEN ) ) ); + } + + if ( pChild->IsVisible() ) + { + BOOL bMaxWarning = FALSE; + if ( pChild->GetType() == WINDOW_NUMERICFIELD ) + { + NumericField* pField = (NumericField*)pChild; + if ( pField->GetMax() == LONG_MAX ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_METRICFIELD ) + { + MetricField* pField = (MetricField*)pChild; + if ( pField->GetMax() == LONG_MAX ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_CURRENCYFIELD ) + { + CurrencyField* pField = (CurrencyField*)pChild; + if ( pField->GetMax() == LONG_MAX ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_TIMEFIELD ) + { + TimeField* pField = (TimeField*)pChild; + if ( pField->GetMax() == Time( 23, 59, 59, 99 ) ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_DATEFIELD ) + { + DateField* pField = (DateField*)pChild; + if ( pField->GetMax() == Date( 31, 12, 9999 ) ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_NUMERICBOX ) + { + NumericBox* pBox = (NumericBox*)pChild; + if ( pBox->GetMax() == LONG_MAX ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_METRICBOX ) + { + MetricBox* pBox = (MetricBox*)pChild; + if ( pBox->GetMax() == LONG_MAX ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_CURRENCYBOX ) + { + CurrencyBox* pBox = (CurrencyBox*)pChild; + if ( pBox->GetMax() == LONG_MAX ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_TIMEBOX ) + { + TimeBox* pBox = (TimeBox*)pChild; + if ( pBox->GetMax() == Time( 23, 59, 59, 99 ) ) + bMaxWarning = TRUE; + } + else if ( pChild->GetType() == WINDOW_DATEBOX ) + { + DateBox* pBox = (DateBox*)pChild; + if ( pBox->GetMax() == Date( 31, 12, 9999 ) ) + bMaxWarning = TRUE; + } + if ( bMaxWarning ) + { + DbgOutTypef( DBG_OUT_ERROR, + "No Max-Value is set: %s", + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + + if ( (pChild->GetType() == WINDOW_RADIOBUTTON) || + (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) || + (pChild->GetType() == WINDOW_CHECKBOX) || + (pChild->GetType() == WINDOW_TRISTATEBOX) || + (pChild->GetType() == WINDOW_PUSHBUTTON) || + (pChild->GetType() == WINDOW_OKBUTTON) || + (pChild->GetType() == WINDOW_CANCELBUTTON) || + (pChild->GetType() == WINDOW_HELPBUTTON) || + (pChild->GetType() == WINDOW_IMAGEBUTTON) || + (pChild->GetType() == WINDOW_FIXEDTEXT) || + (pChild->GetType() == WINDOW_EDIT) || + (pChild->GetType() == WINDOW_MULTILINEEDIT) || + (pChild->GetType() == WINDOW_SPINFIELD) || + (pChild->GetType() == WINDOW_PATTERNFIELD) || + (pChild->GetType() == WINDOW_NUMERICFIELD) || + (pChild->GetType() == WINDOW_METRICFIELD) || + (pChild->GetType() == WINDOW_CURRENCYFIELD) || + (pChild->GetType() == WINDOW_DATEFIELD) || + (pChild->GetType() == WINDOW_TIMEFIELD) || + (pChild->GetType() == WINDOW_LISTBOX) || + (pChild->GetType() == WINDOW_MULTILISTBOX) || + (pChild->GetType() == WINDOW_COMBOBOX) || + (pChild->GetType() == WINDOW_PATTERNBOX) || + (pChild->GetType() == WINDOW_NUMERICBOX) || + (pChild->GetType() == WINDOW_METRICBOX) || + (pChild->GetType() == WINDOW_CURRENCYBOX) || + (pChild->GetType() == WINDOW_DATEBOX) || + (pChild->GetType() == WINDOW_TIMEBOX) ) + { + Point aNewPos = pChild->GetPosPixel(); + Rectangle aChildRect( aNewPos, pChild->GetSizePixel() ); + + if ( cAccel || (pChild->GetStyle() & WB_TABSTOP) || + (pChild->GetType() == WINDOW_RADIOBUTTON) || + (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) ) + { + if ( (aNewPos.X() <= aTabPos.X()) && (aNewPos.Y() <= aTabPos.Y()) ) + { + DbgOutTypef( DBG_OUT_ERROR, + "Possible wrong childorder for dialogcontrol: %s", + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + aTabPos = aNewPos; + } + + for ( USHORT j = 0; j < i; j++ ) + { + if ( ((pRectAry[j].Right() != 0) || (pRectAry[j].Bottom() != 0)) && + aChildRect.IsOver( pRectAry[j] ) ) + { + DbgOutTypef( DBG_OUT_ERROR, + "Window overlaps with sibling window: %s", + ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + } + } + pRectAry[i] = aChildRect; + } + } + } + + pGetChild = pGetChild->GetWindow( WINDOW_NEXT ); + i++; + } + + delete [] pRectAry; +} + +// ======================================================================= +#ifndef WNT +#define USE_VCL_MSGBOX +#define COPY_BUTTON_ID 25 + +class DbgMessageBox : public ErrorBox +{ + String m_aMessage; + public: + DbgMessageBox( const String& rMessage ) : + ErrorBox( NULL, WB_YES_NO_CANCEL | WB_DEF_NO, rMessage ), + m_aMessage( rMessage ) + { + SetText( String( RTL_CONSTASCII_USTRINGPARAM("Debug Output") ) ); + AddButton( String( RTL_CONSTASCII_USTRINGPARAM( "Copy" ) ), COPY_BUTTON_ID, 0 ); + } + + virtual void Click() + { + if( GetCurButtonId() == COPY_BUTTON_ID ) + vcl::unohelper::TextDataObject::CopyStringTo( m_aMessage, GetClipboard() ); + else + ErrorBox::Click(); + } +}; + +#endif + +class SolarMessageBoxExecutor : public ::vcl::SolarThreadExecutor +{ +private: + String m_sDebugMessage; + +public: + SolarMessageBoxExecutor( const String& _rDebugMessage ) + :m_sDebugMessage( _rDebugMessage ) + { + } + +protected: + virtual long doIt(); +}; + +long SolarMessageBoxExecutor::doIt() +{ + long nResult = RET_NO; + + // Tracking beenden und Mouse freigeben, damit die Boxen nicht haengen + ImplSVData* pSVData = ImplGetSVData(); + if ( pSVData->maWinData.mpTrackWin ) + pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL ); + if ( pSVData->maWinData.mpCaptureWin ) + pSVData->maWinData.mpCaptureWin->ReleaseMouse(); + +#if ! defined USE_VCL_MSGBOX +#ifdef WNT + BOOL bOldCallTimer = pSVData->mbNoCallTimer; + pSVData->mbNoCallTimer = TRUE; + MessageBeep( MB_ICONHAND ); + nResult = MessageBoxW( 0, (LPWSTR)m_sDebugMessage.GetBuffer(), L"Debug Output", + MB_TASKMODAL | MB_YESNOCANCEL | MB_DEFBUTTON2 | MB_ICONSTOP ); + pSVData->mbNoCallTimer = bOldCallTimer; + switch ( nResult ) + { + case IDYES: + nResult = RET_YES; + break; + case IDNO: + nResult = RET_NO; + break; + case IDCANCEL: + nResult = RET_CANCEL; + break; + } +#endif // WNT +#else + USHORT nOldMode = Application::GetSystemWindowMode(); + Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE ); + DbgMessageBox aBox( m_sDebugMessage ); + Application::SetSystemWindowMode( nOldMode ); + nResult = aBox.Execute(); +#endif + + return nResult; +} + +void DbgPrintMsgBox( const char* pLine ) +{ + // are modal message boxes prohibited at the moment? + if ( Application::IsDialogCancelEnabled() ) + { +#if defined( WNT ) + // TODO: Shouldn't this be a IsDebuggerPresent()? + if ( GetSystemMetrics( SM_DEBUG ) ) + { + MessageBeep( MB_ICONHAND ); + strcpy( aDbgOutBuf, pLine ); + strcat( aDbgOutBuf, "\r\n" ); + OutputDebugString( aDbgOutBuf ); + return; + } +#endif + + Sound::Beep( SOUND_ERROR ); +#ifdef UNX + fprintf( stderr, "%s\n", pLine ); + return; +#else + DbgPrintFile( pLine ); + return; +#endif + } + + strcpy( aDbgOutBuf, pLine ); + strcat( aDbgOutBuf, "\nAbort ? (Yes=abort / No=ignore / Cancel=core dump)" ); + + SolarMessageBoxExecutor aMessageBox( String( aDbgOutBuf, RTL_TEXTENCODING_UTF8 ) ); + TimeValue aTimeout; aTimeout.Seconds = 2; aTimeout.Nanosec = 0; + long nResult = aMessageBox.execute( aTimeout ); + + if ( aMessageBox.didTimeout() ) + DbgPrintShell( pLine ); + else if ( nResult == RET_YES ) + GetpApp()->Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug-Utilities-Error" ) ) ); + else if ( nResult == RET_CANCEL ) + DbgCoreDump(); +} + +// ----------------------------------------------------------------------- + +class SolarWindowPrinter : public ::vcl::SolarThreadExecutor +{ +private: + String m_sDebugMessage; + +public: + SolarWindowPrinter( const String& _rDebugMessage ) + :m_sDebugMessage( _rDebugMessage ) + { + } + +protected: + virtual long doIt(); +}; + +long SolarWindowPrinter::doIt() +{ + DbgWindow* pDbgWindow = ImplGetSVData()->maWinData.mpDbgWin; + if ( !pDbgWindow ) + { + pDbgWindow = new DbgWindow; + ImplGetSVData()->maWinData.mpDbgWin = pDbgWindow; + } + pDbgWindow->InsertLine( m_sDebugMessage ); + + return 0L; +} + +// ----------------------------------------------------------------------- + +void DbgPrintWindow( const char* pLine ) +{ + static BOOL bIn = FALSE; + + // keine rekursiven Traces + if ( bIn ) + return; + bIn = TRUE; + + SolarWindowPrinter aPrinter( String( pLine, RTL_TEXTENCODING_UTF8 ) ); + TimeValue aTimeout; aTimeout.Seconds = 2; aTimeout.Nanosec = 0; + aPrinter.execute( aTimeout ); + + if ( aPrinter.didTimeout() ) + DbgPrintShell( pLine ); + + bIn = FALSE; +} + +// ======================================================================= + +#ifdef WNT +void ImplDbgTestSolarMutex(); +#endif + +// ======================================================================= + +void DbgGUIInit() +{ + DbgSetPrintMsgBox( DbgPrintMsgBox ); + DbgSetPrintWindow( DbgPrintWindow ); +#ifdef WNT + DbgSetTestSolarMutex( ImplDbgTestSolarMutex ); +#endif +} + +// ----------------------------------------------------------------------- + +void DbgGUIDeInit() +{ + DbgSetPrintMsgBox( NULL ); + DbgSetPrintWindow( NULL ); +#ifdef WNT + DbgSetTestSolarMutex( NULL ); +#endif + + DbgWindow* pDbgWindow = ImplGetSVData()->maWinData.mpDbgWin; + if ( pDbgWindow ) + delete pDbgWindow; +} + +// ----------------------------------------------------------------------- + +void DbgGUIStart() +{ + DbgData* pData = DbgGetData(); + + if ( pData ) + { + DbgDialog* pDialog = new DbgDialog; + // Fuer den Debug-Dialog schalten wir Dialogtests aus + ULONG nOldFlags = pData->nTestFlags; + pData->nTestFlags &= ~DBG_TEST_DIALOG; + if ( !pDialog->Execute() ) + pData->nTestFlags |= (nOldFlags & DBG_TEST_DIALOG); + delete pDialog; + } + else + { + ErrorBox( 0, WB_OK, + XubString( RTL_CONSTASCII_USTRINGPARAM( "TOOLS Library has no Debug-Routines" ) ) ).Execute(); + } +} + +// ----------------------------------------------------------------------- + +USHORT DbgRegisterNamedUserChannel( const XubString& _rChannelUIName, DbgPrintLine pProc ) +{ + DbgChannelId nChannelId = DbgRegisterUserChannel( pProc ); + UserDefinedChannels& rChannels = ImplDbgGetUserDefinedChannels(); + rChannels[ _rChannelUIName ] = nChannelId; + return nChannelId; +} + +#endif // DBG_UTIL + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/dndhelp.cxx b/vcl/source/app/dndhelp.cxx new file mode 100644 index 000000000000..46a0eac19d4a --- /dev/null +++ b/vcl/source/app/dndhelp.cxx @@ -0,0 +1,184 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + + + +#include <vcl/dndhelp.hxx> + +using namespace ::com::sun::star; + +vcl::unohelper::DragAndDropClient::~DragAndDropClient() {} + +void vcl::unohelper::DragAndDropClient::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& /*dge*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& /*dsde*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dragEnter( const ::com::sun::star::datatransfer::dnd::DragSourceDragEvent& /*dsde*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dragExit( const ::com::sun::star::datatransfer::dnd::DragSourceEvent& /*dse*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dragOver( const ::com::sun::star::datatransfer::dnd::DragSourceDragEvent& /*dsde*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dropActionChanged( const ::com::sun::star::datatransfer::dnd::DragSourceDragEvent& /*dsde*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& /*dtde*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& /*dtdee*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& /*dte*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& /*dtde*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +void vcl::unohelper::DragAndDropClient::dropActionChanged( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& /*dtde*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +// ======================================================================= + +vcl::unohelper::DragAndDropWrapper::DragAndDropWrapper( DragAndDropClient* pClient ) +{ + mpClient = pClient; +} + +vcl::unohelper::DragAndDropWrapper::~DragAndDropWrapper() +{ +} + +// uno::XInterface +uno::Any vcl::unohelper::DragAndDropWrapper::queryInterface( const uno::Type & rType ) throw(uno::RuntimeException) +{ + uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::lang::XEventListener*, (::com::sun::star::datatransfer::dnd::XDragGestureListener*)this ), + SAL_STATIC_CAST( ::com::sun::star::datatransfer::dnd::XDragGestureListener*, this ), + SAL_STATIC_CAST( ::com::sun::star::datatransfer::dnd::XDragSourceListener*, this ), + SAL_STATIC_CAST( ::com::sun::star::datatransfer::dnd::XDropTargetListener*, this ) ); + return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); +} + +// ::com::sun::star::lang::XEventListener +void vcl::unohelper::DragAndDropWrapper::disposing( const ::com::sun::star::lang::EventObject& rEvent ) throw (::com::sun::star::uno::RuntimeException) +{ + // Empty Source means it's the client, because the client is not a XInterface + if ( !rEvent.Source.is() ) + mpClient = NULL; +} + + +// ::com::sun::star::datatransfer::dnd::XDragGestureListener +void vcl::unohelper::DragAndDropWrapper::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& rDGE ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dragGestureRecognized( rDGE ); +} + +// ::com::sun::star::datatransfer::dnd::XDragSourceListener +void vcl::unohelper::DragAndDropWrapper::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& rDSDE ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dragDropEnd( rDSDE ); +} + +void vcl::unohelper::DragAndDropWrapper::dragEnter( const ::com::sun::star::datatransfer::dnd::DragSourceDragEvent& dsde ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dragEnter( dsde ); +} + +void vcl::unohelper::DragAndDropWrapper::dragExit( const ::com::sun::star::datatransfer::dnd::DragSourceEvent& dse ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dragExit( dse ); +} + +void vcl::unohelper::DragAndDropWrapper::dragOver( const ::com::sun::star::datatransfer::dnd::DragSourceDragEvent& dsde ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dragOver( dsde ); +} + +void vcl::unohelper::DragAndDropWrapper::dropActionChanged( const ::com::sun::star::datatransfer::dnd::DragSourceDragEvent& dsde ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dropActionChanged( dsde ); +} + +// ::com::sun::star::datatransfer::dnd::XDropTargetListener +void vcl::unohelper::DragAndDropWrapper::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->drop( rDTDE ); +} + +void vcl::unohelper::DragAndDropWrapper::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& rDTDEE ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dragEnter( rDTDEE ); +} + +void vcl::unohelper::DragAndDropWrapper::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& dte ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dragExit( dte ); +} + +void vcl::unohelper::DragAndDropWrapper::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dragOver( rDTDE ); +} + +void vcl::unohelper::DragAndDropWrapper::dropActionChanged( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( mpClient ) + mpClient->dropActionChanged( rDTDE ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/help.cxx b/vcl/source/app/help.cxx new file mode 100644 index 000000000000..c6fc815854d0 --- /dev/null +++ b/vcl/source/app/help.cxx @@ -0,0 +1,790 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "vcl/svdata.hxx" +#include "vcl/window.hxx" +#include "vcl/event.hxx" +#include "vcl/svapp.hxx" +#include "vcl/wrkwin.hxx" +#include "vcl/help.hxx" +#include "vcl/helpwin.hxx" +#include "tools/debug.hxx" +#include "tools/time.hxx" + +// ======================================================================= + +#define HELPWINSTYLE_QUICK 0 +#define HELPWINSTYLE_BALLOON 1 + +#define HELPTEXTMARGIN_QUICK 3 +#define HELPTEXTMARGIN_BALLOON 6 + +#define HELPDELAY_NORMAL 1 +#define HELPDELAY_SHORT 2 +#define HELPDELAY_NONE 3 + +// ======================================================================= + +Help::Help() +{ +} + +Help::~Help() +{ +} + +// ----------------------------------------------------------------------- + +BOOL Help::Start( ULONG, const Window* ) +{ + return FALSE; +} + +void Help::OpenHelpAgent( ULONG ) +{ +} + +// ----------------------------------------------------------------------- + +BOOL Help::Start( const XubString&, const Window* ) +{ + return FALSE; +} + +// ----------------------------------------------------------------------- + +XubString Help::GetHelpText( ULONG, const Window* ) +{ + return ImplGetSVEmptyStr(); +} + +// ----------------------------------------------------------------------- + +XubString Help::GetHelpText( const String&, const Window* ) +{ + return ImplGetSVEmptyStr(); +} + +// ----------------------------------------------------------------------- + +void Help::EnableContextHelp() +{ + ImplGetSVData()->maHelpData.mbContextHelp = TRUE; +} + +// ----------------------------------------------------------------------- + +void Help::DisableContextHelp() +{ + ImplGetSVData()->maHelpData.mbContextHelp = FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Help::IsContextHelpEnabled() +{ + return ImplGetSVData()->maHelpData.mbContextHelp; +} + +// ----------------------------------------------------------------------- + +BOOL Help::StartContextHelp() +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maHelpData.mbContextHelp ) + { + Window* pWindow = pSVData->maWinData.mpFocusWin; + if ( pWindow ) + { + Point aMousePos = pWindow->OutputToScreenPixel( pWindow->GetPointerPosPixel() ); + HelpEvent aHelpEvent( aMousePos, HELPMODE_CONTEXT ); + pWindow->RequestHelp( aHelpEvent ); + return TRUE; + } + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +void Help::EnableExtHelp() +{ + ImplGetSVData()->maHelpData.mbExtHelp = TRUE; +} + +// ----------------------------------------------------------------------- + +void Help::DisableExtHelp() +{ + ImplGetSVData()->maHelpData.mbExtHelp = FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Help::IsExtHelpEnabled() +{ + return ImplGetSVData()->maHelpData.mbExtHelp; +} + +// ----------------------------------------------------------------------- + +BOOL Help::StartExtHelp() +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maHelpData.mbExtHelp && !pSVData->maHelpData.mbExtHelpMode ) + { + pSVData->maHelpData.mbExtHelpMode = TRUE; + pSVData->maHelpData.mbOldBalloonMode = pSVData->maHelpData.mbBalloonHelp; + pSVData->maHelpData.mbBalloonHelp = TRUE; + if ( pSVData->maWinData.mpAppWin ) + pSVData->maWinData.mpAppWin->ImplGenerateMouseMove(); + return TRUE; + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Help::EndExtHelp() +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maHelpData.mbExtHelp && pSVData->maHelpData.mbExtHelpMode ) + { + pSVData->maHelpData.mbExtHelpMode = FALSE; + pSVData->maHelpData.mbBalloonHelp = pSVData->maHelpData.mbOldBalloonMode; + if ( pSVData->maWinData.mpAppWin ) + pSVData->maWinData.mpAppWin->ImplGenerateMouseMove(); + return TRUE; + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Help::IsExtHelpActive() +{ + return ImplGetSVData()->maHelpData.mbExtHelpMode; +} + +// ----------------------------------------------------------------------- + +void Help::EnableBalloonHelp() +{ + ImplGetSVData()->maHelpData.mbBalloonHelp = TRUE; +} + +// ----------------------------------------------------------------------- + +void Help::DisableBalloonHelp() +{ + ImplGetSVData()->maHelpData.mbBalloonHelp = FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Help::IsBalloonHelpEnabled() +{ + return ImplGetSVData()->maHelpData.mbBalloonHelp; +} + +// ----------------------------------------------------------------------- + +BOOL Help::ShowBalloon( Window* pParent, + const Point& rScreenPos, + const XubString& rHelpText ) +{ + ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, 0, + rHelpText, ImplGetSVEmptyStr(), rScreenPos ); + + return TRUE; +} + +// ----------------------------------------------------------------------- + +BOOL Help::ShowBalloon( Window* pParent, + const Point& rScreenPos, const Rectangle& rRect, + const XubString& rHelpText ) +{ + ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, 0, + rHelpText, ImplGetSVEmptyStr(), rScreenPos, &rRect ); + + return TRUE; +} + +// ----------------------------------------------------------------------- + +void Help::EnableQuickHelp() +{ + ImplGetSVData()->maHelpData.mbQuickHelp = TRUE; +} + +// ----------------------------------------------------------------------- + +void Help::DisableQuickHelp() +{ + ImplGetSVData()->maHelpData.mbQuickHelp = FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Help::IsQuickHelpEnabled() +{ + return ImplGetSVData()->maHelpData.mbQuickHelp; +} + +// ----------------------------------------------------------------------- + +BOOL Help::ShowQuickHelp( Window* pParent, + const Rectangle& rScreenRect, + const XubString& rHelpText, + const XubString& rLongHelpText, + USHORT nStyle ) +{ + ImplShowHelpWindow( pParent, HELPWINSTYLE_QUICK, nStyle, + rHelpText, rLongHelpText, + pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect ); + return TRUE; +} + +// ----------------------------------------------------------------------- + +ULONG Help::ShowTip( Window* pParent, const Rectangle& rRect, + const XubString& rText, USHORT nStyle ) +{ + USHORT nHelpWinStyle = HELPWINSTYLE_QUICK; + HelpTextWindow* pHelpWin = new HelpTextWindow( pParent, rText, nHelpWinStyle, nStyle ); + + Size aSz = pHelpWin->CalcOutSize(); + pHelpWin->SetOutputSizePixel( aSz ); + ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, + pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rRect ); + pHelpWin->ShowHelp( HELPDELAY_NONE ); + return (ULONG)pHelpWin; +} + +// ----------------------------------------------------------------------- + +void Help::HideTip( ULONG nId ) +{ + HelpTextWindow* pHelpWin = (HelpTextWindow*)nId; + Window* pFrameWindow = pHelpWin->ImplGetFrameWindow(); + pHelpWin->Hide(); + // Update ausloesen, damit ein Paint sofort ausgeloest wird, da + // wir den Hintergrund nicht sichern + pFrameWindow->ImplUpdateAll(); + delete pHelpWin; + ImplGetSVData()->maHelpData.mnLastHelpHideTime = Time::GetSystemTicks(); +} + +// ======================================================================= + +HelpTextWindow::HelpTextWindow( Window* pParent, const XubString& rText, USHORT nHelpWinStyle, USHORT nStyle ) : + //FloatingWindow( pParent->ImplGetFrameWindow(), WB_SYSTEMWINDOW ), + FloatingWindow( pParent, WB_SYSTEMWINDOW|WB_TOOLTIPWIN ), // #105827# if we change the parent, mirroring will not work correctly when positioning this window + maHelpText( rText ) +{ + SetType( WINDOW_HELPTEXTWINDOW ); + ImplSetMouseTransparent( TRUE ); + mnHelpWinStyle = nHelpWinStyle; + mnStyle = nStyle; +// on windows this will raise the application window, because help windows are system windows now +// EnableAlwaysOnTop(); + EnableSaveBackground(); + + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + SetPointFont( rStyleSettings.GetHelpFont() ); + SetTextColor( rStyleSettings.GetHelpTextColor() ); + SetTextAlign( ALIGN_TOP ); + if ( IsNativeControlSupported( CTRL_TOOLTIP, PART_ENTIRE_CONTROL ) ) + { + EnableChildTransparentMode( TRUE ); + SetParentClipMode( PARENTCLIPMODE_NOCLIP ); + SetPaintTransparent( TRUE ); + SetBackground(); + } + else + SetBackground( Wallpaper( rStyleSettings.GetHelpColor() ) ); + if( rStyleSettings.GetHelpColor().IsDark() ) + SetLineColor( COL_WHITE ); + else + SetLineColor( COL_BLACK ); + SetFillColor(); + + if( mnStyle & QUICKHELP_BIDI_RTL ) + { + ULONG nLayoutMode = GetLayoutMode(); + nLayoutMode |= TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT; + SetLayoutMode( nLayoutMode ); + } + SetHelpText( rText ); + Window::SetHelpText( rText ); + + ImplSVData* pSVData = ImplGetSVData(); + if ( pSVData->maHelpData.mbSetKeyboardHelp ) + pSVData->maHelpData.mbKeyboardHelp = TRUE; + + const HelpSettings& rHelpSettings = pParent->GetSettings().GetHelpSettings(); + maShowTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) ); + maHideTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) ); + maHideTimer.SetTimeout( rHelpSettings.GetTipTimeout() ); +} + +// ----------------------------------------------------------------------- + +HelpTextWindow::~HelpTextWindow() +{ + maShowTimer.Stop(); + maHideTimer.Stop(); + + if( this == ImplGetSVData()->maHelpData.mpHelpWin ) + ImplGetSVData()->maHelpData.mpHelpWin = NULL; + + if ( maStatusText.Len() ) + { + ImplSVData* pSVData = ImplGetSVData(); + pSVData->mpApp->HideHelpStatusText(); + } +} + +// ----------------------------------------------------------------------- + +void HelpTextWindow::SetHelpText( const String& rHelpText ) +{ + maHelpText = rHelpText; + if ( mnHelpWinStyle == HELPWINSTYLE_QUICK ) + { + Size aSize; + aSize.Height() = GetTextHeight(); + if ( mnStyle & QUICKHELP_CTRLTEXT ) + aSize.Width() = GetCtrlTextWidth( maHelpText ); + else + aSize.Width() = GetTextWidth( maHelpText ); + maTextRect = Rectangle( Point( HELPTEXTMARGIN_QUICK, HELPTEXTMARGIN_QUICK ), aSize ); + } + else // HELPWINSTYLE_BALLOON + { + Point aTmpPoint; + USHORT nCharsInLine = 35 + ((maHelpText.Len()/100)*5); + XubString aXXX; + aXXX.Fill( nCharsInLine, 'x' ); // Durchschnittliche Breite, damit nicht jedes Fenster anders. + long nWidth = GetTextWidth( aXXX ); + Size aTmpSize( nWidth, 0x7FFFFFFF ); + Rectangle aTry1( aTmpPoint, aTmpSize ); + USHORT nDrawFlags = TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK | + TEXT_DRAW_LEFT | TEXT_DRAW_TOP; + if ( mnStyle & QUICKHELP_CTRLTEXT ) + nDrawFlags |= TEXT_DRAW_MNEMONIC; + Rectangle aTextRect = GetTextRect( aTry1, maHelpText, nDrawFlags ); + + // Spaeter mal eine geeignete Breite ermitteln... + maTextRect = aTextRect; + + // Sicherheitsabstand... + maTextRect.SetPos( Point( HELPTEXTMARGIN_BALLOON, HELPTEXTMARGIN_BALLOON ) ); + } + + Size aSize( CalcOutSize() ); + SetOutputSizePixel( aSize ); +} + +// ----------------------------------------------------------------------- + +void HelpTextWindow::ImplShow() +{ + ImplDelData aDogTag( this ); + if ( maStatusText.Len() ) + { + ImplSVData* pSVData = ImplGetSVData(); + pSVData->mpApp->ShowHelpStatusText( maStatusText ); + } + Show( TRUE, SHOW_NOACTIVATE ); + if( !aDogTag.IsDelete() ) + Update(); +} + +// ----------------------------------------------------------------------- + +void HelpTextWindow::Paint( const Rectangle& ) +{ + // paint native background + bool bNativeOK = false; + if ( IsNativeControlSupported( CTRL_TOOLTIP, PART_ENTIRE_CONTROL ) ) + { + // #i46472# workaround gcc3.3 temporary problem + Rectangle aCtrlRegion( Point( 0, 0 ), GetOutputSizePixel() ); + ImplControlValue aControlValue; + bNativeOK = DrawNativeControl( CTRL_TOOLTIP, PART_ENTIRE_CONTROL, aCtrlRegion, + 0, aControlValue, rtl::OUString() ); + } + + // paint text + if ( mnHelpWinStyle == HELPWINSTYLE_QUICK ) + { + if ( mnStyle & QUICKHELP_CTRLTEXT ) + DrawCtrlText( maTextRect.TopLeft(), maHelpText ); + else + DrawText( maTextRect.TopLeft(), maHelpText ); + } + else // HELPWINSTYLE_BALLOON + { + USHORT nDrawFlags = TEXT_DRAW_MULTILINE|TEXT_DRAW_WORDBREAK| + TEXT_DRAW_LEFT|TEXT_DRAW_TOP; + if ( mnStyle & QUICKHELP_CTRLTEXT ) + nDrawFlags |= TEXT_DRAW_MNEMONIC; + DrawText( maTextRect, maHelpText, nDrawFlags ); + } + + // border + if( ! bNativeOK ) + { + Size aSz = GetOutputSizePixel(); + DrawRect( Rectangle( Point(), aSz ) ); + if ( mnHelpWinStyle == HELPWINSTYLE_BALLOON ) + { + aSz.Width() -= 2; + aSz.Height() -= 2; + Color aColor( GetLineColor() ); + SetLineColor( ( COL_GRAY ) ); + DrawRect( Rectangle( Point( 1, 1 ), aSz ) ); + SetLineColor( aColor ); + } + } +} + +// ----------------------------------------------------------------------- + +void HelpTextWindow::ShowHelp( USHORT nDelayMode ) +{ + ULONG nTimeout = 0; + if ( nDelayMode != HELPDELAY_NONE ) + { + // Im ExtendedHelp-Fall die Hilfe schneller anzeigen + if ( ImplGetSVData()->maHelpData.mbExtHelpMode ) + nTimeout = 15; + else + { + const HelpSettings& rHelpSettings = GetSettings().GetHelpSettings(); + if ( mnHelpWinStyle == HELPWINSTYLE_QUICK ) + nTimeout = rHelpSettings.GetTipDelay(); + else + nTimeout = rHelpSettings.GetBalloonDelay(); + } + + if ( nDelayMode == HELPDELAY_SHORT ) + nTimeout /= 3; + } + + maShowTimer.SetTimeout( nTimeout ); + maShowTimer.Start(); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( HelpTextWindow, TimerHdl, Timer*, pTimer) +{ + if ( pTimer == &maShowTimer ) + { + if ( mnHelpWinStyle == HELPWINSTYLE_QUICK ) + { + // start auto-hide-timer for non-ShowTip windows + ImplSVData* pSVData = ImplGetSVData(); + if ( this == pSVData->maHelpData.mpHelpWin ) + maHideTimer.Start(); + } + ImplShow(); + } + else + { + DBG_ASSERT( pTimer == &maHideTimer, "HelpTextWindow::TimerHdl with bad Timer" ); + ImplDestroyHelpWindow( true ); + } + + return 1; +} + +// ----------------------------------------------------------------------- + +Size HelpTextWindow::CalcOutSize() const +{ + Size aSz = maTextRect.GetSize(); + aSz.Width() += 2*maTextRect.Left(); + aSz.Height() += 2*maTextRect.Top(); + return aSz; +} + +// ----------------------------------------------------------------------- + +void HelpTextWindow::RequestHelp( const HelpEvent& /*rHEvt*/ ) +{ + // Nur damit nicht von Window::RequestHelp() ein + // ShowQuickHelp/ShowBalloonHelp am HelpTextWindow aufgerufen wird. +} + +// ----------------------------------------------------------------------- + +String HelpTextWindow::GetText() const +{ + return maHelpText; +} + +// ----------------------------------------------------------------------- + +::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HelpTextWindow::CreateAccessible() +{ + return FloatingWindow::CreateAccessible(); +} + +// ----------------------------------------------------------------------- + +BOOL HelpTextWindow::RegisterAccessibleParent() +{ + return FALSE; +} + +// ----------------------------------------------------------------------- + +void HelpTextWindow::RevokeAccessibleParent() +{ +} + +// ======================================================================= + +void ImplShowHelpWindow( Window* pParent, USHORT nHelpWinStyle, USHORT nStyle, + const XubString& rHelpText, const XubString& rStatusText, + const Point& rScreenPos, const Rectangle* pHelpArea ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + if( !rHelpText.Len() && !pSVData->maHelpData.mbRequestingHelp ) + return; + + HelpTextWindow* pHelpWin = pSVData->maHelpData.mpHelpWin; + USHORT nDelayMode = HELPDELAY_NORMAL; + if ( pHelpWin ) + { + DBG_ASSERT( pHelpWin != pParent, "HelpInHelp ?!" ); + + if ( (( pHelpWin->GetHelpText() != rHelpText ) || + ( pHelpWin->GetWinStyle() != nHelpWinStyle ) || + ( pHelpArea && ( pHelpWin->GetHelpArea() != *pHelpArea ) ) ) + && pSVData->maHelpData.mbRequestingHelp ) + { + // remove help window if no HelpText or other HelpText or + // other help mode. but keep it if we are scrolling, ie not requesting help + bool bWasVisible = pHelpWin->IsVisible(); + if ( bWasVisible ) + nDelayMode = HELPDELAY_NONE; // display it quickly if we were already in quick help mode + pHelpWin = NULL; + ImplDestroyHelpWindow( bWasVisible ); + } + else + { + bool bTextChanged = rHelpText != pHelpWin->GetHelpText(); + if( bTextChanged ) + { + Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow(); + Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) ); + if( pHelpWin->IsVisible() ) + pWindow->Invalidate( aInvRect ); + + pHelpWin->SetHelpText( rHelpText ); + // approach mouse position + ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea ); + if( pHelpWin->IsVisible() ) + pHelpWin->Invalidate(); + } + } + } + + if ( !pHelpWin && rHelpText.Len() ) + { + ULONG nCurTime = Time::GetSystemTicks(); + if( (nCurTime - pSVData->maHelpData.mnLastHelpHideTime) < pParent->GetSettings().GetHelpSettings().GetTipDelay() ) + nDelayMode = HELPDELAY_NONE; + + DBG_ASSERT( !pHelpWin, "Noch ein HelpWin ?!" ); + pHelpWin = new HelpTextWindow( pParent, rHelpText, nHelpWinStyle, nStyle ); + pSVData->maHelpData.mpHelpWin = pHelpWin; + pHelpWin->SetStatusText( rStatusText ); + if ( pHelpArea ) + pHelpWin->SetHelpArea( *pHelpArea ); + + // positioning + Size aSz = pHelpWin->CalcOutSize(); + pHelpWin->SetOutputSizePixel( aSz ); + ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea ); + // if not called from Window::RequestHelp, then without delay... + if ( !pSVData->maHelpData.mbRequestingHelp ) + nDelayMode = HELPDELAY_NONE; + pHelpWin->ShowHelp( nDelayMode ); + } +} + +// ----------------------------------------------------------------------- + +void ImplDestroyHelpWindow( bool bUpdateHideTime ) +{ + ImplSVData* pSVData = ImplGetSVData(); + HelpTextWindow* pHelpWin = pSVData->maHelpData.mpHelpWin; + if ( pHelpWin ) + { + Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow(); + // find out screen area covered by system help window + Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) ); + if( pHelpWin->IsVisible() ) + pWindow->Invalidate( aInvRect ); + pSVData->maHelpData.mpHelpWin = NULL; + pSVData->maHelpData.mbKeyboardHelp = FALSE; + pHelpWin->Hide(); + delete pHelpWin; + if( bUpdateHideTime ) + pSVData->maHelpData.mnLastHelpHideTime = Time::GetSystemTicks(); + } +} + +// ----------------------------------------------------------------------- + +void ImplSetHelpWindowPos( Window* pHelpWin, USHORT nHelpWinStyle, USHORT nStyle, + const Point& rPos, const Rectangle* pHelpArea ) +{ + Point aPos = rPos; + Size aSz = pHelpWin->GetSizePixel(); + Rectangle aScreenRect = pHelpWin->ImplGetFrameWindow()->GetDesktopRectPixel(); + aPos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aPos ); + // get mouse screen coords + Point mPos( pHelpWin->GetParent()->ImplGetFrameWindow()->GetPointerPosPixel() ); + mPos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( mPos ); + + if ( nHelpWinStyle == HELPWINSTYLE_QUICK ) + { + if ( !(nStyle & QUICKHELP_NOAUTOPOS) ) + { + long nScreenHeight = aScreenRect.GetHeight(); + aPos.X() -= 4; + if ( aPos.Y() > aScreenRect.Top()+nScreenHeight-(nScreenHeight/4) ) + aPos.Y() -= aSz.Height()+4; + else + aPos.Y() += 21; + } + } + else + { + // If it's the mouse position, move the window slightly + // so the mouse pointer does not cover it + if ( aPos == mPos ) + { + aPos.X() += 12; + aPos.Y() += 16; + } + } + + if ( nStyle & QUICKHELP_NOAUTOPOS ) + { + if ( pHelpArea ) + { + // convert help area to screen coords + Rectangle devHelpArea( + pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( pHelpArea->TopLeft() ), + pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( pHelpArea->BottomRight() ) ); + + // Welche Position vom Rechteck? + aPos = devHelpArea.Center(); + + if ( nStyle & QUICKHELP_LEFT ) + aPos.X() = devHelpArea.Left(); + else if ( nStyle & QUICKHELP_RIGHT ) + aPos.X() = devHelpArea.Right(); + + if ( nStyle & QUICKHELP_TOP ) + aPos.Y() = devHelpArea.Top(); + else if ( nStyle & QUICKHELP_BOTTOM ) + aPos.Y() = devHelpArea.Bottom(); + } + + // Welche Richtung? + if ( nStyle & QUICKHELP_LEFT ) + ; + else if ( nStyle & QUICKHELP_RIGHT ) + aPos.X() -= aSz.Width(); + else + aPos.X() -= aSz.Width()/2; + + if ( nStyle & QUICKHELP_TOP ) + ; + else if ( nStyle & QUICKHELP_BOTTOM ) + aPos.Y() -= aSz.Height(); + else + aPos.Y() -= aSz.Height()/2; + } + + if ( aPos.X() < aScreenRect.Left() ) + aPos.X() = aScreenRect.Left(); + else if ( ( aPos.X() + aSz.Width() ) > aScreenRect.Right() ) + aPos.X() = aScreenRect.Right() - aSz.Width(); + if ( aPos.Y() < aScreenRect.Top() ) + aPos.Y() = aScreenRect.Top(); + else if ( ( aPos.Y() + aSz.Height() ) > aScreenRect.Bottom() ) + aPos.Y() = aScreenRect.Bottom() - aSz.Height(); + + if( ! (nStyle & QUICKHELP_NOEVADEPOINTER) ) + { + /* the remark below should be obsolete by now as the helpwindow should + not be focusable, leaving it as a hint. However it is sensible in most + conditions to evade the mouse pointer so the content window is fully visible. + + // the popup must not appear under the mouse + // otherwise it would directly be closed due to a focus change... + */ + Rectangle aHelpRect( aPos, aSz ); + if( aHelpRect.IsInside( mPos ) ) + { + Point delta(2,2); + Point pSize( aSz.Width(), aSz.Height() ); + Point pTest( mPos - pSize - delta ); + if( pTest.X() > aScreenRect.Left() && pTest.Y() > aScreenRect.Top() ) + aPos = pTest; + else + aPos = mPos + delta; + } + } + + Window* pWindow = pHelpWin->GetParent()->ImplGetFrameWindow(); + aPos = pWindow->AbsoluteScreenToOutputPixel( aPos ); + pHelpWin->SetPosPixel( aPos ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/i18nhelp.cxx b/vcl/source/app/i18nhelp.cxx new file mode 100644 index 000000000000..c5cd3e796bb6 --- /dev/null +++ b/vcl/source/app/i18nhelp.cxx @@ -0,0 +1,190 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "vcl/i18nhelp.hxx" + +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/i18n/TransliterationModules.hpp" +#include "unotools/localedatawrapper.hxx" +#include "unotools/transliterationwrapper.hxx" +#include "i18npool/mslangid.hxx" + +#include "rtl/ustrbuf.hxx" + +using namespace ::com::sun::star; + +vcl::I18nHelper::I18nHelper( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMSF, const ::com::sun::star::lang::Locale& rLocale ) +{ + mxMSF = rxMSF; + maLocale = rLocale; + mpLocaleDataWrapper = NULL; + mpTransliterationWrapper= NULL; + mbTransliterateIgnoreCase = sal_False; +} + +vcl::I18nHelper::~I18nHelper() +{ + ImplDestroyWrappers(); +} + +void vcl::I18nHelper::ImplDestroyWrappers() +{ + delete mpLocaleDataWrapper; + mpLocaleDataWrapper = NULL; + + delete mpTransliterationWrapper; + mpTransliterationWrapper= NULL; +} + +utl::TransliterationWrapper& vcl::I18nHelper::ImplGetTransliterationWrapper() const +{ + if ( !mpTransliterationWrapper ) + { + sal_Int32 nModules = i18n::TransliterationModules_IGNORE_WIDTH; + if ( mbTransliterateIgnoreCase ) + nModules |= i18n::TransliterationModules_IGNORE_CASE; + + ((vcl::I18nHelper*)this)->mpTransliterationWrapper = new utl::TransliterationWrapper( mxMSF, (i18n::TransliterationModules)nModules ); + ((vcl::I18nHelper*)this)->mpTransliterationWrapper->loadModuleIfNeeded( MsLangId::convertLocaleToLanguage( maLocale ) ); + } + return *mpTransliterationWrapper; +} + +LocaleDataWrapper& vcl::I18nHelper::ImplGetLocaleDataWrapper() const +{ + if ( !mpLocaleDataWrapper ) + { + ((vcl::I18nHelper*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( mxMSF, maLocale ); + } + return *mpLocaleDataWrapper; +} + +const ::com::sun::star::lang::Locale& vcl::I18nHelper::getLocale() const +{ + return maLocale; +} + +inline bool is_formatting_mark( sal_Unicode c ) +{ + if( (c >= 0x200B) && (c <= 0x200F) ) // BiDi and zero-width-markers + return true; + if( (c >= 0x2028) && (c <= 0x202E) ) // BiDi and paragraph-markers + return true; + return false; +} + +/* #i100057# filter formatting marks out of strings before passing them to + the transliteration. The real solution would have been an additional TransliterationModule + to ignore these marks during transliteration; however changin the code in i18npool that actually + implements this could produce unwanted side effects. + + Of course this copying around is not really good, but looking at i18npool, one more time + will not hurt. +*/ +String vcl::I18nHelper::filterFormattingChars( const String& rStr ) +{ + sal_Int32 nUnicodes = rStr.Len(); + rtl::OUStringBuffer aBuf( nUnicodes ); + const sal_Unicode* pStr = rStr.GetBuffer(); + while( nUnicodes-- ) + { + if( ! is_formatting_mark( *pStr ) ) + aBuf.append( *pStr ); + pStr++; + } + return aBuf.makeStringAndClear(); +} + +sal_Int32 vcl::I18nHelper::CompareString( const String& rStr1, const String& rStr2 ) const +{ + ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex ); + + if ( mbTransliterateIgnoreCase ) + { + // Change mbTransliterateIgnoreCase and destroy the warpper, next call to + // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase + ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = FALSE; + delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper; + ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL; + } + + + String aStr1( filterFormattingChars(rStr1) ); + String aStr2( filterFormattingChars(rStr2) ); + return ImplGetTransliterationWrapper().compareString( aStr1, aStr2 ); +} + +sal_Bool vcl::I18nHelper::MatchString( const String& rStr1, const String& rStr2 ) const +{ + ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex ); + + if ( !mbTransliterateIgnoreCase ) + { + // Change mbTransliterateIgnoreCase and destroy the warpper, next call to + // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase + ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = TRUE; + delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper; + ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL; + } + + String aStr1( filterFormattingChars(rStr1) ); + String aStr2( filterFormattingChars(rStr2) ); + return ImplGetTransliterationWrapper().isMatch( aStr1, aStr2 ); +} + +sal_Bool vcl::I18nHelper::MatchMnemonic( const String& rString, sal_Unicode cMnemonicChar ) const +{ + ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex ); + + BOOL bEqual = FALSE; + USHORT n = rString.Search( '~' ); + if ( n != STRING_NOTFOUND ) + { + String aMatchStr( rString, n+1, STRING_LEN ); // not only one char, because of transliteration... + bEqual = MatchString( cMnemonicChar, aMatchStr ); + } + return bEqual; +} + + +String vcl::I18nHelper::GetDate( const Date& rDate ) const +{ + ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex ); + + return ImplGetLocaleDataWrapper().getDate( rDate ); +} + +String vcl::I18nHelper::GetNum( long nNumber, USHORT nDecimals, BOOL bUseThousandSep, BOOL bTrailingZeros ) const +{ + return ImplGetLocaleDataWrapper().getNum( nNumber, nDecimals, bUseThousandSep, bTrailingZeros ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/idlemgr.cxx b/vcl/source/app/idlemgr.cxx new file mode 100644 index 000000000000..c90dc4cd297c --- /dev/null +++ b/vcl/source/app/idlemgr.cxx @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" +#include <tools/list.hxx> +#include <vcl/idlemgr.hxx> +#include <vcl/svapp.hxx> + +// ======================================================================= + +struct ImplIdleData +{ + Link maIdleHdl; + USHORT mnPriority; + BOOL mbTimeout; +}; + +DECLARE_LIST( ImplIdleList, ImplIdleData* ) + +#define IMPL_IDLETIMEOUT 350 + +// ======================================================================= + +ImplIdleMgr::ImplIdleMgr() +{ + mpIdleList = new ImplIdleList( 8, 8, 8 ); + + maTimer.SetTimeout( IMPL_IDLETIMEOUT ); + maTimer.SetTimeoutHdl( LINK( this, ImplIdleMgr, TimeoutHdl ) ); +} + +// ----------------------------------------------------------------------- + +ImplIdleMgr::~ImplIdleMgr() +{ + // Liste loeschen + ImplIdleData* pIdleData = mpIdleList->First(); + while ( pIdleData ) + { + delete pIdleData; + pIdleData = mpIdleList->Next(); + } + + delete mpIdleList; +} + +// ----------------------------------------------------------------------- + +BOOL ImplIdleMgr::InsertIdleHdl( const Link& rLink, USHORT nPriority ) +{ + ULONG nPos = LIST_APPEND; + ImplIdleData* pIdleData = mpIdleList->First(); + while ( pIdleData ) + { + // Wenn Link schon existiert, dann gebe FALSE zurueck + if ( pIdleData->maIdleHdl == rLink ) + return FALSE; + + // Nach Prioritaet sortieren + if ( nPriority <= pIdleData->mnPriority ) + nPos = mpIdleList->GetCurPos(); + + // Schleife nicht beenden, da noch + // geprueft werden muss, ob sich der Link + // schon in der Liste befindet + + pIdleData = mpIdleList->Next(); + } + + pIdleData = new ImplIdleData; + pIdleData->maIdleHdl = rLink; + pIdleData->mnPriority = nPriority; + pIdleData->mbTimeout = FALSE; + mpIdleList->Insert( pIdleData, nPos ); + + // Wenn Timer noch nicht gestartet ist, dann starten + if ( !maTimer.IsActive() ) + maTimer.Start(); + + return TRUE; +} + +// ----------------------------------------------------------------------- + +void ImplIdleMgr::RemoveIdleHdl( const Link& rLink ) +{ + ImplIdleData* pIdleData = mpIdleList->First(); + while ( pIdleData ) + { + if ( pIdleData->maIdleHdl == rLink ) + { + mpIdleList->Remove(); + delete pIdleData; + break; + } + + pIdleData = mpIdleList->Next(); + } + + // keine Handdler mehr da + if ( !mpIdleList->Count() ) + maTimer.Stop(); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( ImplIdleMgr, TimeoutHdl, Timer*, EMPTYARG ) +{ + ImplIdleData* pIdleData = mpIdleList->First(); + while ( pIdleData ) + { + if ( !pIdleData->mbTimeout ) + { + pIdleData->mbTimeout = TRUE; + pIdleData->maIdleHdl.Call( GetpApp() ); + // Kann im Handler entfernt worden sein + if ( mpIdleList->GetPos( pIdleData ) != LIST_ENTRY_NOTFOUND ) + pIdleData->mbTimeout = FALSE; + } + + pIdleData = mpIdleList->Next(); + } + + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/makefile.mk b/vcl/source/app/makefile.mk new file mode 100644 index 000000000000..6e9c91f3c2e7 --- /dev/null +++ b/vcl/source/app/makefile.mk @@ -0,0 +1,71 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=vcl +TARGET=app +ENABLE_EXCEPTIONS=TRUE + +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile2.pmk + +CDEFS+=-DDLLPOSTFIX=$(DLLPOSTFIX) + +# --- Files -------------------------------------------------------- + +SLOFILES= $(SLO)$/dbggui.obj \ + $(SLO)$/brand.obj \ + $(SLO)$/help.obj \ + $(SLO)$/idlemgr.obj \ + $(SLO)$/settings.obj \ + $(SLO)$/sound.obj \ + $(SLO)$/stdtext.obj \ + $(SLO)$/svapp.obj \ + $(SLO)$/svdata.obj \ + $(SLO)$/svmain.obj \ + $(SLO)$/svmainhook.obj \ + $(SLO)$/timer.obj \ + $(SLO)$/dndhelp.obj \ + $(SLO)$/unohelp.obj \ + $(SLO)$/unohelp2.obj \ + $(SLO)$/vclevent.obj \ + $(SLO)$/i18nhelp.obj \ + $(SLO)$/salvtables.obj \ + $(SLO)$/solarmutex.obj \ + $(SLO)$/session.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +.INCLUDE : $(PRJ)$/util$/target.pmk + diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx new file mode 100644 index 000000000000..78de44aae9c8 --- /dev/null +++ b/vcl/source/app/salvtables.cxx @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include <vcl/salframe.hxx> +#include <vcl/salinst.hxx> +#include <vcl/salvd.hxx> +#include <vcl/salprn.hxx> +#include <vcl/saltimer.hxx> +#include <vcl/salimestatus.hxx> +#include <vcl/salsys.hxx> +#include <vcl/salbmp.hxx> +#include <vcl/salobj.hxx> +#include <vcl/salmenu.hxx> +#include <vcl/salctrlhandle.hxx> + +// this file contains the virtual destructors of the sal interface +// compilers ususally put their vtables where the destructor is + +SalFrame::~SalFrame() +{ +} + +// ----------------------------------------------------------------------- + +// default to full-frame flushes +// on ports where partial-flushes are much cheaper this method should be overridden +void SalFrame::Flush( const Rectangle& ) +{ + Flush(); +} + +// ----------------------------------------------------------------------- + +void SalFrame::SetRepresentedURL( const rtl::OUString& ) +{ + // currently this is Mac only functionality +} + +// ----------------------------------------------------------------------- + +SalInstance::~SalInstance() +{ +} + +void SalInstance::FillFontPathList( std::list< rtl::OString >& ) +{ + // do nothing +} + +SalTimer::~SalTimer() +{ +} + +SalBitmap::~SalBitmap() +{ +} + +SalI18NImeStatus::~SalI18NImeStatus() +{ +} + +SalSystem::~SalSystem() +{ +} + +SalPrinter::~SalPrinter() +{ +} + +BOOL SalPrinter::StartJob( const String*, const String&, const String&, + ImplJobSetup*, vcl::PrinterController& ) +{ + return FALSE; +} + +SalInfoPrinter::~SalInfoPrinter() +{ +} + +SalVirtualDevice::~SalVirtualDevice() +{ +} + +SalObject::~SalObject() +{ +} + +SalMenu::~SalMenu() +{ +} + +bool SalMenu::ShowNativePopupMenu(FloatingWindow *, const Rectangle&, ULONG ) +{ + return false; +} + +bool SalMenu::AddMenuBarButton( const SalMenuButtonItem& ) +{ + return false; +} + +void SalMenu::RemoveMenuBarButton( USHORT ) +{ +} + +Rectangle SalMenu::GetMenuBarButtonRectPixel( USHORT, SalFrame* ) +{ + return Rectangle(); +} + +SalMenuItem::~SalMenuItem() +{ +} +SalControlHandle::~SalControlHandle() +{ +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/session.cxx b/vcl/source/app/session.cxx new file mode 100644 index 000000000000..c3a36fb1c537 --- /dev/null +++ b/vcl/source/app/session.cxx @@ -0,0 +1,372 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" +#include <vcl/svapp.hxx> +#include <vcl/svdata.hxx> +#include <vcl/salinst.hxx> +#include <vcl/salsession.hxx> +#include <cppuhelper/compbase1.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/frame/XSessionManagerClient.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/frame/XSessionManagerListener2.hpp> + +#include <list> + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::frame; +using namespace rtl; + +SalSession::~SalSession() +{ +} + +class VCLSession : public cppu::WeakComponentImplHelper1 < XSessionManagerClient > +{ + struct Listener + { + Reference< XSessionManagerListener > m_xListener; + bool m_bInteractionRequested; + bool m_bInteractionDone; + bool m_bSaveDone; + + Listener( const Reference< XSessionManagerListener >& xListener ) + : m_xListener( xListener ), + m_bInteractionRequested( false ), + m_bInteractionDone( false ), + m_bSaveDone( false ) + {} + }; + + std::list< Listener > m_aListeners; + SalSession* m_pSession; + osl::Mutex m_aMutex; + bool m_bInteractionRequested; + bool m_bInteractionGranted; + bool m_bInteractionDone; + bool m_bSaveDone; + + static void SalSessionEventProc( SalSessionEvent* pEvent ); + static VCLSession* pOneInstance; + + void callSaveRequested( bool bShutdown, bool bCancelable ); + void callShutdownCancelled(); + void callInteractionGranted( bool bGranted ); + void callQuit(); +public: + VCLSession(); + virtual ~VCLSession(); + + virtual void SAL_CALL addSessionManagerListener( const Reference< XSessionManagerListener >& xListener ) throw( RuntimeException ); + virtual void SAL_CALL removeSessionManagerListener( const Reference< XSessionManagerListener>& xListener ) throw( RuntimeException ); + virtual void SAL_CALL queryInteraction( const Reference< XSessionManagerListener >& xListener ) throw( RuntimeException ); + virtual void SAL_CALL interactionDone( const Reference< XSessionManagerListener >& xListener ) throw( RuntimeException ); + virtual void SAL_CALL saveDone( const Reference< XSessionManagerListener >& xListener ) throw( RuntimeException ); + virtual sal_Bool SAL_CALL cancelShutdown() throw( RuntimeException ); +}; + +VCLSession* VCLSession::pOneInstance = NULL; + +VCLSession::VCLSession() + : cppu::WeakComponentImplHelper1< XSessionManagerClient >( m_aMutex ), + m_bInteractionRequested( false ), + m_bInteractionGranted( false ), + m_bInteractionDone( false ), + m_bSaveDone( false ) +{ + DBG_ASSERT( pOneInstance == 0, "One instance of VCLSession only !" ); + pOneInstance = this; + m_pSession = ImplGetSVData()->mpDefInst->CreateSalSession(); + if( m_pSession ) + m_pSession->SetCallback( SalSessionEventProc ); +} + +VCLSession::~VCLSession() +{ + DBG_ASSERT( pOneInstance == this, "Another instance of VCLSession in destructor !" ); + pOneInstance = NULL; + delete m_pSession; +} + +void VCLSession::callSaveRequested( bool bShutdown, bool bCancelable ) +{ + std::list< Listener > aListeners; + { + osl::MutexGuard aGuard( m_aMutex ); + // reset listener states + for( std::list< Listener >::iterator it = m_aListeners.begin(); + it != m_aListeners.end(); ++it ) + { + it->m_bSaveDone = it->m_bInteractionRequested = it->m_bInteractionDone = false; + } + + // copy listener list since calling a listener may remove it. + aListeners = m_aListeners; + // set back interaction state + m_bSaveDone = false; + m_bInteractionDone = false; + // without session we assume UI is always possible, + // so it was reqeusted and granted + m_bInteractionRequested = m_bInteractionGranted = m_pSession ? false : true; + + // answer the session manager even if no listeners available anymore + DBG_ASSERT( ! aListeners.empty(), "saveRequested but no listeners !" ); + if( aListeners.empty() ) + { + if( m_pSession ) + m_pSession->saveDone(); + return; + } + } + + ULONG nAcquireCount = Application::ReleaseSolarMutex(); + for( std::list< Listener >::const_iterator it = aListeners.begin(); it != aListeners.end(); ++it ) + it->m_xListener->doSave( bShutdown, bCancelable ); + Application::AcquireSolarMutex( nAcquireCount ); +} + +void VCLSession::callInteractionGranted( bool bInteractionGranted ) +{ + std::list< Listener > aListeners; + { + osl::MutexGuard aGuard( m_aMutex ); + // copy listener list since calling a listener may remove it. + for( std::list< Listener >::const_iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it ) + if( it->m_bInteractionRequested ) + aListeners.push_back( *it ); + + m_bInteractionGranted = bInteractionGranted; + + // answer the session manager even if no listeners available anymore + DBG_ASSERT( ! aListeners.empty(), "interactionGranted but no listeners !" ); + if( aListeners.empty() ) + { + if( m_pSession ) + m_pSession->interactionDone(); + return; + } + } + + ULONG nAcquireCount = Application::ReleaseSolarMutex(); + for( std::list< Listener >::const_iterator it = aListeners.begin(); it != aListeners.end(); ++it ) + it->m_xListener->approveInteraction( bInteractionGranted ); + + Application::AcquireSolarMutex( nAcquireCount ); +} + +void VCLSession::callShutdownCancelled() +{ + std::list< Listener > aListeners; + { + osl::MutexGuard aGuard( m_aMutex ); + // copy listener list since calling a listener may remove it. + aListeners = m_aListeners; + // set back interaction state + m_bInteractionRequested = m_bInteractionDone = m_bInteractionGranted = false; + } + + ULONG nAcquireCount = Application::ReleaseSolarMutex(); + for( std::list< Listener >::const_iterator it = aListeners.begin(); it != aListeners.end(); ++it ) + it->m_xListener->shutdownCanceled(); + Application::AcquireSolarMutex( nAcquireCount ); +} + +void VCLSession::callQuit() +{ + std::list< Listener > aListeners; + { + osl::MutexGuard aGuard( m_aMutex ); + // copy listener list since calling a listener may remove it. + aListeners = m_aListeners; + // set back interaction state + m_bInteractionRequested = m_bInteractionDone = m_bInteractionGranted = false; + } + + ULONG nAcquireCount = Application::ReleaseSolarMutex(); + for( std::list< Listener >::const_iterator it = aListeners.begin(); it != aListeners.end(); ++it ) + { + Reference< XSessionManagerListener2 > xListener2( it->m_xListener, UNO_QUERY ); + if( xListener2.is() ) + xListener2->doQuit(); + } + Application::AcquireSolarMutex( nAcquireCount ); +} + +void VCLSession::SalSessionEventProc( SalSessionEvent* pEvent ) +{ + switch( pEvent->m_eType ) + { + case Interaction: + { + SalSessionInteractionEvent* pIEv = static_cast<SalSessionInteractionEvent*>(pEvent); + pOneInstance->callInteractionGranted( pIEv->m_bInteractionGranted ); + } + break; + case SaveRequest: + { + SalSessionSaveRequestEvent* pSEv = static_cast<SalSessionSaveRequestEvent*>(pEvent); + pOneInstance->callSaveRequested( pSEv->m_bShutdown, pSEv->m_bCancelable ); + } + break; + case ShutdownCancel: + pOneInstance->callShutdownCancelled(); + break; + case Quit: + pOneInstance->callQuit(); + break; + } +} + +void SAL_CALL VCLSession::addSessionManagerListener( const Reference<XSessionManagerListener>& xListener ) throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + m_aListeners.push_back( Listener( xListener ) ); +} + +void SAL_CALL VCLSession::removeSessionManagerListener( const Reference<XSessionManagerListener>& xListener ) throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + std::list< Listener >::iterator it = m_aListeners.begin(); + while( it != m_aListeners.end() ) + { + if( it->m_xListener == xListener ) + { + m_aListeners.erase( it ); + it = m_aListeners.begin(); + } + else + ++it; + } +} + +void SAL_CALL VCLSession::queryInteraction( const Reference<XSessionManagerListener>& xListener ) throw( RuntimeException ) +{ + if( m_bInteractionGranted ) + { + if( m_bInteractionDone ) + xListener->approveInteraction( false ); + else + xListener->approveInteraction( true ); + return; + } + + osl::MutexGuard aGuard( m_aMutex ); + if( ! m_bInteractionRequested ) + { + m_pSession->queryInteraction(); + m_bInteractionRequested = true; + } + for( std::list< Listener >::iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it ) + { + if( it->m_xListener == xListener ) + { + it->m_bInteractionRequested = true; + it->m_bInteractionDone = false; + } + } +} + +void SAL_CALL VCLSession::interactionDone( const Reference< XSessionManagerListener >& xListener ) throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + int nRequested = 0, nDone = 0; + for( std::list< Listener >::iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it ) + { + if( it->m_bInteractionRequested ) + { + nRequested++; + if( xListener == it->m_xListener ) + it->m_bInteractionDone = true; + } + if( it->m_bInteractionDone ) + nDone++; + } + if( nDone == nRequested && nDone > 0 ) + { + m_bInteractionDone = true; + if( m_pSession ) + m_pSession->interactionDone(); + } +} + +void SAL_CALL VCLSession::saveDone( const Reference< XSessionManagerListener >& xListener ) throw( RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + bool bSaveDone = true; + for( std::list< Listener >::iterator it = m_aListeners.begin(); + it != m_aListeners.end(); ++it ) + { + if( it->m_xListener == xListener ) + it->m_bSaveDone = true; + if( ! it->m_bSaveDone ) + bSaveDone = false; + } + if( bSaveDone ) + { + m_bSaveDone = true; + if( m_pSession ) + m_pSession->saveDone(); + } +} + +sal_Bool SAL_CALL VCLSession::cancelShutdown() throw( RuntimeException ) +{ + return m_pSession ? (sal_Bool)m_pSession->cancelShutdown() : sal_False; +} + +// service implementation + +OUString SAL_CALL vcl_session_getImplementationName() +{ + static OUString aImplementationName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.VCLSessionManagerClient" ) ); + return aImplementationName; +} + +Sequence< rtl::OUString > SAL_CALL vcl_session_getSupportedServiceNames() +{ + Sequence< OUString > aRet(1); + aRet[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.SessionManagerClient")); + return aRet; +} + +Reference< XInterface > SAL_CALL vcl_session_createInstance( const Reference< XMultiServiceFactory > & /*xMultiServiceFactory*/ ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->xSMClient.is() ) + pSVData->xSMClient = new VCLSession(); + + return Reference< XInterface >(pSVData->xSMClient, UNO_QUERY ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx new file mode 100644 index 000000000000..20adcc878395 --- /dev/null +++ b/vcl/source/app/settings.cxx @@ -0,0 +1,2103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" +#include "tools/debug.hxx" +#include "i18npool/mslangid.hxx" +#include "vcl/svapp.hxx" +#include "vcl/svdata.hxx" +#include "vcl/event.hxx" +#include "vcl/settings.hxx" +#include "vcl/i18nhelp.hxx" +#include "unotools/fontcfg.hxx" +#include "vcl/configsettings.hxx" +#include "vcl/gradient.hxx" +#include "vcl/unohelp.hxx" +#include "vcl/bitmapex.hxx" +#include "vcl/impimagetree.hxx" +#include "unotools/localedatawrapper.hxx" +#include "unotools/collatorwrapper.hxx" +#include "unotools/configmgr.hxx" +#include "unotools/confignode.hxx" +#include <unotools/syslocaleoptions.hxx> + +#ifdef WNT +#include "tools/prewin.h" +#include <windows.h> +#include "tools/postwin.h" +#endif + +using namespace rtl; + +// ======================================================================= + +DBG_NAME( AllSettings ) + +// ======================================================================= + +#define STDSYS_STYLE (STYLE_OPTION_SCROLLARROW | \ + STYLE_OPTION_SPINARROW | \ + STYLE_OPTION_SPINUPDOWN | \ + STYLE_OPTION_NOMNEMONICS) + +// ======================================================================= +ImplMachineData::ImplMachineData() +{ + mnRefCount = 1; + mnOptions = 0; + mnScreenOptions = 0; + mnPrintOptions = 0; + mnScreenRasterFontDeviation = 0; +} + +// ----------------------------------------------------------------------- + +ImplMachineData::ImplMachineData( const ImplMachineData& rData ) +{ + mnRefCount = 1; + mnOptions = rData.mnOptions; + mnScreenOptions = rData.mnScreenOptions; + mnPrintOptions = rData.mnPrintOptions; + mnScreenRasterFontDeviation = rData.mnScreenRasterFontDeviation; +} + +// ----------------------------------------------------------------------- + +MachineSettings::MachineSettings() +{ + mpData = new ImplMachineData(); +} + +// ----------------------------------------------------------------------- + +MachineSettings::MachineSettings( const MachineSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "MachineSettings: RefCount overflow" ); + + // shared Instance Daten uebernehmen und Referenzcounter erhoehen + mpData = rSet.mpData; + mpData->mnRefCount++; +} + +// ----------------------------------------------------------------------- + +MachineSettings::~MachineSettings() +{ + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; +} + +// ----------------------------------------------------------------------- + +const MachineSettings& MachineSettings::operator =( const MachineSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "MachineSettings: RefCount overflow" ); + + // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann + rSet.mpData->mnRefCount++; + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; + + mpData = rSet.mpData; + + return *this; +} + +// ----------------------------------------------------------------------- + +void MachineSettings::CopyData() +{ + // Falls noch andere Referenzen bestehen, dann kopieren + if ( mpData->mnRefCount != 1 ) + { + mpData->mnRefCount--; + mpData = new ImplMachineData( *mpData ); + } +} + +// ----------------------------------------------------------------------- + +BOOL MachineSettings::operator ==( const MachineSettings& rSet ) const +{ + if ( mpData == rSet.mpData ) + return TRUE; + + if ( (mpData->mnOptions == rSet.mpData->mnOptions) && + (mpData->mnScreenOptions == rSet.mpData->mnScreenOptions) && + (mpData->mnPrintOptions == rSet.mpData->mnPrintOptions) && + (mpData->mnScreenRasterFontDeviation == rSet.mpData->mnScreenRasterFontDeviation) ) + return TRUE; + else + return FALSE; +} + +// ======================================================================= + +ImplMouseData::ImplMouseData() +{ + mnRefCount = 1; + mnOptions = 0; + mnDoubleClkTime = 500; + mnDoubleClkWidth = 2; + mnDoubleClkHeight = 2; + mnStartDragWidth = 2; + mnStartDragHeight = 2; + mnStartDragCode = MOUSE_LEFT; + mnDragMoveCode = 0; + mnDragCopyCode = KEY_MOD1; + mnDragLinkCode = KEY_SHIFT | KEY_MOD1; + mnContextMenuCode = MOUSE_RIGHT; + mnContextMenuClicks = 1; + mbContextMenuDown = TRUE; + mnMiddleButtonAction = MOUSE_MIDDLE_AUTOSCROLL; + mnScrollRepeat = 100; + mnButtonStartRepeat = 370; + mnButtonRepeat = 90; + mnActionDelay = 250; + mnMenuDelay = 150; + mnFollow = MOUSE_FOLLOW_MENU | MOUSE_FOLLOW_DDLIST; + mnWheelBehavior = MOUSE_WHEEL_ALWAYS; +} + +// ----------------------------------------------------------------------- + +ImplMouseData::ImplMouseData( const ImplMouseData& rData ) +{ + mnRefCount = 1; + mnOptions = rData.mnOptions; + mnDoubleClkTime = rData.mnDoubleClkTime; + mnDoubleClkWidth = rData.mnDoubleClkWidth; + mnDoubleClkHeight = rData.mnDoubleClkHeight; + mnStartDragWidth = rData.mnStartDragWidth; + mnStartDragHeight = rData.mnStartDragHeight; + mnStartDragCode = rData.mnStartDragCode; + mnDragMoveCode = rData.mnDragMoveCode; + mnDragCopyCode = rData.mnDragCopyCode; + mnDragLinkCode = rData.mnDragLinkCode; + mnContextMenuCode = rData.mnContextMenuCode; + mnContextMenuClicks = rData.mnContextMenuClicks; + mbContextMenuDown = rData.mbContextMenuDown; + mnMiddleButtonAction = rData.mnMiddleButtonAction; + mnScrollRepeat = rData.mnScrollRepeat; + mnButtonStartRepeat = rData.mnButtonStartRepeat; + mnButtonRepeat = rData.mnButtonRepeat; + mnActionDelay = rData.mnActionDelay; + mnMenuDelay = rData.mnMenuDelay; + mnFollow = rData.mnFollow; + mnWheelBehavior = rData.mnWheelBehavior; +} + +// ----------------------------------------------------------------------- + +MouseSettings::MouseSettings() +{ + mpData = new ImplMouseData(); +} + +// ----------------------------------------------------------------------- + +MouseSettings::MouseSettings( const MouseSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "MouseSettings: RefCount overflow" ); + + // shared Instance Daten uebernehmen und Referenzcounter erhoehen + mpData = rSet.mpData; + mpData->mnRefCount++; +} + +// ----------------------------------------------------------------------- + +MouseSettings::~MouseSettings() +{ + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; +} + +// ----------------------------------------------------------------------- + +const MouseSettings& MouseSettings::operator =( const MouseSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "MouseSettings: RefCount overflow" ); + + // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann + rSet.mpData->mnRefCount++; + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; + + mpData = rSet.mpData; + + return *this; +} + +// ----------------------------------------------------------------------- + +void MouseSettings::CopyData() +{ + // Falls noch andere Referenzen bestehen, dann kopieren + if ( mpData->mnRefCount != 1 ) + { + mpData->mnRefCount--; + mpData = new ImplMouseData( *mpData ); + } +} + +// ----------------------------------------------------------------------- + +BOOL MouseSettings::operator ==( const MouseSettings& rSet ) const +{ + if ( mpData == rSet.mpData ) + return TRUE; + + if ( (mpData->mnOptions == rSet.mpData->mnOptions) && + (mpData->mnDoubleClkTime == rSet.mpData->mnDoubleClkTime) && + (mpData->mnDoubleClkWidth == rSet.mpData->mnDoubleClkWidth) && + (mpData->mnDoubleClkHeight == rSet.mpData->mnDoubleClkHeight) && + (mpData->mnStartDragWidth == rSet.mpData->mnStartDragWidth) && + (mpData->mnStartDragHeight == rSet.mpData->mnStartDragHeight) && + (mpData->mnStartDragCode == rSet.mpData->mnStartDragCode) && + (mpData->mnDragMoveCode == rSet.mpData->mnDragMoveCode) && + (mpData->mnDragCopyCode == rSet.mpData->mnDragCopyCode) && + (mpData->mnDragLinkCode == rSet.mpData->mnDragLinkCode) && + (mpData->mnContextMenuCode == rSet.mpData->mnContextMenuCode) && + (mpData->mnContextMenuClicks == rSet.mpData->mnContextMenuClicks) && + (mpData->mbContextMenuDown == rSet.mpData->mbContextMenuDown) && + (mpData->mnMiddleButtonAction == rSet.mpData->mnMiddleButtonAction) && + (mpData->mnScrollRepeat == rSet.mpData->mnScrollRepeat) && + (mpData->mnButtonStartRepeat == rSet.mpData->mnButtonStartRepeat) && + (mpData->mnButtonRepeat == rSet.mpData->mnButtonRepeat) && + (mpData->mnActionDelay == rSet.mpData->mnActionDelay) && + (mpData->mnMenuDelay == rSet.mpData->mnMenuDelay) && + (mpData->mnFollow == rSet.mpData->mnFollow) && + (mpData->mnWheelBehavior == rSet.mpData->mnWheelBehavior ) ) + return TRUE; + else + return FALSE; +} + +// ======================================================================= + +ImplKeyboardData::ImplKeyboardData() +{ + mnRefCount = 1; + mnOptions = 0; +} + +// ----------------------------------------------------------------------- + +ImplKeyboardData::ImplKeyboardData( const ImplKeyboardData& rData ) +{ + mnRefCount = 1; + mnOptions = rData.mnOptions; +} + +// ----------------------------------------------------------------------- + +KeyboardSettings::KeyboardSettings() +{ + mpData = new ImplKeyboardData(); +} + +// ----------------------------------------------------------------------- + +KeyboardSettings::KeyboardSettings( const KeyboardSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "KeyboardSettings: RefCount overflow" ); + + // shared Instance Daten uebernehmen und Referenzcounter erhoehen + mpData = rSet.mpData; + mpData->mnRefCount++; +} + +// ----------------------------------------------------------------------- + +KeyboardSettings::~KeyboardSettings() +{ + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; +} + +// ----------------------------------------------------------------------- + +const KeyboardSettings& KeyboardSettings::operator =( const KeyboardSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "KeyboardSettings: RefCount overflow" ); + + // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann + rSet.mpData->mnRefCount++; + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; + + mpData = rSet.mpData; + + return *this; +} + +// ----------------------------------------------------------------------- + +void KeyboardSettings::CopyData() +{ + // Falls noch andere Referenzen bestehen, dann kopieren + if ( mpData->mnRefCount != 1 ) + { + mpData->mnRefCount--; + mpData = new ImplKeyboardData( *mpData ); + } +} + +// ----------------------------------------------------------------------- + +BOOL KeyboardSettings::operator ==( const KeyboardSettings& rSet ) const +{ + if ( mpData == rSet.mpData ) + return TRUE; + + if ( (mpData->mnOptions == rSet.mpData->mnOptions) ) + return TRUE; + else + return FALSE; +} + +// ======================================================================= + +ImplStyleData::ImplStyleData() +{ + mnRefCount = 1; + mnScrollBarSize = 16; + mnMinThumbSize = 16; + mnSplitSize = 3; + mnSpinSize = 16; + mnIconHorzSpace = 50; + mnIconVertSpace = 40; + mnAntialiasedMin = 0; + mnCursorSize = 2; + mnCursorBlinkTime = STYLE_CURSOR_NOBLINKTIME; + mnScreenZoom = 100; + mnScreenFontZoom = 100; + mnRadioButtonStyle = 0; + mnCheckBoxStyle = 0; + mnPushButtonStyle = 0; + mnTabControlStyle = 0; + mnLogoDisplayTime = LOGO_DISPLAYTIME_STARTTIME; + mnDragFullOptions = 0; + mnAnimationOptions = 0; + mnSelectionOptions = 0; + mnDisplayOptions = 0; + mnOptions = 0; + mnAutoMnemonic = 1; + mnToolbarIconSize = STYLE_TOOLBAR_ICONSIZE_UNKNOWN; + mnSymbolsStyle = STYLE_SYMBOLS_AUTO; + mnUseImagesInMenus = STYLE_MENUIMAGES_AUTO; + mnPreferredSymbolsStyle = STYLE_SYMBOLS_AUTO; + mpFontOptions = NULL; + + SetStandardStyles(); +} + +// ----------------------------------------------------------------------- + +ImplStyleData::ImplStyleData( const ImplStyleData& rData ) : + maActiveBorderColor( rData.maActiveBorderColor ), + maActiveColor( rData.maActiveColor ), + maActiveColor2( rData.maActiveColor2 ), + maActiveTextColor( rData.maActiveTextColor ), + maButtonTextColor( rData.maButtonTextColor ), + maButtonRolloverTextColor( rData.maButtonRolloverTextColor ), + maCheckedColor( rData.maCheckedColor ), + maDarkShadowColor( rData.maDarkShadowColor ), + maDeactiveBorderColor( rData.maDeactiveBorderColor ), + maDeactiveColor( rData.maDeactiveColor ), + maDeactiveColor2( rData.maDeactiveColor2 ), + maDeactiveTextColor( rData.maDeactiveTextColor ), + maDialogColor( rData.maDialogColor ), + maDialogTextColor( rData.maDialogTextColor ), + maDisableColor( rData.maDisableColor ), + maFaceColor( rData.maFaceColor ), + maFieldColor( rData.maFieldColor ), + maFieldTextColor( rData.maFieldTextColor ), + maFieldRolloverTextColor( rData.maFieldRolloverTextColor ), + maFontColor( rData.maFontColor ), + maGroupTextColor( rData.maGroupTextColor ), + maHelpColor( rData.maHelpColor ), + maHelpTextColor( rData.maHelpTextColor ), + maHighlightColor( rData.maHighlightColor ), + maHighlightLinkColor( rData.maHighlightLinkColor ), + maHighlightTextColor( rData.maHighlightTextColor ), + maInfoTextColor( rData.maInfoTextColor ), + maLabelTextColor( rData.maLabelTextColor ), + maLightBorderColor( rData.maLightBorderColor ), + maLightColor( rData.maLightColor ), + maLinkColor( rData.maLinkColor ), + maMenuBarColor( rData.maMenuBarColor ), + maMenuBorderColor( rData.maMenuBorderColor ), + maMenuColor( rData.maMenuColor ), + maMenuHighlightColor( rData.maMenuHighlightColor ), + maMenuHighlightTextColor( rData.maMenuHighlightTextColor ), + maMenuTextColor( rData.maMenuTextColor ), + maMenuBarTextColor( rData.maMenuBarTextColor ), + maMonoColor( rData.maMonoColor ), + maRadioCheckTextColor( rData.maRadioCheckTextColor ), + maShadowColor( rData.maShadowColor ), + maVisitedLinkColor( rData.maVisitedLinkColor ), + maWindowColor( rData.maWindowColor ), + maWindowTextColor( rData.maWindowTextColor ), + maWorkspaceColor( rData.maWorkspaceColor ), + maActiveTabColor( rData.maActiveTabColor ), + maInactiveTabColor( rData.maInactiveTabColor ), + maAppFont( rData.maAppFont ), + maHelpFont( rData.maAppFont ), + maTitleFont( rData.maTitleFont ), + maFloatTitleFont( rData.maFloatTitleFont ), + maMenuFont( rData.maMenuFont ), + maToolFont( rData.maToolFont ), + maLabelFont( rData.maLabelFont ), + maInfoFont( rData.maInfoFont ), + maRadioCheckFont( rData.maRadioCheckFont ), + maPushButtonFont( rData.maPushButtonFont ), + maFieldFont( rData.maFieldFont ), + maIconFont( rData.maIconFont ), + maGroupFont( rData.maGroupFont ), + maWorkspaceGradient( rData.maWorkspaceGradient ) +{ + mnRefCount = 1; + mnBorderSize = rData.mnBorderSize; + mnTitleHeight = rData.mnTitleHeight; + mnFloatTitleHeight = rData.mnFloatTitleHeight; + mnTearOffTitleHeight = rData.mnTearOffTitleHeight; + mnMenuBarHeight = rData.mnMenuBarHeight; + mnScrollBarSize = rData.mnScrollBarSize; + mnMinThumbSize = rData.mnMinThumbSize; + mnSplitSize = rData.mnSplitSize; + mnSpinSize = rData.mnSpinSize; + mnIconHorzSpace = rData.mnIconHorzSpace; + mnIconVertSpace = rData.mnIconVertSpace; + mnAntialiasedMin = rData.mnAntialiasedMin; + mnCursorSize = rData.mnCursorSize; + mnCursorBlinkTime = rData.mnCursorBlinkTime; + mnScreenZoom = rData.mnScreenZoom; + mnScreenFontZoom = rData.mnScreenFontZoom; + mnRadioButtonStyle = rData.mnRadioButtonStyle; + mnCheckBoxStyle = rData.mnCheckBoxStyle; + mnPushButtonStyle = rData.mnPushButtonStyle; + mnTabControlStyle = rData.mnTabControlStyle; + mnLogoDisplayTime = rData.mnLogoDisplayTime; + mnDragFullOptions = rData.mnDragFullOptions; + mnAnimationOptions = rData.mnAnimationOptions; + mnSelectionOptions = rData.mnSelectionOptions; + mnDisplayOptions = rData.mnDisplayOptions; + mnOptions = rData.mnOptions; + mnHighContrast = rData.mnHighContrast; + mnUseSystemUIFonts = rData.mnUseSystemUIFonts; + mnUseFlatBorders = rData.mnUseFlatBorders; + mnUseFlatMenues = rData.mnUseFlatMenues; + mnAutoMnemonic = rData.mnAutoMnemonic; + mnUseImagesInMenus = rData.mnUseImagesInMenus; + mbPreferredUseImagesInMenus = rData.mbPreferredUseImagesInMenus; + mnSkipDisabledInMenus = rData.mnSkipDisabledInMenus; + mnToolbarIconSize = rData.mnToolbarIconSize; + mnSymbolsStyle = rData.mnSymbolsStyle; + mnPreferredSymbolsStyle = rData.mnPreferredSymbolsStyle; + mpFontOptions = rData.mpFontOptions; +} + +// ----------------------------------------------------------------------- + +void ImplStyleData::SetStandardStyles() +{ + Font aStdFont( FAMILY_SWISS, Size( 0, 8 ) ); + aStdFont.SetCharSet( gsl_getSystemTextEncoding() ); + aStdFont.SetWeight( WEIGHT_NORMAL ); + aStdFont.SetName( utl::DefaultFontConfiguration::get()->getUserInterfaceFont(com::sun::star::lang::Locale( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("en") ), rtl::OUString(), rtl::OUString() ) ) ); + maAppFont = aStdFont; + maHelpFont = aStdFont; + maMenuFont = aStdFont; + maToolFont = aStdFont; + maGroupFont = aStdFont; + maLabelFont = aStdFont; + maInfoFont = aStdFont; + maRadioCheckFont = aStdFont; + maPushButtonFont = aStdFont; + maFieldFont = aStdFont; + maIconFont = aStdFont; + aStdFont.SetWeight( WEIGHT_BOLD ); + maFloatTitleFont = aStdFont; + maTitleFont = aStdFont; + + maFaceColor = Color( COL_LIGHTGRAY ); + maCheckedColor = Color( 0xCC, 0xCC, 0xCC ); + maLightColor = Color( COL_WHITE ); + maLightBorderColor = Color( COL_LIGHTGRAY ); + maShadowColor = Color( COL_GRAY ); + maDarkShadowColor = Color( COL_BLACK ); + maButtonTextColor = Color( COL_BLACK ); + maButtonRolloverTextColor = Color( COL_BLACK ); + maRadioCheckTextColor = Color( COL_BLACK ); + maGroupTextColor = Color( COL_BLACK ); + maLabelTextColor = Color( COL_BLACK ); + maInfoTextColor = Color( COL_BLACK ); + maWindowColor = Color( COL_WHITE ); + maWindowTextColor = Color( COL_BLACK ); + maDialogColor = Color( COL_LIGHTGRAY ); + maDialogTextColor = Color( COL_BLACK ); + maWorkspaceColor = Color( COL_GRAY ); + maMonoColor = Color( COL_BLACK ); + maFieldColor = Color( COL_WHITE ); + maFieldTextColor = Color( COL_BLACK ); + maFieldRolloverTextColor = Color( COL_BLACK ); + maActiveColor = Color( COL_BLUE ); + maActiveColor2 = Color( COL_BLACK ); + maActiveTextColor = Color( COL_WHITE ); + maActiveBorderColor = Color( COL_LIGHTGRAY ); + maDeactiveColor = Color( COL_GRAY ); + maDeactiveColor2 = Color( COL_BLACK ); + maDeactiveTextColor = Color( COL_LIGHTGRAY ); + maDeactiveBorderColor = Color( COL_LIGHTGRAY ); + maMenuColor = Color( COL_LIGHTGRAY ); + maMenuBarColor = Color( COL_LIGHTGRAY ); + maMenuBorderColor = Color( COL_LIGHTGRAY ); + maMenuTextColor = Color( COL_BLACK ); + maMenuBarTextColor = Color( COL_BLACK ); + maMenuHighlightColor = Color( COL_BLUE ); + maMenuHighlightTextColor = Color( COL_WHITE ); + maHighlightColor = Color( COL_BLUE ); + maHighlightTextColor = Color( COL_WHITE ); + maActiveTabColor = Color( COL_WHITE ); + maInactiveTabColor = Color( COL_LIGHTGRAY ); + maDisableColor = Color( COL_GRAY ); + maHelpColor = Color( 0xFF, 0xFF, 0xE0 ); + maHelpTextColor = Color( COL_BLACK ); + maLinkColor = Color( COL_BLUE ); + maVisitedLinkColor = Color( 0x00, 0x00, 0xCC ); + maHighlightLinkColor = Color( COL_LIGHTBLUE ); + maFontColor = Color( COL_BLACK ); + + mnRadioButtonStyle &= ~STYLE_RADIOBUTTON_STYLE; + mnCheckBoxStyle &= ~STYLE_CHECKBOX_STYLE; + mnPushButtonStyle &= ~STYLE_PUSHBUTTON_STYLE; + mnTabControlStyle = 0; + + mnOptions &= ~(STYLE_OPTION_SYSTEMSTYLE | STDSYS_STYLE); + mnBorderSize = 1; + mnTitleHeight = 18; + mnFloatTitleHeight = 13; + mnTearOffTitleHeight = 8; + mnMenuBarHeight = 14; + mnHighContrast = 0; + mnUseSystemUIFonts = 1; + mnUseFlatBorders = 0; + mnUseFlatMenues = 0; + mbPreferredUseImagesInMenus = TRUE; + mnSkipDisabledInMenus = (USHORT)FALSE; + + Gradient aGrad( GRADIENT_LINEAR, DEFAULT_WORKSPACE_GRADIENT_START_COLOR, DEFAULT_WORKSPACE_GRADIENT_END_COLOR ); + maWorkspaceGradient = Wallpaper( aGrad ); +} + +// ----------------------------------------------------------------------- + +StyleSettings::StyleSettings() +{ + mpData = new ImplStyleData(); +} + +// ----------------------------------------------------------------------- + +StyleSettings::StyleSettings( const StyleSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "StyleSettings: RefCount overflow" ); + + // shared Instance Daten uebernehmen und Referenzcounter erhoehen + mpData = rSet.mpData; + mpData->mnRefCount++; +} + +// ----------------------------------------------------------------------- + +StyleSettings::~StyleSettings() +{ + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; +} + +// ----------------------------------------------------------------------- + +void StyleSettings::Set3DColors( const Color& rColor ) +{ + CopyData(); + mpData->maFaceColor = rColor; + mpData->maLightBorderColor = rColor; + mpData->maMenuBorderColor = rColor; + mpData->maDarkShadowColor = Color( COL_BLACK ); + if ( rColor != Color( COL_LIGHTGRAY ) ) + { + mpData->maLightColor = rColor; + mpData->maShadowColor = rColor; + mpData->maLightColor.IncreaseLuminance( 64 ); + mpData->maShadowColor.DecreaseLuminance( 64 ); + ULONG nRed = mpData->maLightColor.GetRed(); + ULONG nGreen = mpData->maLightColor.GetGreen(); + ULONG nBlue = mpData->maLightColor.GetBlue(); + nRed += (ULONG)(mpData->maShadowColor.GetRed()); + nGreen += (ULONG)(mpData->maShadowColor.GetGreen()); + nBlue += (ULONG)(mpData->maShadowColor.GetBlue()); + mpData->maCheckedColor = Color( (BYTE)(nRed/2), (BYTE)(nGreen/2), (BYTE)(nBlue/2) ); + } + else + { + mpData->maCheckedColor = Color( 0x99, 0x99, 0x99 ); + mpData->maLightColor = Color( COL_WHITE ); + mpData->maShadowColor = Color( COL_GRAY ); + } +} + +// ----------------------------------------------------------------------- + +::rtl::OUString StyleSettings::ImplSymbolsStyleToName( ULONG nStyle ) const +{ + switch ( nStyle ) + { + case STYLE_SYMBOLS_DEFAULT: return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("default")); + case STYLE_SYMBOLS_HICONTRAST: return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hicontrast")); + case STYLE_SYMBOLS_INDUSTRIAL: return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("tango")); // industrial is dead + case STYLE_SYMBOLS_CRYSTAL: return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("crystal")); + case STYLE_SYMBOLS_TANGO: return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("tango")); + case STYLE_SYMBOLS_OXYGEN: return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("oxygen")); + case STYLE_SYMBOLS_CLASSIC: return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("classic")); + } + + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("auto")); +} + +// ----------------------------------------------------------------------- + +ULONG StyleSettings::ImplNameToSymbolsStyle( const ::rtl::OUString &rName ) const +{ + if ( rName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("default")) ) + return STYLE_SYMBOLS_DEFAULT; + else if ( rName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("hicontrast")) ) + return STYLE_SYMBOLS_HICONTRAST; + else if ( rName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("industrial")) ) + return STYLE_SYMBOLS_TANGO; // industrial is dead + else if ( rName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("crystal")) ) + return STYLE_SYMBOLS_CRYSTAL; + else if ( rName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("tango")) ) + return STYLE_SYMBOLS_TANGO; + else if ( rName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("oxygen")) ) + return STYLE_SYMBOLS_OXYGEN; + else if ( rName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("classic")) ) + return STYLE_SYMBOLS_CLASSIC; + + return STYLE_SYMBOLS_AUTO; +} + +// ----------------------------------------------------------------------- + +/** + The preferred style name can be read from the desktop setting. We + need to find the closest theme name registered in OOo. Therefore + we check if any registered style name is a case-insensitive + substring of the preferred style name. +*/ +void StyleSettings::SetPreferredSymbolsStyleName( const ::rtl::OUString &rName ) +{ + if ( rName.getLength() > 0 ) + { + ::rtl::OUString rNameLowCase( rName.toAsciiLowerCase() ); + + for( sal_uInt32 n = 0; n <= STYLE_SYMBOLS_THEMES_MAX; n++ ) + if ( rNameLowCase.indexOf( ImplSymbolsStyleToName( n ) ) != -1 ) + SetPreferredSymbolsStyle( n ); + } +} + +// ----------------------------------------------------------------------- + +ULONG StyleSettings::GetCurrentSymbolsStyle() const +{ + // style selected in Tools -> Options... -> OpenOffice.org -> View + ULONG nStyle = GetSymbolsStyle(); + + if ( nStyle == STYLE_SYMBOLS_AUTO || ( !CheckSymbolStyle (nStyle) ) ) + { + // the preferred style can be read from the desktop setting by the desktop native widgets modules + ULONG nPreferredStyle = GetPreferredSymbolsStyle(); + + if ( nPreferredStyle == STYLE_SYMBOLS_AUTO || ( !CheckSymbolStyle (nPreferredStyle) ) ) + { + + // use a hardcoded desktop-specific fallback if no preferred style has been detected + static bool sbFallbackDesktopChecked = false; + static ULONG snFallbackDesktopStyle = STYLE_SYMBOLS_DEFAULT; + + if ( !sbFallbackDesktopChecked ) + { + snFallbackDesktopStyle = GetAutoSymbolsStyle(); + sbFallbackDesktopChecked = true; + } + + nPreferredStyle = snFallbackDesktopStyle; + } + + if (GetHighContrastMode() && CheckSymbolStyle (STYLE_SYMBOLS_HICONTRAST) ) + nStyle = STYLE_SYMBOLS_HICONTRAST; + else + nStyle = nPreferredStyle; + } + + return nStyle; +} + +// ----------------------------------------------------------------------- + +ULONG StyleSettings::GetAutoSymbolsStyle() const +{ + const ::rtl::OUString& rDesktopEnvironment = Application::GetDesktopEnvironment(); + ULONG nRet = STYLE_SYMBOLS_DEFAULT; + bool bCont = true; + + try + { + const ::com::sun::star::uno::Any aAny( ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::OPENSOURCECONTEXT ) ); + sal_Int32 nValue( 0 ); + + aAny >>= nValue; + + if( 0 == nValue ) + bCont = false; + } + catch ( ::com::sun::star::uno::Exception& ) + { + } + + if( bCont ) + { + if( rDesktopEnvironment.equalsIgnoreAsciiCaseAscii( "gnome" ) || + rDesktopEnvironment.equalsIgnoreAsciiCaseAscii( "windows" ) ) + nRet = STYLE_SYMBOLS_TANGO; + else if( rDesktopEnvironment.equalsIgnoreAsciiCaseAscii( "kde" ) ) + nRet = STYLE_SYMBOLS_CRYSTAL; + else if( rDesktopEnvironment.equalsIgnoreAsciiCaseAscii( "kde4" ) ) + nRet = STYLE_SYMBOLS_OXYGEN; + } + + // falback to any existing style + if ( ! CheckSymbolStyle (nRet) ) + { + for ( ULONG n = 0 ; n <= STYLE_SYMBOLS_THEMES_MAX ; n++ ) + { + ULONG nStyleToCheck = n; + + // auto is not a real theme => can't be fallback + if ( nStyleToCheck == STYLE_SYMBOLS_AUTO ) + continue; + + // will check hicontrast in the end + if ( nStyleToCheck == STYLE_SYMBOLS_HICONTRAST ) + continue; + if ( nStyleToCheck == STYLE_SYMBOLS_THEMES_MAX ) + nStyleToCheck = STYLE_SYMBOLS_HICONTRAST; + + if ( CheckSymbolStyle ( nStyleToCheck ) ) + { + nRet = nStyleToCheck; + n = STYLE_SYMBOLS_THEMES_MAX; + } + } + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +bool StyleSettings::CheckSymbolStyle( ULONG nStyle ) const +{ + if ( nStyle == STYLE_SYMBOLS_INDUSTRIAL ) + return false; // industrial is dead + + static ImplImageTreeSingletonRef aImageTree; + return aImageTree->checkStyle( ImplSymbolsStyleToName( nStyle ) ); +} + +// ----------------------------------------------------------------------- + +BOOL StyleSettings::GetUseImagesInMenus() const +{ + // icon mode selected in Tools -> Options... -> OpenOffice.org -> View + USHORT nStyle = mpData->mnUseImagesInMenus; + + if ( nStyle == STYLE_MENUIMAGES_AUTO ) + return GetPreferredUseImagesInMenus(); + + return (BOOL)nStyle; +} + +// ----------------------------------------------------------------------- + +void StyleSettings::SetStandardStyles() +{ + CopyData(); + mpData->SetStandardStyles(); +} + +// ----------------------------------------------------------------------- + +void StyleSettings::SetStandardWinStyles() +{ + return; // no more style changes since NWF +} + +// ----------------------------------------------------------------------- + +void StyleSettings::SetStandardOS2Styles() +{ + return; // no more style changes since NWF +} + +// ----------------------------------------------------------------------- + +void StyleSettings::SetStandardMacStyles() +{ + return; // no more style changes since NWF +} + +// ----------------------------------------------------------------------- + +void StyleSettings::SetStandardUnixStyles() +{ + return; // no more style changes since NWF +} + +// ----------------------------------------------------------------------- + +Color StyleSettings::GetFaceGradientColor() const +{ + // compute a brighter face color that can be used in gradients + // for a convex look (eg toolbars) + + USHORT h, s, b; + GetFaceColor().RGBtoHSB( h, s, b ); + if( s > 1) s=1; + if( b < 98) b=98; + return Color( Color::HSBtoRGB( h, s, b ) ); +} + +// ----------------------------------------------------------------------- + +Color StyleSettings::GetSeparatorColor() const +{ + // compute a brighter shadow color for separators (used in toolbars or between menubar and toolbars on Windows XP) + USHORT h, s, b; + GetShadowColor().RGBtoHSB( h, s, b ); + b += b/4; + s -= s/4; + return Color( Color::HSBtoRGB( h, s, b ) ); +} + +// ----------------------------------------------------------------------- + +const StyleSettings& StyleSettings::operator =( const StyleSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "StyleSettings: RefCount overflow" ); + + // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann + rSet.mpData->mnRefCount++; + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; + + mpData = rSet.mpData; + + return *this; +} + +// ----------------------------------------------------------------------- + +void StyleSettings::CopyData() +{ + // Falls noch andere Referenzen bestehen, dann kopieren + if ( mpData->mnRefCount != 1 ) + { + mpData->mnRefCount--; + mpData = new ImplStyleData( *mpData ); + } +} + +// ----------------------------------------------------------------------- + +inline BOOL ImplIsBackOrWhite( const Color& rColor ) +{ + UINT8 nLuminance = rColor.GetLuminance(); + return ( nLuminance < 8 ) || ( nLuminance > 250 ); +} + +BOOL StyleSettings::IsHighContrastBlackAndWhite() const +{ + BOOL bBWOnly = TRUE; + + // Only use B&W if fully B&W, like on GNOME. + // Some colors like CheckedColor and HighlightColor are not B&W in Windows Standard HC Black, + // and we don't want to be B&W then, so check these color first, very probably not B&W. + + // Unfortunately, GNOME uses a very very dark color (0x000033) instead of BLACK (0x000000) + + if ( !ImplIsBackOrWhite( GetFaceColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetHighlightTextColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetWindowColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetWindowTextColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetButtonTextColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetButtonTextColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetGroupTextColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetLabelTextColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetDialogColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetFieldColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetMenuColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetMenuBarColor() ) ) + bBWOnly = FALSE; + else if ( !ImplIsBackOrWhite( GetMenuHighlightColor() ) ) + bBWOnly = FALSE; + + return bBWOnly; +} + +// ----------------------------------------------------------------------- + +BOOL StyleSettings::operator ==( const StyleSettings& rSet ) const +{ + if ( mpData == rSet.mpData ) + return TRUE; + + if ( (mpData->mnOptions == rSet.mpData->mnOptions) && + (mpData->mnAutoMnemonic == rSet.mpData->mnAutoMnemonic) && + (mpData->mnLogoDisplayTime == rSet.mpData->mnLogoDisplayTime) && + (mpData->mnDragFullOptions == rSet.mpData->mnDragFullOptions) && + (mpData->mnAnimationOptions == rSet.mpData->mnAnimationOptions) && + (mpData->mnSelectionOptions == rSet.mpData->mnSelectionOptions) && + (mpData->mnDisplayOptions == rSet.mpData->mnDisplayOptions) && + (mpData->mnCursorSize == rSet.mpData->mnCursorSize) && + (mpData->mnCursorBlinkTime == rSet.mpData->mnCursorBlinkTime) && + (mpData->mnBorderSize == rSet.mpData->mnBorderSize) && + (mpData->mnTitleHeight == rSet.mpData->mnTitleHeight) && + (mpData->mnFloatTitleHeight == rSet.mpData->mnFloatTitleHeight) && + (mpData->mnTearOffTitleHeight == rSet.mpData->mnTearOffTitleHeight) && + (mpData->mnMenuBarHeight == rSet.mpData->mnMenuBarHeight) && + (mpData->mnScrollBarSize == rSet.mpData->mnScrollBarSize) && + (mpData->mnMinThumbSize == rSet.mpData->mnMinThumbSize) && + (mpData->mnSplitSize == rSet.mpData->mnSplitSize) && + (mpData->mnSpinSize == rSet.mpData->mnSpinSize) && + (mpData->mnIconHorzSpace == rSet.mpData->mnIconHorzSpace) && + (mpData->mnIconVertSpace == rSet.mpData->mnIconVertSpace) && + (mpData->mnAntialiasedMin == rSet.mpData->mnAntialiasedMin) && + (mpData->mnScreenZoom == rSet.mpData->mnScreenZoom) && + (mpData->mnScreenFontZoom == rSet.mpData->mnScreenFontZoom) && + (mpData->mnRadioButtonStyle == rSet.mpData->mnRadioButtonStyle) && + (mpData->mnCheckBoxStyle == rSet.mpData->mnCheckBoxStyle) && + (mpData->mnPushButtonStyle == rSet.mpData->mnPushButtonStyle) && + (mpData->mnTabControlStyle == rSet.mpData->mnTabControlStyle) && + (mpData->mnHighContrast == rSet.mpData->mnHighContrast) && + (mpData->mnUseSystemUIFonts == rSet.mpData->mnUseSystemUIFonts) && + (mpData->mnUseFlatBorders == rSet.mpData->mnUseFlatBorders) && + (mpData->mnUseFlatMenues == rSet.mpData->mnUseFlatMenues) && + (mpData->maFaceColor == rSet.mpData->maFaceColor) && + (mpData->maCheckedColor == rSet.mpData->maCheckedColor) && + (mpData->maLightColor == rSet.mpData->maLightColor) && + (mpData->maLightBorderColor == rSet.mpData->maLightBorderColor) && + (mpData->maShadowColor == rSet.mpData->maShadowColor) && + (mpData->maDarkShadowColor == rSet.mpData->maDarkShadowColor) && + (mpData->maButtonTextColor == rSet.mpData->maButtonTextColor) && + (mpData->maRadioCheckTextColor == rSet.mpData->maRadioCheckTextColor) && + (mpData->maGroupTextColor == rSet.mpData->maGroupTextColor) && + (mpData->maLabelTextColor == rSet.mpData->maLabelTextColor) && + (mpData->maInfoTextColor == rSet.mpData->maInfoTextColor) && + (mpData->maWindowColor == rSet.mpData->maWindowColor) && + (mpData->maWindowTextColor == rSet.mpData->maWindowTextColor) && + (mpData->maDialogColor == rSet.mpData->maDialogColor) && + (mpData->maDialogTextColor == rSet.mpData->maDialogTextColor) && + (mpData->maWorkspaceColor == rSet.mpData->maWorkspaceColor) && + (mpData->maMonoColor == rSet.mpData->maMonoColor) && + (mpData->maFieldColor == rSet.mpData->maFieldColor) && + (mpData->maFieldTextColor == rSet.mpData->maFieldTextColor) && + (mpData->maActiveColor == rSet.mpData->maActiveColor) && + (mpData->maActiveColor2 == rSet.mpData->maActiveColor2) && + (mpData->maActiveTextColor == rSet.mpData->maActiveTextColor) && + (mpData->maActiveBorderColor == rSet.mpData->maActiveBorderColor) && + (mpData->maDeactiveColor == rSet.mpData->maDeactiveColor) && + (mpData->maDeactiveColor2 == rSet.mpData->maDeactiveColor2) && + (mpData->maDeactiveTextColor == rSet.mpData->maDeactiveTextColor) && + (mpData->maDeactiveBorderColor == rSet.mpData->maDeactiveBorderColor) && + (mpData->maMenuColor == rSet.mpData->maMenuColor) && + (mpData->maMenuBarColor == rSet.mpData->maMenuBarColor) && + (mpData->maMenuBorderColor == rSet.mpData->maMenuBorderColor) && + (mpData->maMenuTextColor == rSet.mpData->maMenuTextColor) && + (mpData->maMenuBarTextColor == rSet.mpData->maMenuBarTextColor) && + (mpData->maMenuHighlightColor == rSet.mpData->maMenuHighlightColor) && + (mpData->maMenuHighlightTextColor == rSet.mpData->maMenuHighlightTextColor) && + (mpData->maHighlightColor == rSet.mpData->maHighlightColor) && + (mpData->maHighlightTextColor == rSet.mpData->maHighlightTextColor) && + (mpData->maActiveTabColor == rSet.mpData->maActiveTabColor) && + (mpData->maInactiveTabColor == rSet.mpData->maInactiveTabColor) && + (mpData->maDisableColor == rSet.mpData->maDisableColor) && + (mpData->maHelpColor == rSet.mpData->maHelpColor) && + (mpData->maHelpTextColor == rSet.mpData->maHelpTextColor) && + (mpData->maLinkColor == rSet.mpData->maLinkColor) && + (mpData->maVisitedLinkColor == rSet.mpData->maVisitedLinkColor) && + (mpData->maHighlightLinkColor == rSet.mpData->maHighlightLinkColor) && + (mpData->maAppFont == rSet.mpData->maAppFont) && + (mpData->maHelpFont == rSet.mpData->maHelpFont) && + (mpData->maTitleFont == rSet.mpData->maTitleFont) && + (mpData->maFloatTitleFont == rSet.mpData->maFloatTitleFont) && + (mpData->maMenuFont == rSet.mpData->maMenuFont) && + (mpData->maToolFont == rSet.mpData->maToolFont) && + (mpData->maGroupFont == rSet.mpData->maGroupFont) && + (mpData->maLabelFont == rSet.mpData->maLabelFont) && + (mpData->maInfoFont == rSet.mpData->maInfoFont) && + (mpData->maRadioCheckFont == rSet.mpData->maRadioCheckFont) && + (mpData->maPushButtonFont == rSet.mpData->maPushButtonFont) && + (mpData->maFieldFont == rSet.mpData->maFieldFont) && + (mpData->maIconFont == rSet.mpData->maIconFont) && + (mpData->mnUseImagesInMenus == rSet.mpData->mnUseImagesInMenus) && + (mpData->mbPreferredUseImagesInMenus == rSet.mpData->mbPreferredUseImagesInMenus) && + (mpData->mnSkipDisabledInMenus == rSet.mpData->mnSkipDisabledInMenus) && + (mpData->maFontColor == rSet.mpData->maFontColor )) + return TRUE; + else + return FALSE; +} + +// ======================================================================= + +ImplMiscData::ImplMiscData() +{ + mnRefCount = 1; + mnEnableATT = sal::static_int_cast<USHORT>(~0U); + mnDisablePrinting = sal::static_int_cast<USHORT>(~0U); + static const char* pEnv = getenv("SAL_DECIMALSEP_ENABLED" ); // set default without UI + mbEnableLocalizedDecimalSep = (pEnv != NULL) ? TRUE : FALSE; +} + +// ----------------------------------------------------------------------- + +ImplMiscData::ImplMiscData( const ImplMiscData& rData ) +{ + mnRefCount = 1; + mnEnableATT = rData.mnEnableATT; + mnDisablePrinting = rData.mnDisablePrinting; + mbEnableLocalizedDecimalSep = rData.mbEnableLocalizedDecimalSep; +} + +// ----------------------------------------------------------------------- + +MiscSettings::MiscSettings() +{ + mpData = new ImplMiscData(); +} + +// ----------------------------------------------------------------------- + +MiscSettings::MiscSettings( const MiscSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "MiscSettings: RefCount overflow" ); + + // shared Instance Daten uebernehmen und Referenzcounter erhoehen + mpData = rSet.mpData; + mpData->mnRefCount++; +} + +// ----------------------------------------------------------------------- + +MiscSettings::~MiscSettings() +{ + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; +} + +// ----------------------------------------------------------------------- + +const MiscSettings& MiscSettings::operator =( const MiscSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "MiscSettings: RefCount overflow" ); + + // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann + rSet.mpData->mnRefCount++; + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; + + mpData = rSet.mpData; + + return *this; +} + +// ----------------------------------------------------------------------- + +void MiscSettings::CopyData() +{ + // Falls noch andere Referenzen bestehen, dann kopieren + if ( mpData->mnRefCount != 1 ) + { + mpData->mnRefCount--; + mpData = new ImplMiscData( *mpData ); + } +} + +// ----------------------------------------------------------------------- + +BOOL MiscSettings::operator ==( const MiscSettings& rSet ) const +{ + if ( mpData == rSet.mpData ) + return TRUE; + + if ( (mpData->mnEnableATT == rSet.mpData->mnEnableATT ) && + (mpData->mnDisablePrinting == rSet.mpData->mnDisablePrinting ) && + (mpData->mbEnableLocalizedDecimalSep == rSet.mpData->mbEnableLocalizedDecimalSep ) ) + return TRUE; + else + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL MiscSettings::GetDisablePrinting() const +{ + if( mpData->mnDisablePrinting == (USHORT)~0 ) + { + rtl::OUString aEnable = + vcl::SettingsConfigItem::get()-> + getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DesktopManagement" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisablePrinting" ) ) ); + mpData->mnDisablePrinting = aEnable.equalsIgnoreAsciiCaseAscii( "true" ) ? 1 : 0; + } + + return (BOOL)mpData->mnDisablePrinting; +} +// ----------------------------------------------------------------------- + +BOOL MiscSettings::GetEnableATToolSupport() const +{ + +#ifdef WNT + if( mpData->mnEnableATT == (USHORT)~0 ) + { + // Check in the Windows registry if an AT tool wants Accessibility support to + // be activated .. + HKEY hkey; + + if( ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, + "Software\\OpenOffice.org\\Accessibility\\AtToolSupport", + &hkey) ) + { + DWORD dwType; + WIN_BYTE Data[6]; // possible values: "true", "false", "1", "0", DWORD + DWORD cbData = sizeof(Data); + + if( ERROR_SUCCESS == RegQueryValueEx(hkey, "SupportAssistiveTechnology", + NULL, &dwType, Data, &cbData) ) + { + switch (dwType) + { + case REG_SZ: + mpData->mnEnableATT = ((0 == stricmp((const char *) Data, "1")) || (0 == stricmp((const char *) Data, "true"))); + break; + case REG_DWORD: + mpData->mnEnableATT = (USHORT) (((DWORD *) Data)[0]); + break; + default: + // Unsupported registry type + break; + } + } + + RegCloseKey(hkey); + } + } +#endif + + if( mpData->mnEnableATT == (USHORT)~0 ) + { + static const char* pEnv = getenv("SAL_ACCESSIBILITY_ENABLED" ); + if( !pEnv || !*pEnv ) + { + rtl::OUString aEnable = + vcl::SettingsConfigItem::get()-> + getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Accessibility" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableATToolSupport" ) ) ); + mpData->mnEnableATT = aEnable.equalsIgnoreAsciiCaseAscii( "true" ) ? 1 : 0; + } + else + { + mpData->mnEnableATT = 1; + } + } + + return (BOOL)mpData->mnEnableATT; +} + +// ----------------------------------------------------------------------- + +void MiscSettings::SetDisablePrinting( BOOL bEnable ) +{ + if ( bEnable != mpData->mnDisablePrinting ) + { + vcl::SettingsConfigItem::get()-> + setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DesktopManagement" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisablePrinting" ) ), + rtl::OUString::createFromAscii( bEnable ? "true" : "false" ) ); + mpData->mnDisablePrinting = bEnable ? 1 : 0; + } +} + +// ----------------------------------------------------------------------- + +void MiscSettings::SetEnableATToolSupport( BOOL bEnable ) +{ + if ( bEnable != mpData->mnEnableATT ) + { + BOOL bDummy; + if( bEnable && !ImplInitAccessBridge(false, bDummy) ) + return; + +#ifdef WNT + HKEY hkey; + + // If the accessibility key in the Windows registry exists, change it synchronously + if( ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, + "Software\\OpenOffice.org\\Accessibility\\AtToolSupport", + &hkey) ) + { + DWORD dwType; + WIN_BYTE Data[6]; // possible values: "true", "false", 1, 0 + DWORD cbData = sizeof(Data); + + if( ERROR_SUCCESS == RegQueryValueEx(hkey, "SupportAssistiveTechnology", + NULL, &dwType, Data, &cbData) ) + { + switch (dwType) + { + case REG_SZ: + RegSetValueEx(hkey, "SupportAssistiveTechnology", + NULL, dwType, + bEnable ? (WIN_BYTE *) "true" : (WIN_BYTE *) "false", + bEnable ? sizeof("true") : sizeof("false")); + break; + case REG_DWORD: + ((DWORD *) Data)[0] = bEnable ? 1 : 0; + RegSetValueEx(hkey, "SupportAssistiveTechnology", + NULL, dwType, Data, sizeof(DWORD)); + break; + default: + // Unsupported registry type + break; + } + } + + RegCloseKey(hkey); + } + +#endif + vcl::SettingsConfigItem::get()-> + setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Accessibility" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableATToolSupport" ) ), + rtl::OUString::createFromAscii( bEnable ? "true" : "false" ) ); + mpData->mnEnableATT = bEnable ? 1 : 0; + } +} + +void MiscSettings::SetEnableLocalizedDecimalSep( BOOL bEnable ) +{ + CopyData(); + mpData->mbEnableLocalizedDecimalSep = bEnable; +} + +BOOL MiscSettings::GetEnableLocalizedDecimalSep() const +{ + return mpData->mbEnableLocalizedDecimalSep; +} + +// ======================================================================= + +ImplNotificationData::ImplNotificationData() +{ + mnRefCount = 1; + mnOptions = 0; +} + +// ----------------------------------------------------------------------- + +ImplNotificationData::ImplNotificationData( const ImplNotificationData& rData ) +{ + mnRefCount = 1; + mnOptions = rData.mnOptions; +} + +// ----------------------------------------------------------------------- + +NotificationSettings::NotificationSettings() +{ + mpData = new ImplNotificationData(); +} + +// ----------------------------------------------------------------------- + +NotificationSettings::NotificationSettings( const NotificationSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "NotificationSettings: RefCount overflow" ); + + // shared Instance Daten uebernehmen und Referenzcounter erhoehen + mpData = rSet.mpData; + mpData->mnRefCount++; +} + +// ----------------------------------------------------------------------- + +NotificationSettings::~NotificationSettings() +{ + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; +} + +// ----------------------------------------------------------------------- + +const NotificationSettings& NotificationSettings::operator =( const NotificationSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "NotificationSettings: RefCount overflow" ); + + // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann + rSet.mpData->mnRefCount++; + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; + + mpData = rSet.mpData; + + return *this; +} + +// ----------------------------------------------------------------------- + +void NotificationSettings::CopyData() +{ + // Falls noch andere Referenzen bestehen, dann kopieren + if ( mpData->mnRefCount != 1 ) + { + mpData->mnRefCount--; + mpData = new ImplNotificationData( *mpData ); + } +} + +// ----------------------------------------------------------------------- + +BOOL NotificationSettings::operator ==( const NotificationSettings& rSet ) const +{ + if ( mpData == rSet.mpData ) + return TRUE; + + if ( (mpData->mnOptions == rSet.mpData->mnOptions) ) + return TRUE; + else + return FALSE; +} + +// ======================================================================= + +ImplHelpData::ImplHelpData() +{ + mnRefCount = 1; + mnOptions = 0; + mnTipDelay = 500; + mnTipTimeout = 3000; + mnBalloonDelay = 1500; +} + +// ----------------------------------------------------------------------- + +ImplHelpData::ImplHelpData( const ImplHelpData& rData ) +{ + mnRefCount = 1; + mnOptions = rData.mnOptions; + mnTipDelay = rData.mnTipDelay; + mnTipTimeout = rData.mnTipTimeout; + mnBalloonDelay = rData.mnBalloonDelay; +} + +// ----------------------------------------------------------------------- + +HelpSettings::HelpSettings() +{ + mpData = new ImplHelpData(); +} + +// ----------------------------------------------------------------------- + +HelpSettings::HelpSettings( const HelpSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "HelpSettings: RefCount overflow" ); + + // shared Instance Daten uebernehmen und Referenzcounter erhoehen + mpData = rSet.mpData; + mpData->mnRefCount++; +} + +// ----------------------------------------------------------------------- + +HelpSettings::~HelpSettings() +{ + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; +} + +// ----------------------------------------------------------------------- + +const HelpSettings& HelpSettings::operator =( const HelpSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "HelpSettings: RefCount overflow" ); + + // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann + rSet.mpData->mnRefCount++; + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; + + mpData = rSet.mpData; + + return *this; +} + +// ----------------------------------------------------------------------- + +void HelpSettings::CopyData() +{ + // Falls noch andere Referenzen bestehen, dann kopieren + if ( mpData->mnRefCount != 1 ) + { + mpData->mnRefCount--; + mpData = new ImplHelpData( *mpData ); + } +} + +// ----------------------------------------------------------------------- + +BOOL HelpSettings::operator ==( const HelpSettings& rSet ) const +{ + if ( mpData == rSet.mpData ) + return TRUE; + + if ( (mpData->mnOptions == rSet.mpData->mnOptions ) && + (mpData->mnTipDelay == rSet.mpData->mnTipDelay ) && + (mpData->mnTipTimeout == rSet.mpData->mnTipTimeout ) && + (mpData->mnBalloonDelay == rSet.mpData->mnBalloonDelay ) ) + return TRUE; + else + return FALSE; +} + +// ======================================================================= + +ImplAllSettingsData::ImplAllSettingsData() +{ + mnRefCount = 1; + mnSystemUpdate = SETTINGS_ALLSETTINGS; + mnWindowUpdate = SETTINGS_ALLSETTINGS; + meLanguage = LANGUAGE_SYSTEM; + meUILanguage = LANGUAGE_SYSTEM; + mpLocaleDataWrapper = NULL; + mpUILocaleDataWrapper = NULL; + mpCollatorWrapper = NULL; + mpUICollatorWrapper = NULL; + mpI18nHelper = NULL; + mpUII18nHelper = NULL; + maMiscSettings.SetEnableLocalizedDecimalSep( maSysLocale.GetOptions().IsDecimalSeparatorAsLocale() ); +} + +// ----------------------------------------------------------------------- + +ImplAllSettingsData::ImplAllSettingsData( const ImplAllSettingsData& rData ) : + maMouseSettings( rData.maMouseSettings ), + maKeyboardSettings( rData.maKeyboardSettings ), + maStyleSettings( rData.maStyleSettings ), + maMiscSettings( rData.maMiscSettings ), + maNotificationSettings( rData.maNotificationSettings ), + maHelpSettings( rData.maHelpSettings ), + maLocale( rData.maLocale ) +{ + mnRefCount = 1; + mnSystemUpdate = rData.mnSystemUpdate; + mnWindowUpdate = rData.mnWindowUpdate; + meLanguage = rData.meLanguage; + // Pointer couldn't shared and objects haven't a copy ctor + // So we create the cache objects new, if the GetFunction is + // called + mpLocaleDataWrapper = NULL; + mpUILocaleDataWrapper = NULL; + mpCollatorWrapper = NULL; + mpUICollatorWrapper = NULL; + mpI18nHelper = NULL; + mpUII18nHelper = NULL; +} + +// ----------------------------------------------------------------------- + +ImplAllSettingsData::~ImplAllSettingsData() +{ + if ( mpLocaleDataWrapper ) + delete mpLocaleDataWrapper; + if ( mpUILocaleDataWrapper ) + delete mpUILocaleDataWrapper; + if ( mpCollatorWrapper ) + delete mpCollatorWrapper; + if ( mpUICollatorWrapper ) + delete mpUICollatorWrapper; + if ( mpI18nHelper ) + delete mpI18nHelper; + if ( mpUII18nHelper ) + delete mpUII18nHelper; +} + +// ----------------------------------------------------------------------- + +AllSettings::AllSettings() +{ + DBG_CTOR( AllSettings, NULL ); + + mpData = new ImplAllSettingsData(); +} + +// ----------------------------------------------------------------------- + +AllSettings::AllSettings( const AllSettings& rSet ) +{ + DBG_CTOR( AllSettings, NULL ); + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "Settings: RefCount overflow" ); + + // shared Instance Daten uebernehmen und Referenzcounter erhoehen + mpData = rSet.mpData; + mpData->mnRefCount++; +} + +// ----------------------------------------------------------------------- + +AllSettings::~AllSettings() +{ + DBG_DTOR( AllSettings, NULL ); + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; +} + +// ----------------------------------------------------------------------- + +const AllSettings& AllSettings::operator =( const AllSettings& rSet ) +{ + DBG_ASSERT( rSet.mpData->mnRefCount < 0xFFFFFFFE, "AllSettings: RefCount overflow" ); + DBG_CHKTHIS( AllSettings, NULL ); + DBG_CHKOBJ( &rSet, AllSettings, NULL ); + + // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann + rSet.mpData->mnRefCount++; + + // Daten loeschen, wenn letzte Referenz + if ( mpData->mnRefCount == 1 ) + delete mpData; + else + mpData->mnRefCount--; + + mpData = rSet.mpData; + + return *this; +} + +// ----------------------------------------------------------------------- + +void AllSettings::CopyData() +{ + DBG_CHKTHIS( AllSettings, NULL ); + + // Falls noch andere Referenzen bestehen, dann kopieren + if ( mpData->mnRefCount != 1 ) + { + mpData->mnRefCount--; + mpData = new ImplAllSettingsData( *mpData ); + } +} + +// ----------------------------------------------------------------------- + +ULONG AllSettings::Update( ULONG nFlags, const AllSettings& rSet ) +{ + DBG_CHKTHIS( AllSettings, NULL ); + DBG_CHKOBJ( &rSet, AllSettings, NULL ); + + ULONG nChangeFlags = 0; + + if ( nFlags & SETTINGS_MACHINE ) + { + if ( mpData->maMachineSettings != rSet.mpData->maMachineSettings ) + { + CopyData(); + mpData->maMachineSettings = rSet.mpData->maMachineSettings; + nChangeFlags |= SETTINGS_MACHINE; + } + } + + if ( nFlags & SETTINGS_MOUSE ) + { + if ( mpData->maMouseSettings != rSet.mpData->maMouseSettings ) + { + CopyData(); + mpData->maMouseSettings = rSet.mpData->maMouseSettings; + nChangeFlags |= SETTINGS_MOUSE; + } + } + + if ( nFlags & SETTINGS_KEYBOARD ) + { + if ( mpData->maKeyboardSettings != rSet.mpData->maKeyboardSettings ) + { + CopyData(); + mpData->maKeyboardSettings = rSet.mpData->maKeyboardSettings; + nChangeFlags |= SETTINGS_KEYBOARD; + } + } + + if ( nFlags & SETTINGS_STYLE ) + { + if ( mpData->maStyleSettings != rSet.mpData->maStyleSettings ) + { + CopyData(); + mpData->maStyleSettings = rSet.mpData->maStyleSettings; + nChangeFlags |= SETTINGS_STYLE; + } + } + + if ( nFlags & SETTINGS_MISC ) + { + if ( mpData->maMiscSettings != rSet.mpData->maMiscSettings ) + { + CopyData(); + mpData->maMiscSettings = rSet.mpData->maMiscSettings; + nChangeFlags |= SETTINGS_MISC; + } + } + + if ( nFlags & SETTINGS_NOTIFICATION ) + { + if ( mpData->maNotificationSettings != rSet.mpData->maNotificationSettings ) + { + CopyData(); + mpData->maNotificationSettings = rSet.mpData->maNotificationSettings; + nChangeFlags |= SETTINGS_NOTIFICATION; + } + } + + if ( nFlags & SETTINGS_HELP ) + { + if ( mpData->maHelpSettings != rSet.mpData->maHelpSettings ) + { + CopyData(); + mpData->maHelpSettings = rSet.mpData->maHelpSettings; + nChangeFlags |= SETTINGS_HELP; + } + } + + if ( nFlags & SETTINGS_INTERNATIONAL ) + { + // Nothing, class International is gone. + DBG_ERRORFILE("AllSettings::Update: who calls with SETTINGS_INTERNATIONAL and why? You're flogging a dead horse."); + } + + if ( nFlags & SETTINGS_LOCALE ) + { + if ( mpData->meLanguage || rSet.mpData->meLanguage ) + { + SetLanguage( rSet.mpData->meLanguage ); + nChangeFlags |= SETTINGS_LOCALE; + } + } + + if ( nFlags & SETTINGS_UILOCALE ) + { + // UILocale can't be changed + } + + return nChangeFlags; +} + +// ----------------------------------------------------------------------- + +ULONG AllSettings::GetChangeFlags( const AllSettings& rSet ) const +{ + DBG_CHKTHIS( AllSettings, NULL ); + DBG_CHKOBJ( &rSet, AllSettings, NULL ); + + ULONG nChangeFlags = 0; + + if ( mpData->maMachineSettings != rSet.mpData->maMachineSettings ) + nChangeFlags |= SETTINGS_MACHINE; + + if ( mpData->maMouseSettings != rSet.mpData->maMouseSettings ) + nChangeFlags |= SETTINGS_MOUSE; + + if ( mpData->maKeyboardSettings != rSet.mpData->maKeyboardSettings ) + nChangeFlags |= SETTINGS_KEYBOARD; + + if ( mpData->maStyleSettings != rSet.mpData->maStyleSettings ) + nChangeFlags |= SETTINGS_STYLE; + + if ( mpData->maMiscSettings != rSet.mpData->maMiscSettings ) + nChangeFlags |= SETTINGS_MISC; + + if ( mpData->maNotificationSettings != rSet.mpData->maNotificationSettings ) + nChangeFlags |= SETTINGS_NOTIFICATION; + + if ( mpData->maHelpSettings != rSet.mpData->maHelpSettings ) + nChangeFlags |= SETTINGS_HELP; + + if ( mpData->meLanguage || rSet.mpData->meLanguage ) + nChangeFlags |= SETTINGS_LOCALE; + + return nChangeFlags; +} + +// ----------------------------------------------------------------------- + +BOOL AllSettings::operator ==( const AllSettings& rSet ) const +{ + DBG_CHKTHIS( AllSettings, NULL ); + DBG_CHKOBJ( &rSet, AllSettings, NULL ); + + if ( mpData == rSet.mpData ) + return TRUE; + + if ( (mpData->maMachineSettings == rSet.mpData->maMachineSettings) && + (mpData->maMouseSettings == rSet.mpData->maMouseSettings) && + (mpData->maKeyboardSettings == rSet.mpData->maKeyboardSettings) && + (mpData->maStyleSettings == rSet.mpData->maStyleSettings) && + (mpData->maMiscSettings == rSet.mpData->maMiscSettings) && + (mpData->maNotificationSettings == rSet.mpData->maNotificationSettings) && + (mpData->maHelpSettings == rSet.mpData->maHelpSettings) && + (mpData->mnSystemUpdate == rSet.mpData->mnSystemUpdate) && + (mpData->maLocale == rSet.mpData->maLocale) && + (mpData->mnWindowUpdate == rSet.mpData->mnWindowUpdate) ) + { + return TRUE; + } + else + return FALSE; +} + +// ----------------------------------------------------------------------- + +void AllSettings::SetLocale( const ::com::sun::star::lang::Locale& rLocale ) +{ + CopyData(); + + mpData->maLocale = rLocale; + + if ( !rLocale.Language.getLength() ) + mpData->meLanguage = LANGUAGE_SYSTEM; + else + mpData->meLanguage = MsLangId::convertLocaleToLanguage( rLocale ); + if ( mpData->mpLocaleDataWrapper ) + { + delete mpData->mpLocaleDataWrapper; + mpData->mpLocaleDataWrapper = NULL; + } + if ( mpData->mpI18nHelper ) + { + delete mpData->mpI18nHelper; + mpData->mpI18nHelper = NULL; + } +} + +// ----------------------------------------------------------------------- + +void AllSettings::SetUILocale( const ::com::sun::star::lang::Locale& ) +{ + // there is only one UILocale per process +} + +// ----------------------------------------------------------------------- + +void AllSettings::SetLanguage( LanguageType eLang ) +{ + if ( eLang != mpData->meLanguage ) + { + CopyData(); + + mpData->meLanguage = eLang; + MsLangId::convertLanguageToLocale( GetLanguage(), ((AllSettings*)this)->mpData->maLocale ); + if ( mpData->mpLocaleDataWrapper ) + { + delete mpData->mpLocaleDataWrapper; + mpData->mpLocaleDataWrapper = NULL; + } + if ( mpData->mpI18nHelper ) + { + delete mpData->mpI18nHelper; + mpData->mpI18nHelper = NULL; + } + } +} + +// ----------------------------------------------------------------------- + +void AllSettings::SetUILanguage( LanguageType ) +{ + // there is only one UILanguage per process +} + +// ----------------------------------------------------------------------- + +BOOL AllSettings::GetLayoutRTL() const +{ + static const char* pEnv = getenv("SAL_RTL_ENABLED" ); + static int nUIMirroring = -1; // -1: undef, 0: auto, 1: on 2: off + + // environment always overrides + if( pEnv ) + return true; + + BOOL bRTL = FALSE; + + if( nUIMirroring == -1 ) + { + nUIMirroring = 0; // ask configuration only once + utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory( + vcl::unohelper::GetMultiServiceFactory(), + OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/I18N/CTL")) ); // note: case sensisitive ! + if ( aNode.isValid() ) + { + BOOL bTmp = BOOL(); + ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString(RTL_CONSTASCII_USTRINGPARAM("UIMirroring")) ); + if( aValue >>= bTmp ) + { + // found true or false; if it was nil, nothing is changed + nUIMirroring = bTmp ? 1 : 2; + } + } + } + + if( nUIMirroring == 0 ) // no config found (eg, setup) or default (nil) was set: check language + { + LanguageType aLang = LANGUAGE_DONTKNOW; + ImplSVData* pSVData = ImplGetSVData(); + if ( pSVData->maAppData.mpSettings ) + aLang = pSVData->maAppData.mpSettings->GetUILanguage(); + bRTL = MsLangId::isRightToLeft( aLang ); + } + else + bRTL = (nUIMirroring == 1); + + return bRTL; +} + +// ----------------------------------------------------------------------- + +const ::com::sun::star::lang::Locale& AllSettings::GetLocale() const +{ + if ( !mpData->maLocale.Language.getLength() ) + mpData->maLocale = mpData->maSysLocale.GetLocale(); + + return mpData->maLocale; +} + +// ----------------------------------------------------------------------- + +const ::com::sun::star::lang::Locale& AllSettings::GetUILocale() const +{ + // the UILocale is never changed + if ( !mpData->maUILocale.Language.getLength() ) + mpData->maUILocale = mpData->maSysLocale.GetUILocale(); + + return mpData->maUILocale; +} + +// ----------------------------------------------------------------------- + +LanguageType AllSettings::GetLanguage() const +{ + // meLanguage == LANGUAGE_SYSTEM means: use settings from SvtSysLocale + if ( mpData->meLanguage == LANGUAGE_SYSTEM ) + return mpData->maSysLocale.GetLanguage(); + + return mpData->meLanguage; +} + +// ----------------------------------------------------------------------- + +LanguageType AllSettings::GetUILanguage() const +{ + // the UILanguage is never changed + return mpData->maSysLocale.GetUILanguage(); +} + +// ----------------------------------------------------------------------- + +const LocaleDataWrapper& AllSettings::GetLocaleDataWrapper() const +{ + if ( !mpData->mpLocaleDataWrapper ) + ((AllSettings*)this)->mpData->mpLocaleDataWrapper = new LocaleDataWrapper( vcl::unohelper::GetMultiServiceFactory(), GetLocale() ); + return *mpData->mpLocaleDataWrapper; +} + +// ----------------------------------------------------------------------- + +const LocaleDataWrapper& AllSettings::GetUILocaleDataWrapper() const +{ + if ( !mpData->mpUILocaleDataWrapper ) + ((AllSettings*)this)->mpData->mpUILocaleDataWrapper = new LocaleDataWrapper( vcl::unohelper::GetMultiServiceFactory(), GetUILocale() ); + return *mpData->mpUILocaleDataWrapper; +} + +// ----------------------------------------------------------------------- + +const vcl::I18nHelper& AllSettings::GetLocaleI18nHelper() const +{ + if ( !mpData->mpI18nHelper ) { + ::com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> aFactory(vcl::unohelper::GetMultiServiceFactory()); + ((AllSettings*)this)->mpData->mpI18nHelper = new vcl::I18nHelper( aFactory, GetLocale() ); + } + return *mpData->mpI18nHelper; +} + +// ----------------------------------------------------------------------- + +const vcl::I18nHelper& AllSettings::GetUILocaleI18nHelper() const +{ + if ( !mpData->mpUII18nHelper ) { + ::com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> aFactory(vcl::unohelper::GetMultiServiceFactory()); + ((AllSettings*)this)->mpData->mpUII18nHelper = new vcl::I18nHelper( aFactory, GetUILocale() ); + } + return *mpData->mpUII18nHelper; +} + + +// ----------------------------------------------------------------------- +/* +const CollatorWrapper& AllSettings::GetCollatorWrapper() const +{ + if ( !mpData->mpCollatorWrapper ) + { + ((AllSettings*)this)->mpData->mpCollatorWrapper = new CollatorWrapper( vcl::unohelper::GetMultiServiceFactory() ); + ((AllSettings*)this)->mpData->mpCollatorWrapper->loadDefaultCollator( GetLocale(), 0 ); + } + return *mpData->mpCollatorWrapper; +} +*/ +// ----------------------------------------------------------------------- +/* +const CollatorWrapper& AllSettings::GetUICollatorWrapper() const +{ + if ( !mpData->mpUICollatorWrapper ) + { + ((AllSettings*)this)->mpData->mpUICollatorWrapper = new CollatorWrapper( vcl::unohelper::GetMultiServiceFactory() ); + ((AllSettings*)this)->mpData->mpUICollatorWrapper->loadDefaultCollator( GetUILocale(), 0 ); + } + return *mpData->mpUICollatorWrapper; +} +*/ + +void AllSettings::LocaleSettingsChanged( sal_uInt32 nHint ) +{ + AllSettings aAllSettings( Application::GetSettings() ); + if ( nHint & SYSLOCALEOPTIONS_HINT_DECSEP ) + { + MiscSettings aMiscSettings = aAllSettings.GetMiscSettings(); + BOOL bIsDecSepAsLocale = aAllSettings.mpData->maSysLocale.GetOptions().IsDecimalSeparatorAsLocale(); + if ( aMiscSettings.GetEnableLocalizedDecimalSep() != bIsDecSepAsLocale ) + { + aMiscSettings.SetEnableLocalizedDecimalSep( bIsDecSepAsLocale ); + aAllSettings.SetMiscSettings( aMiscSettings ); + } + } + + if ( (nHint & SYSLOCALEOPTIONS_HINT_LOCALE) ) + aAllSettings.SetLocale( aAllSettings.mpData->maSysLocale.GetOptions().GetLocale() ); + + Application::SetSettings( aAllSettings ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/solarmutex.cxx b/vcl/source/app/solarmutex.cxx new file mode 100644 index 000000000000..6423a74e6c61 --- /dev/null +++ b/vcl/source/app/solarmutex.cxx @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <vcl/solarmutex.hxx> + +using namespace vcl; + +SolarMutexObject::SolarMutexObject() : m_solarMutex( osl_createMutex() ) +{ +} + +SolarMutexObject::~SolarMutexObject() +{ + osl_destroyMutex( m_solarMutex ); +} + +void SolarMutexObject::acquire() +{ + osl_acquireMutex( m_solarMutex ); +} + +sal_Bool SolarMutexObject::tryToAcquire() +{ + return osl_tryToAcquireMutex( m_solarMutex ); +} + +void SolarMutexObject::release() +{ + osl_releaseMutex( m_solarMutex ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
\ No newline at end of file diff --git a/vcl/source/app/sound.cxx b/vcl/source/app/sound.cxx new file mode 100644 index 000000000000..30ecf5c3a3a4 --- /dev/null +++ b/vcl/source/app/sound.cxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" +#include <tools/urlobj.hxx> +#include <unotools/localfilehelper.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <svsys.h> +#include <vcl/salframe.hxx> +#include <tools/debug.hxx> +#include <vcl/svdata.hxx> +#include <vcl/window.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/sound.hxx> +#include <vcl/salinst.hxx> + +void Sound::Beep( SoundType eType, Window* pWindow ) +{ + if( !pWindow ) + { + Window* pDefWindow = ImplGetDefaultWindow(); + pDefWindow->ImplGetFrame()->Beep( eType ); + } + else + pWindow->ImplGetFrame()->Beep( eType ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/stdtext.cxx b/vcl/source/app/stdtext.cxx new file mode 100644 index 000000000000..ba8d69abbd3e --- /dev/null +++ b/vcl/source/app/stdtext.cxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include <vcl/svids.hrc> +#include <vcl/svdata.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/stdtext.hxx> + + + +// ======================================================================= + +XubString GetStandardText( USHORT nStdText ) +{ + ResMgr* pResMgr = ImplGetResMgr(); + XubString aText; + if( pResMgr ) + aText = XubString( ResId( nStdText-STANDARD_TEXT_FIRST+SV_STDTEXT_FIRST, *pResMgr ) ); + return aText; +} + +// ======================================================================= + +void ShowServiceNotAvailableError( Window* pParent, + const XubString& rServiceName, BOOL bError ) +{ + XubString aText( GetStandardText( STANDARD_TEXT_SERVICE_NOT_AVAILABLE ) ); + aText.SearchAndReplaceAscii( "%s", rServiceName ); + if ( bError ) + { + ErrorBox aBox( pParent, WB_OK | WB_DEF_OK, aText ); + aBox.Execute(); + } + else + { + WarningBox aBox( pParent, WB_OK | WB_DEF_OK, aText ); + aBox.Execute(); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx new file mode 100644 index 000000000000..b86477f32fb4 --- /dev/null +++ b/vcl/source/app/svapp.cxx @@ -0,0 +1,2087 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "svsys.h" +#include "vcl/salinst.hxx" +#include "vcl/salframe.hxx" +#include "vcl/salsys.hxx" +#include "tools/tools.h" +#include "tools/debug.hxx" +#include "tools/time.hxx" +#include "i18npool/mslangid.hxx" +#include "vcl/svdata.hxx" +#include "vcl/settings.hxx" +#include "vcl/accmgr.hxx" +#include "vcl/keycod.hxx" +#include "vcl/event.hxx" +#include "vcl/vclevent.hxx" +#include "vcl/virdev.hxx" +#include "vcl/windata.hxx" +#include "vcl/window.h" +#include "vcl/wrkwin.hxx" +#include "vcl/idlemgr.hxx" +#include "vcl/svapp.hxx" +#include "vcl/cvtgrf.hxx" +#include "vcl/unowrap.hxx" +#include "vcl/xconnection.hxx" +#include "vcl/svids.hrc" +#include "vcl/timer.hxx" + +#include "vcl/unohelp.hxx" + +#include "com/sun/star/uno/Reference.h" +#include "com/sun/star/awt/XToolkit.hpp" +#include "com/sun/star/uno/XNamingService.hpp" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "comphelper/processfactory.hxx" + +#include "osl/module.h" +#include "osl/file.hxx" +#include "osl/mutex.hxx" +#include "osl/process.h" +#include "osl/thread.h" +#include "rtl/tencinfo.h" +#include "rtl/instance.hxx" +#include "vcl/salimestatus.hxx" + +#include <utility> +#include <vcl/lazydelete.hxx> +#include <unotools/syslocaleoptions.hxx> + +using namespace ::com::sun::star::uno; + +// keycodes handled internally by VCL +class ImplReservedKey +{ +public: + ImplReservedKey( KeyCode aKeyCode, USHORT nResId ) : + mKeyCode(aKeyCode), mnResId( nResId) + {} + + KeyCode mKeyCode; + USHORT mnResId; +}; + +typedef std::pair<ImplReservedKey*, size_t> ReservedKeys; +namespace +{ + struct ImplReservedKeysImpl + { + ReservedKeys* operator()() + { + static ImplReservedKey ImplReservedKeys[] = + { + ImplReservedKey(KeyCode(KEY_F1,0), SV_SHORTCUT_HELP), + ImplReservedKey(KeyCode(KEY_F1,KEY_SHIFT), SV_SHORTCUT_ACTIVEHELP), + ImplReservedKey(KeyCode(KEY_F1,KEY_MOD1), SV_SHORTCUT_CONTEXTHELP), + ImplReservedKey(KeyCode(KEY_F2,KEY_SHIFT), SV_SHORTCUT_CONTEXTHELP), + ImplReservedKey(KeyCode(KEY_F4,KEY_MOD1), SV_SHORTCUT_DOCKUNDOCK), + ImplReservedKey(KeyCode(KEY_F4,KEY_MOD2), SV_SHORTCUT_DOCKUNDOCK), + ImplReservedKey(KeyCode(KEY_F4,KEY_MOD1|KEY_MOD2), SV_SHORTCUT_DOCKUNDOCK), + ImplReservedKey(KeyCode(KEY_F6,0), SV_SHORTCUT_NEXTSUBWINDOW), + ImplReservedKey(KeyCode(KEY_F6,KEY_MOD1), SV_SHORTCUT_TODOCUMENT), + ImplReservedKey(KeyCode(KEY_F6,KEY_SHIFT), SV_SHORTCUT_PREVSUBWINDOW), + ImplReservedKey(KeyCode(KEY_F6,KEY_MOD1|KEY_SHIFT), SV_SHORTCUT_SPLITTER), + ImplReservedKey(KeyCode(KEY_F10,0), SV_SHORTCUT_MENUBAR) +#ifdef UNX + , + ImplReservedKey(KeyCode(KEY_1,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_2,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_3,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_4,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_5,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_6,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_7,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_8,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_9,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_0,KEY_SHIFT|KEY_MOD1), 0), + ImplReservedKey(KeyCode(KEY_ADD,KEY_SHIFT|KEY_MOD1), 0) +#endif + }; + static ReservedKeys aKeys + ( + &ImplReservedKeys[0], + sizeof(ImplReservedKeys) / sizeof(ImplReservedKey) + ); + return &aKeys; + } + }; + + struct ImplReservedKeys + : public rtl::StaticAggregate<ReservedKeys, ImplReservedKeysImpl> {}; +} + + +class Reflection; + + + +extern "C" { + typedef UnoWrapperBase* (SAL_CALL *FN_TkCreateUnoWrapper)(); +} + +// ======================================================================= + +// -------------- +// - ImplHotKey - +// -------------- + +struct ImplHotKey +{ + ImplHotKey* mpNext; + void* mpUserData; + KeyCode maKeyCode; + Link maLink; +}; + +// ======================================================================= + +// ----------------- +// - ImplEventHook - +// ----------------- + +struct ImplEventHook +{ + ImplEventHook* mpNext; + void* mpUserData; + VCLEventHookProc mpProc; +}; + +// ======================================================================= + +// --------------------- +// - ImplPostEventData - +// --------------------- + +struct ImplPostEventData +{ + ULONG mnEvent; + const Window* mpWin; + ULONG mnEventId; + KeyEvent maKeyEvent; + MouseEvent maMouseEvent; + + + ImplPostEventData( ULONG nEvent, const Window* pWin, const KeyEvent& rKeyEvent ) : + mnEvent( nEvent ), mpWin( pWin ), mnEventId( 0 ), maKeyEvent( rKeyEvent ) {} + ImplPostEventData( ULONG nEvent, const Window* pWin, const MouseEvent& rMouseEvent ) : + mnEvent( nEvent ), mpWin( pWin ), mnEventId( 0 ), maMouseEvent( rMouseEvent ) {} + + ~ImplPostEventData() {} +}; + +typedef ::std::pair< Window*, ImplPostEventData* > ImplPostEventPair; + +static ::std::list< ImplPostEventPair > aPostedEventList; + +// ======================================================================= + +Application* GetpApp() +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( !pSVData ) + return NULL; + return pSVData->mpApp; +} + +// ----------------------------------------------------------------------- + +Application::Application() +{ + if( ! ImplGetSVData() ) + ImplInitSVData(); + ImplGetSVData()->mpApp = this; + InitSalData(); +} + +// ----------------------------------------------------------------------- + +Application::~Application() +{ + ImplDeInitSVData(); + DeInitSalData(); + ImplGetSVData()->mpApp = NULL; + ImplDestroySVData(); + GlobalDeInitTools(); +} + +// ----------------------------------------------------------------------- + +void Application::InitAppRes( const ResId& ) +{ +} + +// ----------------------------------------------------------------------- + +BOOL Application::QueryExit() +{ + WorkWindow* pAppWin = ImplGetSVData()->maWinData.mpAppWin; + + // Aufruf des Close-Handlers des Applikationsfensters + if ( pAppWin ) + return pAppWin->Close(); + else + return TRUE; +} + +// ----------------------------------------------------------------------- + +void Application::UserEvent( ULONG, void* ) +{ +} + +// ----------------------------------------------------------------------- + +void Application::ShowStatusText( const XubString& ) +{ +} + +// ----------------------------------------------------------------------- + +void Application::ShowHelpStatusText( const XubString& ) +{ +} + +// ----------------------------------------------------------------------- + +void Application::ActivateExtHelp() +{ +} + +// ----------------------------------------------------------------------- + +void Application::DeactivateExtHelp() +{ +} + +// ----------------------------------------------------------------------- + +void Application::HideStatusText() +{ +} + +// ----------------------------------------------------------------------- + +void Application::HideHelpStatusText() +{ +} + +// ----------------------------------------------------------------------- + +void Application::FocusChanged() +{ +} + +// ----------------------------------------------------------------------- + +void Application::DataChanged( const DataChangedEvent& ) +{ +} + +// ----------------------------------------------------------------------- +void Application::Init() +{ +} + +// ----------------------------------------------------------------------- +void Application::InitFinished() +{ +} + +// ----------------------------------------------------------------------- + +void Application::DeInit() +{ +} + +// ----------------------------------------------------------------------- + +sal_uInt16 Application::GetCommandLineParamCount() +{ + return (sal_uInt16)osl_getCommandArgCount(); +} + +// ----------------------------------------------------------------------- + +XubString Application::GetCommandLineParam( USHORT nParam ) +{ + rtl::OUString aParam; + osl_getCommandArg( nParam, &aParam.pData ); + return aParam; +} + +// ----------------------------------------------------------------------- + +const XubString& Application::GetAppFileName() +{ + ImplSVData* pSVData = ImplGetSVData(); + DBG_ASSERT( pSVData->maAppData.mpAppFileName, "AppFileName vor SVMain ?!" ); + if ( pSVData->maAppData.mpAppFileName ) + return *pSVData->maAppData.mpAppFileName; + + /* + * #91147# provide a fallback for people without initialized + * vcl here (like setup in responsefile mode) + */ + static String aAppFileName; + if( !aAppFileName.Len() ) + { + rtl::OUString aExeFileName; + osl_getExecutableFile( &aExeFileName.pData ); + + // convert path to native file format + rtl::OUString aNativeFileName; + osl::FileBase::getSystemPathFromFileURL( aExeFileName, aNativeFileName ); + aAppFileName = aNativeFileName; + } + + return aAppFileName; +} + +// ----------------------------------------------------------------------- + +USHORT Application::Exception( USHORT nError ) +{ + switch ( nError & EXC_MAJORTYPE ) + { + // Bei System machen wir nichts und lassen dem System den + // vortritt + case EXC_SYSTEM: + return 0; + + case EXC_DISPLAY: + case EXC_REMOTE: + return 0; + +#ifdef DBG_UTIL + case EXC_RSCNOTLOADED: + Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "Resource not loaded" ) ) ); + break; + case EXC_SYSOBJNOTCREATED: + Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "System Object not created" ) ) ); + break; + default: + Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "Unknown Error" ) ) ); + break; +#else + default: + Abort( ImplGetSVEmptyStr() ); + break; +#endif + } + + return 0; +} + +// ----------------------------------------------------------------------- + +void Application::Abort( const XubString& rErrorText ) +{ + SalAbort( rErrorText ); +} + +// ----------------------------------------------------------------------- + +ULONG Application::GetReservedKeyCodeCount() +{ + return ImplReservedKeys::get()->second; +} + +const KeyCode* Application::GetReservedKeyCode( ULONG i ) +{ + if( i >= GetReservedKeyCodeCount() ) + return NULL; + else + return &ImplReservedKeys::get()->first[i].mKeyCode; +} + +String Application::GetReservedKeyCodeDescription( ULONG i ) +{ + ResMgr* pResMgr = ImplGetResMgr(); + if( ! pResMgr ) + return String(); + ImplReservedKey *pImplReservedKeys = ImplReservedKeys::get()->first; + if( i >= GetReservedKeyCodeCount() || ! pImplReservedKeys[i].mnResId ) + return String(); + else + return String( ResId( pImplReservedKeys[i].mnResId, *pResMgr ) ); +} + +// ----------------------------------------------------------------------- + +void Application::Execute() +{ + DBG_STARTAPPEXECUTE(); + + ImplSVData* pSVData = ImplGetSVData(); + pSVData->maAppData.mbInAppExecute = TRUE; + + while ( !pSVData->maAppData.mbAppQuit ) + Application::Yield(); + + pSVData->maAppData.mbInAppExecute = FALSE; + + DBG_ENDAPPEXECUTE(); +} + +// ----------------------------------------------------------------------- + +inline void ImplYield( bool i_bWait, bool i_bAllEvents ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + // run timers that have timed out + if ( !pSVData->mbNoCallTimer ) + while ( pSVData->mbNotAllTimerCalled ) + Timer::ImplTimerCallbackProc(); + + pSVData->maAppData.mnDispatchLevel++; + // do not wait for events if application was already quit; in that + // case only dispatch events already available + // do not wait for events either if the app decided that it is too busy for timers + // (feature added for the slideshow) + pSVData->mpDefInst->Yield( i_bWait && !pSVData->maAppData.mbAppQuit && !pSVData->maAppData.mbNoYield, i_bAllEvents ); + pSVData->maAppData.mnDispatchLevel--; + + // flush lazy deleted objects + if( pSVData->maAppData.mnDispatchLevel == 0 ) + vcl::LazyDelete::flush(); + + // the system timer events will not necesseraly come in in non waiting mode + // e.g. on aqua; need to trigger timer checks manually + if( pSVData->maAppData.mbNoYield && !pSVData->mbNoCallTimer ) + { + do + { + Timer::ImplTimerCallbackProc(); + } + while( pSVData->mbNotAllTimerCalled ); + } + + // call post yield listeners + if( pSVData->maAppData.mpPostYieldListeners ) + pSVData->maAppData.mpPostYieldListeners->callListeners( NULL ); +} + +// ----------------------------------------------------------------------- + +void Application::Reschedule( bool i_bAllEvents ) +{ + ImplYield( false, i_bAllEvents ); +} + +// ----------------------------------------------------------------------- + +void Application::Yield( bool i_bAllEvents ) +{ + ImplYield( true, i_bAllEvents ); +} + +// ----------------------------------------------------------------------- + +IMPL_STATIC_LINK_NOINSTANCE( ImplSVAppData, ImplQuitMsg, void*, EMPTYARG ) +{ + ImplGetSVData()->maAppData.mbAppQuit = TRUE; + return 0; +} + +// ----------------------------------------------------------------------- + +void Application::Quit() +{ + Application::PostUserEvent( STATIC_LINK( NULL, ImplSVAppData, ImplQuitMsg ) ); +} + +// ----------------------------------------------------------------------- + +osl::SolarMutex& Application::GetSolarMutex() +{ + ImplSVData* pSVData = ImplGetSVData(); + return *(pSVData->mpDefInst->GetYieldMutex()); +} + +// ----------------------------------------------------------------------- + +oslThreadIdentifier Application::GetMainThreadIdentifier() +{ + return ImplGetSVData()->mnMainThreadId; +} + +// ----------------------------------------------------------------------- + +ULONG Application::ReleaseSolarMutex() +{ + ImplSVData* pSVData = ImplGetSVData(); + return pSVData->mpDefInst->ReleaseYieldMutex(); +} + +// ----------------------------------------------------------------------- + +void Application::AcquireSolarMutex( ULONG nCount ) +{ + ImplSVData* pSVData = ImplGetSVData(); + pSVData->mpDefInst->AcquireYieldMutex( nCount ); +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsInMain() +{ + return ImplGetSVData()->maAppData.mbInAppMain; +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsInExecute() +{ + return ImplGetSVData()->maAppData.mbInAppExecute; +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsShutDown() +{ + return ImplGetSVData()->maAppData.mbAppQuit; +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsInModalMode() +{ + return (ImplGetSVData()->maAppData.mnModalMode != 0); +} + +// ----------------------------------------------------------------------- + +USHORT Application::GetModalModeCount() +{ + return ImplGetSVData()->maAppData.mnModalMode; +} + +// ----------------------------------------------------------------------- + +USHORT Application::GetDispatchLevel() +{ + return ImplGetSVData()->maAppData.mnDispatchLevel; +} + +// ----------------------------------------------------------------------- + +BOOL Application::AnyInput( USHORT nType ) +{ + return (BOOL)ImplGetSVData()->mpDefInst->AnyInput( nType ); +} + +// ----------------------------------------------------------------------- + +ULONG Application::GetLastInputInterval() +{ + return (Time::GetSystemTicks()-ImplGetSVData()->maAppData.mnLastInputTime); +} + +// ----------------------------------------------------------------------- + +extern int nImplSysDialog; + +BOOL Application::IsUICaptured() +{ + ImplSVData* pSVData = ImplGetSVData(); + // Wenn Mouse gecaptured, oder im TrackingModus oder im Auswahlmodus + // eines FloatingWindows (wie Menus, Aufklapp-ToolBoxen) soll kein + // weiteres Fenster aufgezogen werden + // D&D aktive !!! + if ( pSVData->maWinData.mpCaptureWin || pSVData->maWinData.mpTrackWin || + pSVData->maWinData.mpFirstFloat || nImplSysDialog ) + return TRUE; + else + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsUserActive( USHORT nTest ) +{ + if ( nTest & (USERACTIVE_MOUSEDRAG | USERACTIVE_INPUT) ) + { + if ( IsUICaptured() ) + return TRUE; + } + + if ( nTest & USERACTIVE_INPUT ) + { + if ( GetLastInputInterval() < 500 ) + return TRUE; + + if ( AnyInput( INPUT_KEYBOARD ) ) + return TRUE; + } + + if ( nTest & USERACTIVE_MODALDIALOG ) + { + if ( ImplGetSVData()->maAppData.mnModalDialog ) + return TRUE; + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +void Application::SystemSettingsChanging( AllSettings& /*rSettings*/, + Window* /*pFrame*/ ) +{ +} + +// ----------------------------------------------------------------------- + +void Application::MergeSystemSettings( AllSettings& rSettings ) +{ + Window* pWindow = ImplGetSVData()->maWinData.mpFirstFrame; + if( ! pWindow ) + pWindow = ImplGetDefaultWindow(); + if( pWindow ) + { + ImplSVData* pSVData = ImplGetSVData(); + if ( !pSVData->maAppData.mbSettingsInit ) + { + // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings + pWindow->ImplUpdateGlobalSettings( *pSVData->maAppData.mpSettings ); + pSVData->maAppData.mbSettingsInit = TRUE; + } + // side effect: ImplUpdateGlobalSettings does an ImplGetFrame()->UpdateSettings + pWindow->ImplUpdateGlobalSettings( rSettings, FALSE ); + } +} + +// ----------------------------------------------------------------------- + +bool Application::ValidateSystemFont() +{ + Window* pWindow = ImplGetSVData()->maWinData.mpFirstFrame; + if( ! pWindow ) + pWindow = ImplGetDefaultWindow(); + + if( pWindow ) + { + AllSettings aSettings; + pWindow->ImplGetFrame()->UpdateSettings( aSettings ); + return pWindow->ImplCheckUIFont( aSettings.GetStyleSettings().GetAppFont() ); + } + return false; +} + +// ----------------------------------------------------------------------- + +void Application::SetSettings( const AllSettings& rSettings ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( !pSVData->maAppData.mpSettings ) + { + GetSettings(); + *pSVData->maAppData.mpSettings = rSettings; + ResMgr::SetDefaultLocale( rSettings.GetUILocale() ); + } + else + { + AllSettings aOldSettings = *pSVData->maAppData.mpSettings; + if( aOldSettings.GetUILanguage() != rSettings.GetUILanguage() && pSVData->mpResMgr ) + { + delete pSVData->mpResMgr; + pSVData->mpResMgr = NULL; + } + ResMgr::SetDefaultLocale( rSettings.GetUILocale() ); + *pSVData->maAppData.mpSettings = rSettings; + ULONG nChangeFlags = aOldSettings.GetChangeFlags( *pSVData->maAppData.mpSettings ); + if ( nChangeFlags ) + { + DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags ); + GetpApp()->DataChanged( aDCEvt ); + + // notify data change handler + ImplCallEventListeners( VCLEVENT_APPLICATION_DATACHANGED, NULL, &aDCEvt); + + // Update all windows + Window* pFirstFrame = pSVData->maWinData.mpFirstFrame; + // Daten, die neu berechnet werden muessen, zuruecksetzen + long nOldDPIX = 0; + long nOldDPIY = 0; + if ( pFirstFrame ) + { + nOldDPIX = pFirstFrame->mnDPIX; + nOldDPIY = pFirstFrame->mnDPIY; + pSVData->maGDIData.mnAppFontX = 0; + } + Window* pFrame = pFirstFrame; + while ( pFrame ) + { + // AppFont-Cache-Daten zuruecksetzen + pFrame->mpWindowImpl->mpFrameData->meMapUnit = MAP_PIXEL; + + // UpdateSettings am ClientWindow aufrufen, damit + // die Daten nicht doppelt geupdatet werden + Window* pClientWin = pFrame; + while ( pClientWin->ImplGetClientWindow() ) + pClientWin = pClientWin->ImplGetClientWindow(); + pClientWin->UpdateSettings( rSettings, TRUE ); + + Window* pTempWin = pFrame->mpWindowImpl->mpFrameData->mpFirstOverlap; + while ( pTempWin ) + { + // UpdateSettings am ClientWindow aufrufen, damit + // die Daten nicht doppelt geupdatet werden + pClientWin = pTempWin; + while ( pClientWin->ImplGetClientWindow() ) + pClientWin = pClientWin->ImplGetClientWindow(); + pClientWin->UpdateSettings( rSettings, TRUE ); + pTempWin = pTempWin->mpWindowImpl->mpNextOverlap; + } + + pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame; + } + + // Wenn sich die DPI-Aufloesung fuer Screen-Ausgaben + // geaendert hat, setzen wir auch bei allen + // Screen-Kompatiblen VirDev's die neue Aufloesung + pFirstFrame = pSVData->maWinData.mpFirstFrame; + if ( pFirstFrame ) + { + if ( (pFirstFrame->mnDPIX != nOldDPIX) || + (pFirstFrame->mnDPIY != nOldDPIY) ) + { + VirtualDevice* pVirDev = pSVData->maGDIData.mpFirstVirDev; + while ( pVirDev ) + { + if ( pVirDev->mbScreenComp && + (pVirDev->mnDPIX == nOldDPIX) && + (pVirDev->mnDPIY == nOldDPIY) ) + { + pVirDev->mnDPIX = pFirstFrame->mnDPIX; + pVirDev->mnDPIY = pFirstFrame->mnDPIY; + if ( pVirDev->IsMapMode() ) + { + MapMode aMapMode = pVirDev->GetMapMode(); + pVirDev->SetMapMode(); + pVirDev->SetMapMode( aMapMode ); + } + } + + pVirDev = pVirDev->mpNext; + } + } + } + } + } +} + +// ----------------------------------------------------------------------- + +const AllSettings& Application::GetSettings() +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( !pSVData->maAppData.mpSettings ) + { + pSVData->maAppData.mpCfgListener = new LocaleConfigurationListener; + pSVData->maAppData.mpSettings = new AllSettings(); + pSVData->maAppData.mpSettings->GetSysLocale().GetOptions().AddListener( pSVData->maAppData.mpCfgListener ); + } + + return *(pSVData->maAppData.mpSettings); +} + +// ----------------------------------------------------------------------- + +void Application::NotifyAllWindows( DataChangedEvent& rDCEvt ) +{ + ImplSVData* pSVData = ImplGetSVData(); + Window* pFrame = pSVData->maWinData.mpFirstFrame; + while ( pFrame ) + { + pFrame->NotifyAllChilds( rDCEvt ); + + Window* pSysWin = pFrame->mpWindowImpl->mpFrameData->mpFirstOverlap; + while ( pSysWin ) + { + pSysWin->NotifyAllChilds( rDCEvt ); + pSysWin = pSysWin->mpWindowImpl->mpNextOverlap; + } + + pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame; + } +} + +// ----------------------------------------------------------------------- + +void Application::ImplCallEventListeners( ULONG nEvent, Window *pWin, void* pData ) +{ + ImplSVData* pSVData = ImplGetSVData(); + VclWindowEvent aEvent( pWin, nEvent, pData ); + + if ( pSVData->maAppData.mpEventListeners ) + if ( !pSVData->maAppData.mpEventListeners->empty() ) + pSVData->maAppData.mpEventListeners->Call( &aEvent ); +} + +// ----------------------------------------------------------------------- + +void Application::ImplCallEventListeners( VclSimpleEvent* pEvent ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maAppData.mpEventListeners ) + if ( !pSVData->maAppData.mpEventListeners->empty() ) + pSVData->maAppData.mpEventListeners->Call( pEvent ); +} + +// ----------------------------------------------------------------------- + +void Application::AddEventListener( const Link& rEventListener ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if( !pSVData->maAppData.mpEventListeners ) + pSVData->maAppData.mpEventListeners = new VclEventListeners; + pSVData->maAppData.mpEventListeners->push_back( rEventListener ); +} + +// ----------------------------------------------------------------------- + +void Application::RemoveEventListener( const Link& rEventListener ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if( pSVData->maAppData.mpEventListeners ) + pSVData->maAppData.mpEventListeners->remove( rEventListener ); +} + +// ----------------------------------------------------------------------- +void Application::AddKeyListener( const Link& rKeyListener ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if( !pSVData->maAppData.mpKeyListeners ) + pSVData->maAppData.mpKeyListeners = new VclEventListeners; + pSVData->maAppData.mpKeyListeners->push_back( rKeyListener ); +} + +// ----------------------------------------------------------------------- + +void Application::RemoveKeyListener( const Link& rKeyListener ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if( pSVData->maAppData.mpKeyListeners ) + pSVData->maAppData.mpKeyListeners->remove( rKeyListener ); +} + +// ----------------------------------------------------------------------- + +BOOL Application::HandleKey( ULONG nEvent, Window *pWin, KeyEvent* pKeyEvent ) +{ + // let listeners process the key event + VclWindowEvent aEvent( pWin, nEvent, (void *) pKeyEvent ); + + ImplSVData* pSVData = ImplGetSVData(); + BOOL bProcessed = FALSE; + + if ( pSVData->maAppData.mpKeyListeners ) + if ( !pSVData->maAppData.mpKeyListeners->empty() ) + bProcessed = pSVData->maAppData.mpKeyListeners->Process( &aEvent ); + + return bProcessed; +} + +// ----------------------------------------------------------------------------- + +ULONG Application::PostKeyEvent( ULONG nEvent, Window *pWin, KeyEvent* pKeyEvent ) +{ + const SolarMutexGuard aGuard; + ULONG nEventId = 0; + + if( pWin && pKeyEvent ) + { + ImplPostEventData* pPostEventData = new ImplPostEventData( nEvent, pWin, *pKeyEvent ); + + PostUserEvent( nEventId, + STATIC_LINK( NULL, Application, PostEventHandler ), + pPostEventData ); + + if( nEventId ) + { + pPostEventData->mnEventId = nEventId; + aPostedEventList.push_back( ImplPostEventPair( pWin, pPostEventData ) ); + } + else + delete pPostEventData; + } + + return nEventId; +} + +// ----------------------------------------------------------------------------- + +ULONG Application::PostMouseEvent( ULONG nEvent, Window *pWin, MouseEvent* pMouseEvent ) +{ + const SolarMutexGuard aGuard; + ULONG nEventId = 0; + + if( pWin && pMouseEvent ) + { + Point aTransformedPos( pMouseEvent->GetPosPixel() ); + + aTransformedPos.X() += pWin->mnOutOffX; + aTransformedPos.Y() += pWin->mnOutOffY; + + const MouseEvent aTransformedEvent( aTransformedPos, pMouseEvent->GetClicks(), pMouseEvent->GetMode(), + pMouseEvent->GetButtons(), pMouseEvent->GetModifier() ); + + ImplPostEventData* pPostEventData = new ImplPostEventData( nEvent, pWin, aTransformedEvent ); + + PostUserEvent( nEventId, + STATIC_LINK( NULL, Application, PostEventHandler ), + pPostEventData ); + + if( nEventId ) + { + pPostEventData->mnEventId = nEventId; + aPostedEventList.push_back( ImplPostEventPair( pWin, pPostEventData ) ); + } + else + delete pPostEventData; + } + + return nEventId; +} + +// ----------------------------------------------------------------------------- + +IMPL_STATIC_LINK_NOINSTANCE( Application, PostEventHandler, void*, pCallData ) +{ + const SolarMutexGuard aGuard; + ImplPostEventData* pData = static_cast< ImplPostEventData * >( pCallData ); + const void* pEventData; + ULONG nEvent; + const ULONG nEventId = pData->mnEventId; + + switch( pData->mnEvent ) + { + case VCLEVENT_WINDOW_MOUSEMOVE: + nEvent = SALEVENT_EXTERNALMOUSEMOVE; + pEventData = &pData->maMouseEvent; + break; + + case VCLEVENT_WINDOW_MOUSEBUTTONDOWN: + nEvent = SALEVENT_EXTERNALMOUSEBUTTONDOWN; + pEventData = &pData->maMouseEvent; + break; + + case VCLEVENT_WINDOW_MOUSEBUTTONUP: + nEvent = SALEVENT_EXTERNALMOUSEBUTTONUP; + pEventData = &pData->maMouseEvent; + break; + + case VCLEVENT_WINDOW_KEYINPUT: + nEvent = SALEVENT_EXTERNALKEYINPUT; + pEventData = &pData->maKeyEvent; + break; + + case VCLEVENT_WINDOW_KEYUP: + nEvent = SALEVENT_EXTERNALKEYUP; + pEventData = &pData->maKeyEvent; + break; + + default: + nEvent = 0; + pEventData = NULL; + break; + }; + + if( pData->mpWin && pData->mpWin->mpWindowImpl->mpFrameWindow && pEventData ) + ImplWindowFrameProc( pData->mpWin->mpWindowImpl->mpFrameWindow, NULL, (USHORT) nEvent, pEventData ); + + // remove this event from list of posted events, watch for destruction of internal data + ::std::list< ImplPostEventPair >::iterator aIter( aPostedEventList.begin() ); + + while( aIter != aPostedEventList.end() ) + { + if( nEventId == (*aIter).second->mnEventId ) + { + delete (*aIter).second; + aIter = aPostedEventList.erase( aIter ); + } + else + ++aIter; + } + + return 0; +} + +// ----------------------------------------------------------------------- + +void Application::RemoveMouseAndKeyEvents( Window* pWin ) +{ + const SolarMutexGuard aGuard; + + // remove all events for specific window, watch for destruction of internal data + ::std::list< ImplPostEventPair >::iterator aIter( aPostedEventList.begin() ); + + while( aIter != aPostedEventList.end() ) + { + if( pWin == (*aIter).first ) + { + if( (*aIter).second->mnEventId ) + RemoveUserEvent( (*aIter).second->mnEventId ); + + delete (*aIter).second; + aIter = aPostedEventList.erase( aIter ); + } + else + ++aIter; + } +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsProcessedMouseOrKeyEvent( ULONG nEventId ) +{ + const SolarMutexGuard aGuard; + + // find event + ::std::list< ImplPostEventPair >::iterator aIter( aPostedEventList.begin() ); + + while( aIter != aPostedEventList.end() ) + { + if( (*aIter).second->mnEventId == nEventId ) + return FALSE; + + else + ++aIter; + } + return TRUE; +} + +// ----------------------------------------------------------------------- + +ULONG Application::PostUserEvent( ULONG nEvent, void* pEventData ) +{ + ULONG nEventId; + PostUserEvent( nEventId, nEvent, pEventData ); + return nEventId; +} + +// ----------------------------------------------------------------------- + +ULONG Application::PostUserEvent( const Link& rLink, void* pCaller ) +{ + ULONG nEventId; + PostUserEvent( nEventId, rLink, pCaller ); + return nEventId; +} + +// ----------------------------------------------------------------------- + +BOOL Application::PostUserEvent( ULONG& rEventId, ULONG nEvent, void* pEventData ) +{ + ImplSVEvent* pSVEvent = new ImplSVEvent; + pSVEvent->mnEvent = nEvent; + pSVEvent->mpData = pEventData; + pSVEvent->mpLink = NULL; + pSVEvent->mpWindow = NULL; + pSVEvent->mbCall = TRUE; + rEventId = (ULONG)pSVEvent; + Window* pDefWindow = ImplGetDefaultWindow(); + if ( pDefWindow && pDefWindow->ImplGetFrame()->PostEvent( pSVEvent ) ) + return TRUE; + else + { + rEventId = 0; + delete pSVEvent; + return FALSE; + } +} + +// ----------------------------------------------------------------------- + +BOOL Application::PostUserEvent( ULONG& rEventId, const Link& rLink, void* pCaller ) +{ + ImplSVEvent* pSVEvent = new ImplSVEvent; + pSVEvent->mnEvent = 0; + pSVEvent->mpData = pCaller; + pSVEvent->mpLink = new Link( rLink ); + pSVEvent->mpWindow = NULL; + pSVEvent->mbCall = TRUE; + rEventId = (ULONG)pSVEvent; + Window* pDefWindow = ImplGetDefaultWindow(); + if ( pDefWindow && pDefWindow->ImplGetFrame()->PostEvent( pSVEvent ) ) + return TRUE; + else + { + rEventId = 0; + delete pSVEvent; + return FALSE; + } +} + +// ----------------------------------------------------------------------- + +void Application::RemoveUserEvent( ULONG nUserEvent ) +{ + if(nUserEvent) + { + ImplSVEvent* pSVEvent = (ImplSVEvent*)nUserEvent; + + DBG_ASSERT( !pSVEvent->mpWindow, + "Application::RemoveUserEvent(): Event is send to a window" ); + DBG_ASSERT( pSVEvent->mbCall, + "Application::RemoveUserEvent(): Event is already removed" ); + + if ( pSVEvent->mpWindow ) + { + if( ! pSVEvent->maDelData.IsDelete() ) + pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) ); + pSVEvent->mpWindow = NULL; + } + + pSVEvent->mbCall = FALSE; + } +} + +// ----------------------------------------------------------------------- + +BOOL Application::InsertIdleHdl( const Link& rLink, USHORT nPrio ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + // Falls er noch nicht existiert, dann anlegen + if ( !pSVData->maAppData.mpIdleMgr ) + pSVData->maAppData.mpIdleMgr = new ImplIdleMgr; + + return pSVData->maAppData.mpIdleMgr->InsertIdleHdl( rLink, nPrio ); +} + +// ----------------------------------------------------------------------- + +void Application::RemoveIdleHdl( const Link& rLink ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maAppData.mpIdleMgr ) + pSVData->maAppData.mpIdleMgr->RemoveIdleHdl( rLink ); +} + +// ----------------------------------------------------------------------- + +void Application::EnableNoYieldMode( bool i_bNoYield ) +{ + ImplSVData* pSVData = ImplGetSVData(); + pSVData->maAppData.mbNoYield = i_bNoYield; +} + +// ----------------------------------------------------------------------- + +void Application::AddPostYieldListener( const Link& i_rListener ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->maAppData.mpPostYieldListeners ) + pSVData->maAppData.mpPostYieldListeners = new VclEventListeners2(); + pSVData->maAppData.mpPostYieldListeners->addListener( i_rListener ); +} + +// ----------------------------------------------------------------------- + +void Application::RemovePostYieldListener( const Link& i_rListener ) +{ + ImplSVData* pSVData = ImplGetSVData(); + if( pSVData->maAppData.mpPostYieldListeners ) + pSVData->maAppData.mpPostYieldListeners->removeListener( i_rListener ); +} + +// ----------------------------------------------------------------------- + +WorkWindow* Application::GetAppWindow() +{ + return ImplGetSVData()->maWinData.mpAppWin; +} + +// ----------------------------------------------------------------------- + +Window* Application::GetFocusWindow() +{ + return ImplGetSVData()->maWinData.mpFocusWin; +} + +// ----------------------------------------------------------------------- + +OutputDevice* Application::GetDefaultDevice() +{ + return ImplGetDefaultWindow(); +} + +// ----------------------------------------------------------------------- + +Window* Application::GetFirstTopLevelWindow() +{ + ImplSVData* pSVData = ImplGetSVData(); + return pSVData->maWinData.mpFirstFrame; +} + +// ----------------------------------------------------------------------- + +Window* Application::GetNextTopLevelWindow( Window* pWindow ) +{ + return pWindow->mpWindowImpl->mpFrameData->mpNextFrame; +} + +// ----------------------------------------------------------------------- + +long Application::GetTopWindowCount() +{ + long nRet = 0; + ImplSVData* pSVData = ImplGetSVData(); + Window *pWin = pSVData ? pSVData->maWinData.mpFirstFrame : NULL; + while( pWin ) + { + if( pWin->ImplGetWindow()->IsTopWindow() ) + nRet++; + pWin = pWin->mpWindowImpl->mpFrameData->mpNextFrame; + } + return nRet; +} + +// ----------------------------------------------------------------------- + +Window* Application::GetTopWindow( long nIndex ) +{ + long nIdx = 0; + ImplSVData* pSVData = ImplGetSVData(); + Window *pWin = pSVData ? pSVData->maWinData.mpFirstFrame : NULL; + while( pWin ) + { + if( pWin->ImplGetWindow()->IsTopWindow() ) + { + if( nIdx == nIndex ) + return pWin->ImplGetWindow(); + else + nIdx++; + } + pWin = pWin->mpWindowImpl->mpFrameData->mpNextFrame; + } + return NULL; +} + +// ----------------------------------------------------------------------- + +Window* Application::GetActiveTopWindow() +{ + Window *pWin = ImplGetSVData()->maWinData.mpFocusWin; + while( pWin ) + { + if( pWin->IsTopWindow() ) + return pWin; + pWin = pWin->mpWindowImpl->mpParent; + } + return NULL; +} + +// ----------------------------------------------------------------------- + +void Application::SetAppName( const XubString& rUniqueName ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + // Falls er noch nicht existiert, dann anlegen + if ( !pSVData->maAppData.mpAppName ) + pSVData->maAppData.mpAppName = new XubString( rUniqueName ); + else + *(pSVData->maAppData.mpAppName) = rUniqueName; +} + +// ----------------------------------------------------------------------- + +XubString Application::GetAppName() +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( pSVData->maAppData.mpAppName ) + return *(pSVData->maAppData.mpAppName); + else + return ImplGetSVEmptyStr(); +} + +// ----------------------------------------------------------------------- + +void Application::SetDisplayName( const UniString& rName ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + // Falls er noch nicht existiert, dann anlegen + if ( !pSVData->maAppData.mpDisplayName ) + pSVData->maAppData.mpDisplayName = new UniString( rName ); + else + *(pSVData->maAppData.mpDisplayName) = rName; +} + +// ----------------------------------------------------------------------- + +UniString Application::GetDisplayName() +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( pSVData->maAppData.mpDisplayName ) + return *(pSVData->maAppData.mpDisplayName); + else if ( pSVData->maWinData.mpAppWin ) + return pSVData->maWinData.mpAppWin->GetText(); + else + return ImplGetSVEmptyStr(); +} + +// ----------------------------------------------------------------------- + +unsigned int Application::GetScreenCount() +{ + SalSystem* pSys = ImplGetSalSystem(); + return pSys ? pSys->GetDisplayScreenCount() : 0; +} + +rtl::OUString Application::GetScreenName( unsigned int nScreen ) +{ + SalSystem* pSys = ImplGetSalSystem(); + return pSys ? pSys->GetScreenName( nScreen ) : rtl::OUString(); +} + +bool Application::IsMultiDisplay() +{ + SalSystem* pSys = ImplGetSalSystem(); + return pSys ? pSys->IsMultiDisplay() : false; +} + +unsigned int Application::GetDefaultDisplayNumber() +{ + SalSystem* pSys = ImplGetSalSystem(); + return pSys ? pSys->GetDefaultDisplayNumber() : 0; +} + +Rectangle Application::GetScreenPosSizePixel( unsigned int nScreen ) +{ + SalSystem* pSys = ImplGetSalSystem(); + return pSys ? pSys->GetDisplayScreenPosSizePixel( nScreen ) : Rectangle(); +} + +Rectangle Application::GetWorkAreaPosSizePixel( unsigned int nScreen ) +{ + SalSystem* pSys = ImplGetSalSystem(); + return pSys ? pSys->GetDisplayWorkAreaPosSizePixel( nScreen ) : Rectangle(); +} + +namespace { +unsigned long calcDistSquare( const Point& i_rPoint, const Rectangle& i_rRect ) +{ + const Point aRectCenter( (i_rRect.Left() + i_rRect.Right())/2, + (i_rRect.Top() + i_rRect.Bottom())/ 2 ); + const long nDX = aRectCenter.X() - i_rPoint.X(); + const long nDY = aRectCenter.Y() - i_rPoint.Y(); + return nDX*nDX + nDY*nDY; +} +} + +unsigned int Application::GetBestScreen( const Rectangle& i_rRect ) +{ + if( IsMultiDisplay() ) + return GetDefaultDisplayNumber(); + + const unsigned int nScreens = GetScreenCount(); + unsigned int nBestMatchScreen = 0; + unsigned long nOverlap = 0; + for( unsigned int i = 0; i < nScreens; i++ ) + { + const Rectangle aCurScreenRect( GetScreenPosSizePixel( i ) ); + // if a screen contains the rectangle completely it is obviously the best screen + if( aCurScreenRect.IsInside( i_rRect ) ) + return i; + // next the screen which contains most of the area of the rect is the best + Rectangle aIntersection( aCurScreenRect.GetIntersection( i_rRect ) ); + if( ! aIntersection.IsEmpty() ) + { + const unsigned long nCurOverlap( aIntersection.GetWidth() * aIntersection.GetHeight() ); + if( nCurOverlap > nOverlap ) + { + nOverlap = nCurOverlap; + nBestMatchScreen = i; + } + } + } + if( nOverlap > 0 ) + return nBestMatchScreen; + + // finally the screen which center is nearest to the rect is the best + const Point aCenter( (i_rRect.Left() + i_rRect.Right())/2, + (i_rRect.Top() + i_rRect.Bottom())/2 ); + unsigned long nDist = ULONG_MAX; + for( unsigned int i = 0; i < nScreens; i++ ) + { + const Rectangle aCurScreenRect( GetScreenPosSizePixel( i ) ); + const unsigned long nCurDist( calcDistSquare( aCenter, aCurScreenRect ) ); + if( nCurDist < nDist ) + { + nBestMatchScreen = i; + nDist = nCurDist; + } + } + return nBestMatchScreen; +} + +// ----------------------------------------------------------------------- + +BOOL Application::InsertAccel( Accelerator* pAccel ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( !pSVData->maAppData.mpAccelMgr ) + pSVData->maAppData.mpAccelMgr = new ImplAccelManager(); + return pSVData->maAppData.mpAccelMgr->InsertAccel( pAccel ); +} + +// ----------------------------------------------------------------------- + +void Application::RemoveAccel( Accelerator* pAccel ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maAppData.mpAccelMgr ) + pSVData->maAppData.mpAccelMgr->RemoveAccel( pAccel ); +} + +// ----------------------------------------------------------------------- + +void Application::FlushAccel() +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maAppData.mpAccelMgr ) + pSVData->maAppData.mpAccelMgr->FlushAccel(); +} + +// ----------------------------------------------------------------------- + +BOOL Application::CallAccel( const KeyCode& rKeyCode, USHORT nRepeat ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( pSVData->maAppData.mpAccelMgr ) + { + if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( rKeyCode, nRepeat ) ) + return TRUE; + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +void Application::SetHelp( Help* pHelp ) +{ + ImplGetSVData()->maAppData.mpHelp = pHelp; +} + +// ----------------------------------------------------------------------- + +Help* Application::GetHelp() +{ + return ImplGetSVData()->maAppData.mpHelp; +} + +// ----------------------------------------------------------------------- + +void Application::EnableAutoHelpId( BOOL bEnabled ) +{ + ImplGetSVData()->maHelpData.mbAutoHelpId = bEnabled; +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsAutoHelpIdEnabled() +{ + return ImplGetSVData()->maHelpData.mbAutoHelpId; +} + +// ----------------------------------------------------------------------- + +void Application::EnableAutoMnemonic( BOOL bEnabled ) +{ + AllSettings aSettings = GetSettings(); + StyleSettings aStyle = aSettings.GetStyleSettings(); + aStyle.SetAutoMnemonic( bEnabled ); + aSettings.SetStyleSettings( aStyle ); + SetSettings( aSettings ); +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsAutoMnemonicEnabled() +{ + return GetSettings().GetStyleSettings().GetAutoMnemonic(); +} + +// ----------------------------------------------------------------------- + +void Application::SetDialogScaleX( short nScale ) +{ + ImplSVData* pSVData = ImplGetSVData(); + pSVData->maAppData.mnDialogScaleX = nScale; + pSVData->maGDIData.mnAppFontX = pSVData->maGDIData.mnRealAppFontX; + if ( nScale ) + pSVData->maGDIData.mnAppFontX += (pSVData->maGDIData.mnAppFontX*nScale)/100; +} + +// ----------------------------------------------------------------------- + +short Application::GetDialogScaleX() +{ + return ImplGetSVData()->maAppData.mnDialogScaleX; +} + +// ----------------------------------------------------------------------- + +void Application::SetDefDialogParent( Window* pWindow ) +{ + ImplGetSVData()->maWinData.mpDefDialogParent = pWindow; +} + +// ----------------------------------------------------------------------- + +Window* Application::GetDefDialogParent() +{ + ImplSVData* pSVData = ImplGetSVData(); + // #103442# find some useful dialog parent if there + // was no default set + // NOTE: currently even the default is not used + if( FALSE && pSVData->maWinData.mpDefDialogParent != NULL ) + return pSVData->maWinData.mpDefDialogParent; + else + { + // always use the topmost parent of the candidate + // window to avoid using dialogs or floaters + // as DefDialogParent + + // current focus frame + Window *pWin = NULL; + if( (pWin = pSVData->maWinData.mpFocusWin) != NULL ) + { + while( pWin->mpWindowImpl && pWin->mpWindowImpl->mpParent ) + pWin = pWin->mpWindowImpl->mpParent; + + if( (pWin->mpWindowImpl->mnStyle & WB_INTROWIN) == 0 ) + { + // check for corrupted window hierarchy, #122232#, may be we now crash somewhere else + if( !pWin->mpWindowImpl ) + { + DBG_ERROR( "Window hierarchy corrupted!" ); + pSVData->maWinData.mpFocusWin = NULL; // avoid further access + return NULL; + } + + // MAV: before the implementation has used only decorated windows, + // but it is not true in case of ActiveX or plugin scenario, + // so this check is commented out + // if( pWin->mpWindowImpl->mpFrameWindow->GetStyle() & (WB_MOVEABLE | WB_SIZEABLE) ) + return pWin->mpWindowImpl->mpFrameWindow->ImplGetWindow(); + // else + // return NULL; + } + } + // last active application frame + if( NULL != (pWin = pSVData->maWinData.mpActiveApplicationFrame) ) + { + return pWin->mpWindowImpl->mpFrameWindow->ImplGetWindow(); + } + else + { + // first visible top window (may be totally wrong....) + pWin = pSVData->maWinData.mpFirstFrame; + while( pWin ) + { + if( pWin->ImplGetWindow()->IsTopWindow() && + pWin->mpWindowImpl->mbReallyVisible && + (pWin->mpWindowImpl->mnStyle & WB_INTROWIN) == 0 + ) + { + while( pWin->mpWindowImpl->mpParent ) + pWin = pWin->mpWindowImpl->mpParent; + return pWin->mpWindowImpl->mpFrameWindow->ImplGetWindow(); + } + pWin = pWin->mpWindowImpl->mpFrameData->mpNextFrame; + } + // use the desktop + return NULL; + } + } +} + +// ----------------------------------------------------------------------- + +void Application::EnableDialogCancel( BOOL bDialogCancel ) +{ + ImplGetSVData()->maAppData.mbDialogCancel = bDialogCancel; +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsDialogCancelEnabled() +{ + return ImplGetSVData()->maAppData.mbDialogCancel; +} + +// ----------------------------------------------------------------------- + +void Application::SetSystemWindowMode( USHORT nMode ) +{ + ImplGetSVData()->maAppData.mnSysWinMode = nMode; +} + +// ----------------------------------------------------------------------- + +USHORT Application::GetSystemWindowMode() +{ + return ImplGetSVData()->maAppData.mnSysWinMode; +} + +// ----------------------------------------------------------------------- + +const String& Application::GetFontPath() +{ + ImplSVData* pSVData = ImplGetSVData(); + if( !pSVData->maAppData.mpFontPath ) + { + if( const char* pFontPath = ::getenv( "SAL_FONTPATH_PRIVATE" ) ) + pSVData->maAppData.mpFontPath = new String( String::CreateFromAscii( pFontPath ) ); + } + + if( pSVData->maAppData.mpFontPath ) + return *(pSVData->maAppData.mpFontPath); + return ImplGetSVEmptyStr(); +} + +// ----------------------------------------------------------------------- + +void Application::SetFontPath( const String& rPath ) +{ + ImplSVData* pSVData = ImplGetSVData(); + + // if it doesn't exist create a new one + if( !pSVData->maAppData.mpFontPath ) + pSVData->maAppData.mpFontPath = new String( rPath ); + else + *(pSVData->maAppData.mpFontPath) = rPath; +} + +// ----------------------------------------------------------------------- + +UniqueItemId Application::CreateUniqueId() +{ + ImplSVData* pSVData = ImplGetSVData(); + + if ( !pSVData->maAppData.mpUniqueIdCont ) + pSVData->maAppData.mpUniqueIdCont = new UniqueIdContainer( UNIQUEID_SV_BEGIN ); + return pSVData->maAppData.mpUniqueIdCont->CreateId(); +} + +// ----------------------------------------------------------------------- + +::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > Application::GetVCLToolkit() +{ + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > xT; + UnoWrapperBase* pWrapper = Application::GetUnoWrapper( TRUE ); + if ( pWrapper ) + xT = pWrapper->GetVCLToolkit(); + return xT; +} + +// ----------------------------------------------------------------------- + +extern "C" { static void SAL_CALL thisModule() {} } + +UnoWrapperBase* Application::GetUnoWrapper( BOOL bCreateIfNotExist ) +{ + ImplSVData* pSVData = ImplGetSVData(); + static BOOL bAlreadyTriedToCreate = FALSE; + if ( !pSVData->mpUnoWrapper && bCreateIfNotExist && !bAlreadyTriedToCreate ) + { + ::rtl::OUString aLibName = ::vcl::unohelper::CreateLibraryName( "tk", TRUE ); + oslModule hTkLib = osl_loadModuleRelative( + &thisModule, aLibName.pData, SAL_LOADMODULE_DEFAULT ); + if ( hTkLib ) + { + ::rtl::OUString aFunctionName( RTL_CONSTASCII_USTRINGPARAM( "CreateUnoWrapper" ) ); + FN_TkCreateUnoWrapper fnCreateWrapper = (FN_TkCreateUnoWrapper)osl_getFunctionSymbol( hTkLib, aFunctionName.pData ); + if ( fnCreateWrapper ) + { + pSVData->mpUnoWrapper = fnCreateWrapper(); + } + } + DBG_ASSERT( pSVData->mpUnoWrapper, "UnoWrapper could not be created!" ); + bAlreadyTriedToCreate = TRUE; + } + return pSVData->mpUnoWrapper; +} + +// ----------------------------------------------------------------------- + +void Application::SetUnoWrapper( UnoWrapperBase* pWrapper ) +{ + ImplSVData* pSVData = ImplGetSVData(); + DBG_ASSERT( !pSVData->mpUnoWrapper, "SetUnoWrapper: Wrapper allready exists" ); + pSVData->mpUnoWrapper = pWrapper; +} + +// ----------------------------------------------------------------------- + +::com::sun::star::uno::Reference< ::com::sun::star::awt::XDisplayConnection > Application::GetDisplayConnection() +{ + ImplSVData* pSVData = ImplGetSVData(); + + if( !pSVData->mxDisplayConnection.is() ) + pSVData->mxDisplayConnection.set( new ::vcl::DisplayConnection ); + + return pSVData->mxDisplayConnection; +} + +// ----------------------------------------------------------------------- + +void Application::SetFilterHdl( const Link& rLink ) +{ + ImplGetSVData()->maGDIData.mpGrfConverter->SetFilterHdl( rLink ); +} + +// ----------------------------------------------------------------------- + +const Link& Application::GetFilterHdl() +{ + return ImplGetSVData()->maGDIData.mpGrfConverter->GetFilterHdl(); +} + +// ----------------------------------------------------------------------- + +BOOL ImplCallHotKey( const KeyCode& rKeyCode ) +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplHotKey* pHotKeyData = pSVData->maAppData.mpFirstHotKey; + while ( pHotKeyData ) + { + if ( pHotKeyData->maKeyCode.IsDefinedKeyCodeEqual( rKeyCode ) ) + { + pHotKeyData->maLink.Call( pHotKeyData->mpUserData ); + return TRUE; + } + + pHotKeyData = pHotKeyData->mpNext; + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +void ImplFreeHotKeyData() +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplHotKey* pTempHotKeyData; + ImplHotKey* pHotKeyData = pSVData->maAppData.mpFirstHotKey; + while ( pHotKeyData ) + { + pTempHotKeyData = pHotKeyData->mpNext; + delete pHotKeyData; + pHotKeyData = pTempHotKeyData; + } + + pSVData->maAppData.mpFirstHotKey = NULL; +} + +// ----------------------------------------------------------------------- + +ULONG Application::AddHotKey( const KeyCode& rKeyCode, const Link& rLink, void* pData ) +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplHotKey* pHotKeyData = new ImplHotKey; + pHotKeyData->mpUserData = pData; + pHotKeyData->maKeyCode = rKeyCode; + pHotKeyData->maLink = rLink; + pHotKeyData->mpNext = pSVData->maAppData.mpFirstHotKey; + pSVData->maAppData.mpFirstHotKey = pHotKeyData; + return (ULONG)pHotKeyData; +} + +// ----------------------------------------------------------------------- + +void Application::RemoveHotKey( ULONG nId ) +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplHotKey* pFindHotKeyData = (ImplHotKey*)nId; + ImplHotKey* pPrevHotKeyData = NULL; + ImplHotKey* pHotKeyData = pSVData->maAppData.mpFirstHotKey; + while ( pHotKeyData ) + { + if ( pHotKeyData == pFindHotKeyData ) + { + if ( pPrevHotKeyData ) + pPrevHotKeyData->mpNext = pFindHotKeyData->mpNext; + else + pSVData->maAppData.mpFirstHotKey = pFindHotKeyData->mpNext; + delete pFindHotKeyData; + break; + } + + pPrevHotKeyData = pHotKeyData; + pHotKeyData = pHotKeyData->mpNext; + } + + DBG_ASSERT( pHotKeyData, "Application::RemoveHotKey() - HotKey is not added" ); +} + +// ----------------------------------------------------------------------- + +void ImplFreeEventHookData() +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplEventHook* pTempEventHookData; + ImplEventHook* pEventHookData = pSVData->maAppData.mpFirstEventHook; + while ( pEventHookData ) + { + pTempEventHookData = pEventHookData->mpNext; + delete pEventHookData; + pEventHookData = pTempEventHookData; + } + + pSVData->maAppData.mpFirstEventHook = NULL; +} + +// ----------------------------------------------------------------------- + +ULONG Application::AddEventHook( VCLEventHookProc pProc, void* pData ) +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplEventHook* pEventHookData = new ImplEventHook; + pEventHookData->mpUserData = pData; + pEventHookData->mpProc = pProc; + pEventHookData->mpNext = pSVData->maAppData.mpFirstEventHook; + pSVData->maAppData.mpFirstEventHook = pEventHookData; + return (ULONG)pEventHookData; +} + +// ----------------------------------------------------------------------- + +void Application::RemoveEventHook( ULONG nId ) +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplEventHook* pFindEventHookData = (ImplEventHook*)nId; + ImplEventHook* pPrevEventHookData = NULL; + ImplEventHook* pEventHookData = pSVData->maAppData.mpFirstEventHook; + while ( pEventHookData ) + { + if ( pEventHookData == pFindEventHookData ) + { + if ( pPrevEventHookData ) + pPrevEventHookData->mpNext = pFindEventHookData->mpNext; + else + pSVData->maAppData.mpFirstEventHook = pFindEventHookData->mpNext; + delete pFindEventHookData; + break; + } + + pPrevEventHookData = pEventHookData; + pEventHookData = pEventHookData->mpNext; + } + + DBG_ASSERT( pEventHookData, "Application::RemoveEventHook() - EventHook is not added" ); +} + +// ----------------------------------------------------------------------- + +long Application::CallEventHooks( NotifyEvent& rEvt ) +{ + ImplSVData* pSVData = ImplGetSVData(); + long nRet = 0; + ImplEventHook* pTempEventHookData; + ImplEventHook* pEventHookData = pSVData->maAppData.mpFirstEventHook; + while ( pEventHookData ) + { + pTempEventHookData = pEventHookData->mpNext; + nRet = pEventHookData->mpProc( rEvt, pEventHookData->mpUserData ); + if ( nRet ) + break; + pEventHookData = pTempEventHookData; + } + + return nRet; +} + +// ----------------------------------------------------------------------- + +long Application::CallPreNotify( NotifyEvent& rEvt ) +{ + return ImplCallPreNotify( rEvt ); +} + +// ----------------------------------------------------------------------- + +long Application::CallEvent( NotifyEvent& rEvt ) +{ + return ImplCallEvent( rEvt ); +} + +// ----------------------------------------------------------------------- + +const LocaleDataWrapper& Application::GetAppLocaleDataWrapper() +{ + return GetSettings().GetLocaleDataWrapper(); +} + +// ----------------------------------------------------------------------- + +void Application::EnableHeadlessMode( BOOL bEnable ) +{ + EnableDialogCancel( bEnable ); +} + +// ----------------------------------------------------------------------- + +BOOL Application::IsHeadlessModeEnabled() +{ + return IsDialogCancelEnabled(); +} + +// ----------------------------------------------------------------------- + +void Application::ShowNativeErrorBox(const String& sTitle , + const String& sMessage) +{ + int btn = ImplGetSalSystem()->ShowNativeMessageBox ( + sTitle, + sMessage, + SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK, + SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK); + if (btn != SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK) { + OSL_TRACE("ShowNativeMessageBox returned %d\n", btn); + } +} + +// ----------------------------------------------------------------------- + +bool Application::CanToggleImeStatusWindow() +{ + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->mpImeStatus ) + pSVData->mpImeStatus = pSVData->mpDefInst->CreateI18NImeStatus(); + return pSVData->mpImeStatus->canToggle(); +} + +void Application::ShowImeStatusWindow(bool bShow) +{ + ImplGetSVData()->maAppData.meShowImeStatusWindow = bShow + ? ImplSVAppData::ImeStatusWindowMode_SHOW + : ImplSVAppData::ImeStatusWindowMode_HIDE; + + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->mpImeStatus ) + pSVData->mpImeStatus = pSVData->mpDefInst->CreateI18NImeStatus(); + pSVData->mpImeStatus->toggle(); +} + +bool Application::GetShowImeStatusWindowDefault() +{ + rtl_TextEncodingInfo aInfo; + aInfo.StructSize = sizeof aInfo; + return rtl_getTextEncodingInfo(osl_getThreadTextEncoding(), &aInfo) + && aInfo.MaximumCharSize > 1; +} + +const ::rtl::OUString& Application::GetDesktopEnvironment() +{ + return SalGetDesktopEnvironment(); +} + +void Application::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType) +{ + ImplSVData* pSVData = ImplGetSVData(); + pSVData->mpDefInst->AddToRecentDocumentList(rFileUrl, rMimeType); +} + +BOOL Application::IsAccessibilityEnabled() +{ + return FALSE; +} + +BOOL InitAccessBridge( BOOL bShowCancel, BOOL &rCancelled ) +{ + BOOL bRet = true; + +// Disable Java bridge on UNIX +#if defined UNX + (void) bShowCancel; // unsued + (void) rCancelled; // unused +#else + bRet = ImplInitAccessBridge( bShowCancel, rCancelled ); + + if( !bRet && bShowCancel && !rCancelled ) + { + // disable accessibility if the user chooses to continue + AllSettings aSettings = Application::GetSettings(); + MiscSettings aMisc = aSettings.GetMiscSettings(); + aMisc.SetEnableATToolSupport( FALSE ); + aSettings.SetMiscSettings( aMisc ); + Application::SetSettings( aSettings ); + } +#endif // !UNX + + return bRet; +} + +// MT: AppProperty, AppEvent was in oldsv.cxx, but is still needed... +// ------------------------------------------------------------------------ + +TYPEINIT0(ApplicationProperty) + +// ------------------------------------------------------------------------ + +static PropertyHandler* pHandler=NULL; + +void Application::Property( ApplicationProperty& rProp ) +{ + if ( pHandler ) + pHandler->Property( rProp ); +} + +void Application::SetPropertyHandler( PropertyHandler* p ) +{ + if ( pHandler ) + delete pHandler; + pHandler = p; +} + + + +void Application::AppEvent( const ApplicationEvent& /*rAppEvent*/ ) +{ +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx new file mode 100644 index 000000000000..269ca4700cab --- /dev/null +++ b/vcl/source/app/svdata.cxx @@ -0,0 +1,534 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" +#include <string.h> + +#include <svsys.h> +#include <vcl/salinst.hxx> +#include <vcl/salframe.hxx> + +#include <osl/mutex.hxx> + +#include <osl/process.h> +#include <osl/file.hxx> +#include <uno/current_context.hxx> +#include <cppuhelper/implbase1.hxx> +#include <tools/debug.hxx> +#include <unotools/fontcfg.hxx> +#include <vcl/configsettings.hxx> +#include <vcl/svdata.hxx> +#include <vcl/window.h> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/unohelp.hxx> +#include <vcl/button.hxx> // for Button::GetStandardText +#include <vcl/dockwin.hxx> // for DockingManager +#include <vcl/salimestatus.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/awt/XExtendedToolkit.hpp> +#include <com/sun/star/java/JavaNotConfiguredException.hpp> +#include <com/sun/star/java/JavaVMCreationFailureException.hpp> +#include <com/sun/star/java/MissingJavaRuntimeException.hpp> +#include <com/sun/star/java/JavaDisabledException.hpp> + +#include <com/sun/star/lang/XComponent.hpp> + +#include <stdio.h> +#include <vcl/salsys.hxx> +#include <vcl/svids.hrc> +#include <rtl/instance.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::awt; +using namespace rtl; + +// ======================================================================= + +namespace +{ + struct private_aImplSVData : + public rtl::Static<ImplSVData, private_aImplSVData> {}; +} + +// static SV-Data +ImplSVData* pImplSVData = NULL; + +SalSystem* ImplGetSalSystem() +{ + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->mpSalSystem ) + pSVData->mpSalSystem = pSVData->mpDefInst->CreateSalSystem(); + return pSVData->mpSalSystem; +} + + +static String& ReplaceJavaErrorMessages( String& rString ) +{ + rString.SearchAndReplaceAllAscii( "%OK", Button::GetStandardText( BUTTON_OK ) ); + rString.SearchAndReplaceAllAscii( "%IGNORE", Button::GetStandardText( BUTTON_IGNORE ) ); + rString.SearchAndReplaceAllAscii( "%CANCEL", Button::GetStandardText( BUTTON_CANCEL ) ); + + return rString; +} + +// ======================================================================= + +void ImplInitSVData() +{ + pImplSVData = &private_aImplSVData::get(); + + // init global instance data + memset( pImplSVData, 0, sizeof( ImplSVData ) ); + pImplSVData->maHelpData.mbAutoHelpId = sal_True; + pImplSVData->maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT ); + + // find out whether we are running in the testtool + // in this case we need some special workarounds + sal_uInt32 nArgs = osl_getCommandArgCount(); + for( sal_uInt32 i = 0; i < nArgs; i++ ) + { + rtl::OUString aArg; + osl_getCommandArg( i, &aArg.pData ); + if( aArg.equalsAscii( "-enableautomation" ) ) + { + pImplSVData->mbIsTestTool = true; + break; + } + } +} + +// ----------------------------------------------------------------------- + +void ImplDeInitSVData() +{ + ImplSVData* pSVData = ImplGetSVData(); + + // delete global instance data + if( pSVData->mpSettingsConfigItem ) + delete pSVData->mpSettingsConfigItem; + + if( pSVData->mpDockingManager ) + delete pSVData->mpDockingManager; + + if( pSVData->maGDIData.mpDefaultFontConfiguration ) + delete pSVData->maGDIData.mpDefaultFontConfiguration; + if( pSVData->maGDIData.mpFontSubstConfiguration ) + delete pSVData->maGDIData.mpFontSubstConfiguration; + + if ( pSVData->maAppData.mpMSFTempFileName ) + { + if ( pSVData->maAppData.mxMSF.is() ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pSVData->maAppData.mxMSF, ::com::sun::star::uno::UNO_QUERY ); + xComp->dispose(); + pSVData->maAppData.mxMSF = NULL; + } + + ::rtl::OUString aFileUrl; + ::osl::File::getFileURLFromSystemPath( *pSVData->maAppData.mpMSFTempFileName, aFileUrl ); + osl::File::remove( aFileUrl ); + delete pSVData->maAppData.mpMSFTempFileName; + pSVData->maAppData.mpMSFTempFileName = NULL; + } +} + +// ----------------------------------------------------------------------- + +void ImplDestroySVData() +{ + pImplSVData = NULL; +} + +// ----------------------------------------------------------------------- + +Window* ImplGetDefaultWindow() +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( pSVData->maWinData.mpAppWin ) + return pSVData->maWinData.mpAppWin; + + // First test if we already have a default window. + // Don't only place a single if..else inside solar mutex lockframe + // because then we might have to wait for the solar mutex what is not neccessary + // if we already have a default window. + + if ( !pSVData->mpDefaultWin ) + { + Application::GetSolarMutex().acquire(); + + // Test again because the thread who released the solar mutex could have called + // the same method + + if ( !pSVData->mpDefaultWin && !pSVData->mbDeInit ) + { + DBG_WARNING( "ImplGetDefaultWindow(): No AppWindow" ); + pSVData->mpDefaultWin = new WorkWindow( 0, WB_DEFAULTWIN ); + pSVData->mpDefaultWin->SetText( OUString( RTL_CONSTASCII_USTRINGPARAM( "VCL ImplGetDefaultWindow" ) ) ); + } + Application::GetSolarMutex().release(); + } + + return pSVData->mpDefaultWin; +} + +// ----------------------------------------------------------------------- + +#define VCL_CREATERESMGR_NAME( Name ) #Name + +ResMgr* ImplGetResMgr() +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( !pSVData->mpResMgr ) + { + ::com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale(); + pSVData->mpResMgr = ResMgr::SearchCreateResMgr( VCL_CREATERESMGR_NAME( vcl ), aLocale ); + + static bool bMessageOnce = false; + if( !pSVData->mpResMgr && ! bMessageOnce ) + { + bMessageOnce = true; + const char* pMsg = + "Missing vcl resource. This indicates that files vital to localization are missing. " + "You might have a corrupt installation."; + fprintf( stderr, "%s\n", pMsg ); + ErrorBox aBox( NULL, WB_OK | WB_DEF_OK, rtl::OUString( pMsg, strlen( pMsg ), RTL_TEXTENCODING_ASCII_US ) ); + aBox.Execute(); + } + } + return pSVData->mpResMgr; +} + +ResId VclResId( sal_Int32 nId ) +{ + ResMgr* pMgr = ImplGetResMgr(); + if( ! pMgr ) + throw std::bad_alloc(); + + return ResId( nId, *pMgr ); +} + +DockingManager* ImplGetDockingManager() +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( !pSVData->mpDockingManager ) + pSVData->mpDockingManager = new DockingManager(); + + return pSVData->mpDockingManager; +} + +class AccessBridgeCurrentContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext > +{ +public: + AccessBridgeCurrentContext( + const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > &context ) : + m_prevContext( context ) {} + + // XCurrentContext + virtual com::sun::star::uno::Any SAL_CALL getValueByName( const rtl::OUString& Name ) + throw (com::sun::star::uno::RuntimeException); +private: + com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_prevContext; +}; + +com::sun::star::uno::Any AccessBridgeCurrentContext::getValueByName( const rtl::OUString & Name ) + throw (com::sun::star::uno::RuntimeException) +{ + com::sun::star::uno::Any ret; + if( Name.equalsAscii( "java-vm.interaction-handler" ) ) + { + // Currently, for accessbility no interaction handler shall be offered. + // There may be introduced later on a handler using native toolkits + // jbu->obr: Instantiate here your interaction handler + } + else if( m_prevContext.is() ) + { + ret = m_prevContext->getValueByName( Name ); + } + return ret; +} + + +bool ImplInitAccessBridge(BOOL bAllowCancel, BOOL &rCancelled) +{ + rCancelled = FALSE; + + bool bErrorMessage = true; + + // Note: + // if bAllowCancel is TRUE we were called from application startup + // where we will disable any Java errorboxes and show our own accessibility dialog if Java throws an exception + // if bAllowCancel is FALSE we were called from Tools->Options + // where we will see Java errorboxes, se we do not show our dialogs in addition to Java's + + try + { + bool bSuccess = true; + + // No error messages when env var is set .. + static const char* pEnv = getenv("SAL_ACCESSIBILITY_ENABLED" ); + if( pEnv && *pEnv ) + { + bErrorMessage = false; + } + + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->mxAccessBridge.is() ) + { + Reference< XMultiServiceFactory > xFactory(vcl::unohelper::GetMultiServiceFactory()); + + if( xFactory.is() ) + { + Reference< XExtendedToolkit > xToolkit = + Reference< XExtendedToolkit >(Application::GetVCLToolkit(), UNO_QUERY); + + Sequence< Any > arguments(1); + arguments[0] = makeAny(xToolkit); + + // Disable default java error messages on startup, because they were probably unreadable + // for a disabled user. Use native message boxes which are accessible without java support. + // No need to do this when activated by Tools-Options dialog .. + if( bAllowCancel ) + { + // customize the java-not-available-interaction-handler entry within the + // current context when called at startup. + com::sun::star::uno::ContextLayer layer( + new AccessBridgeCurrentContext( com::sun::star::uno::getCurrentContext() ) ); + + pSVData->mxAccessBridge = xFactory->createInstanceWithArguments( + OUString::createFromAscii( "com.sun.star.accessibility.AccessBridge" ), + arguments + ); + } + else + { + pSVData->mxAccessBridge = xFactory->createInstanceWithArguments( + OUString::createFromAscii( "com.sun.star.accessibility.AccessBridge" ), + arguments + ); + } + + if( !pSVData->mxAccessBridge.is() ) + bSuccess = false; + } + } + + return bSuccess; + } + + catch(::com::sun::star::java::JavaNotConfiguredException e) + { + ResMgr *pResMgr = ImplGetResMgr(); + if( bErrorMessage && bAllowCancel && pResMgr ) + { + String aTitle(ResId(SV_ACCESSERROR_JAVA_NOT_CONFIGURED, *pResMgr)); + String aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr)); + + aMessage += String(" ", 1, RTL_TEXTENCODING_ASCII_US); + aMessage += String(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr)); + + int ret = ImplGetSalSystem()->ShowNativeMessageBox( + aTitle, + ReplaceJavaErrorMessages(aMessage), + SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL, + SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL); + + // Do not change the setting in case the user chooses to cancel + if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret ) + rCancelled = TRUE; + } + + return false; + } + + catch(::com::sun::star::java::JavaVMCreationFailureException e) + { + ResMgr *pResMgr = ImplGetResMgr(); + if( bErrorMessage && bAllowCancel && pResMgr ) + { + String aTitle(ResId(SV_ACCESSERROR_FAULTY_JAVA, *pResMgr)); + String aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr)); + + aMessage += String(" ", 1, RTL_TEXTENCODING_ASCII_US); + aMessage += String(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr)); + + int ret = ImplGetSalSystem()->ShowNativeMessageBox( + aTitle, + ReplaceJavaErrorMessages(aMessage), + SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL, + SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL); + + // Do not change the setting in case the user chooses to cancel + if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret ) + rCancelled = TRUE; + } + + return false; + } + + catch(::com::sun::star::java::MissingJavaRuntimeException e) + { + ResMgr *pResMgr = ImplGetResMgr(); + if( bErrorMessage && bAllowCancel && pResMgr ) + { + String aTitle(ResId(SV_ACCESSERROR_MISSING_JAVA, *pResMgr)); + String aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr)); + + aMessage += String(" ", 1, RTL_TEXTENCODING_ASCII_US); + aMessage += String(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr)); + + int ret = ImplGetSalSystem()->ShowNativeMessageBox( + aTitle, + ReplaceJavaErrorMessages(aMessage), + SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL, + SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL); + + // Do not change the setting in case the user chooses to cancel + if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret ) + rCancelled = TRUE; + } + + return false; + } + + catch(::com::sun::star::java::JavaDisabledException e) + { + ResMgr *pResMgr = ImplGetResMgr(); + if( bErrorMessage && bAllowCancel && pResMgr ) + { + String aTitle(ResId(SV_ACCESSERROR_JAVA_DISABLED, *pResMgr)); + String aMessage(ResId(SV_ACCESSERROR_JAVA_MSG, *pResMgr)); + + aMessage += String(" ", 1, RTL_TEXTENCODING_ASCII_US); + aMessage += String(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr)); + + int ret = ImplGetSalSystem()->ShowNativeMessageBox( + aTitle, + ReplaceJavaErrorMessages(aMessage), + SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL, + SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL); + + // Do not change the setting in case the user chooses to cancel + if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret ) + rCancelled = TRUE; + } + + return false; + } + + + catch(::com::sun::star::uno::RuntimeException e) + { + ResMgr *pResMgr = ImplGetResMgr(); + if( bErrorMessage && pResMgr ) + { + String aTitle; + String aMessage(ResId(SV_ACCESSERROR_BRIDGE_MSG, *pResMgr)); + + if( 0 == e.Message.compareTo(::rtl::OUString::createFromAscii("ClassNotFound"), 13) ) + { + aTitle = String(ResId(SV_ACCESSERROR_MISSING_BRIDGE, *pResMgr)); + } + else if( 0 == e.Message.compareTo(::rtl::OUString::createFromAscii("NoSuchMethod"), 12) ) + { + aTitle = String(ResId(SV_ACCESSERROR_WRONG_VERSION, *pResMgr)); + } + + if( aTitle.Len() != 0 ) + { + if( bAllowCancel ) + { + // Something went wrong initializing the Java AccessBridge (on Windows) during the + // startup. Since the office will be probably unusable for a disabled user, we offer + // to terminate directly. + aMessage += String(" ", 1, RTL_TEXTENCODING_ASCII_US); + aMessage += String(ResId(SV_ACCESSERROR_OK_CANCEL_MSG, *pResMgr)); + + int ret = ImplGetSalSystem()->ShowNativeMessageBox( + aTitle, + ReplaceJavaErrorMessages(aMessage), + SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL, + SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL); + + // Do not change the setting in case the user chooses to cancel + if( SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL == ret ) + rCancelled = TRUE; + } + else + { + // The user tried to activate accessibility support using Tools-Options dialog, + // so we don't offer to terminate here ! + ImplGetSalSystem()->ShowNativeMessageBox( + aTitle, + ReplaceJavaErrorMessages(aMessage), + SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK, + SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK); + } + } + } + + return false; + } + + catch (...) + { + return false; + } +} + +// ----------------------------------------------------------------------- + +Window* ImplFindWindow( const SalFrame* pFrame, Point& rSalFramePos ) +{ + ImplSVData* pSVData = ImplGetSVData(); + Window* pFrameWindow = pSVData->maWinData.mpFirstFrame; + while ( pFrameWindow ) + { + if ( pFrameWindow->ImplGetFrame() == pFrame ) + { + Window* pWindow = pFrameWindow->ImplFindWindow( rSalFramePos ); + if ( !pWindow ) + pWindow = pFrameWindow->ImplGetWindow(); + rSalFramePos = pWindow->ImplFrameToOutput( rSalFramePos ); + return pWindow; + } + pFrameWindow = pFrameWindow->ImplGetFrameData()->mpNextFrame; + } + + return NULL; +} + +void LocaleConfigurationListener::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 nHint ) +{ + AllSettings::LocaleSettingsChanged( nHint ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx new file mode 100644 index 000000000000..4f76193d4b90 --- /dev/null +++ b/vcl/source/app/svmain.cxx @@ -0,0 +1,631 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#ifdef WNT +#include <tools/prewin.h> +#include <process.h> // for _beginthreadex +#include <ole2.h> // for _beginthreadex +#include <tools/postwin.h> +#endif + +// [ed 5/14/02 Add in explicit check for quartz graphics. OS X will define +// unx for both quartz and X11 graphics, but we include svunx.h only if we're +// building X11 graphics layers. + +#if defined UNX && ! defined QUARTZ +#include "svunx.h" +#endif + +#include "svsys.h" +#include "vcl/salinst.hxx" +#include "vcl/salwtype.hxx" +#include "osl/signal.h" +#include "tools/tools.h" +#include "tools/debug.hxx" +#include "tools/unqid.hxx" +#include "vcl/svdata.hxx" +#include "vcl/dbggui.hxx" +#include "vcl/svapp.hxx" +#include "vcl/wrkwin.hxx" +#include "vcl/cvtgrf.hxx" +#include "vcl/image.hxx" +#include "tools/resmgr.hxx" +#include "vcl/accmgr.hxx" +#include "vcl/idlemgr.hxx" +#include "vcl/outdev.h" +#include "vcl/outfont.hxx" +#include "vcl/print.h" +#include "vcl/settings.hxx" +#include "vcl/unowrap.hxx" +#include "vcl/salsys.hxx" +#include "vcl/saltimer.hxx" +#include "vcl/salimestatus.hxx" +#include "vcl/impimagetree.hxx" +#include "vcl/xconnection.hxx" + +#include "osl/file.hxx" +#include "osl/process.h" +#include "comphelper/processfactory.hxx" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/lang/XComponent.hpp" +#include "rtl/logfile.hxx" +#include <unotools/syslocaleoptions.hxx> +#include "unotools/fontcfg.hxx" +#include "vcl/configsettings.hxx" +#include "vcl/lazydelete.hxx" + +#include "cppuhelper/implbase1.hxx" +#include "uno/current_context.hxx" + +#if OSL_DEBUG_LEVEL > 0 +#include <typeinfo> +#include "rtl/strbuf.hxx" +#endif + +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + + + +// ======================================================================= + +oslSignalAction SAL_CALL VCLExceptionSignal_impl( void* /*pData*/, oslSignalInfo* pInfo) +{ + static bool bIn = false; + + // Wenn wir nocheinmal abstuerzen, verabschieden wir uns gleich + if ( !bIn ) + { + sal_uInt16 nVCLException = 0; + + // UAE + if ( (pInfo->Signal == osl_Signal_AccessViolation) || + (pInfo->Signal == osl_Signal_IntegerDivideByZero) || + (pInfo->Signal == osl_Signal_FloatDivideByZero) || + (pInfo->Signal == osl_Signal_DebugBreak) ) + nVCLException = EXC_SYSTEM; + + // RC + if ((pInfo->Signal == osl_Signal_User) && + (pInfo->UserSignal == OSL_SIGNAL_USER_RESOURCEFAILURE) ) + nVCLException = EXC_RSCNOTLOADED; + + // DISPLAY-Unix + if ((pInfo->Signal == osl_Signal_User) && + (pInfo->UserSignal == OSL_SIGNAL_USER_X11SUBSYSTEMERROR) ) + nVCLException = EXC_DISPLAY; + + // Remote-Client + if ((pInfo->Signal == osl_Signal_User) && + (pInfo->UserSignal == OSL_SIGNAL_USER_RVPCONNECTIONERROR) ) + nVCLException = EXC_REMOTE; + + if ( nVCLException ) + { + bIn = true; + + SolarMutexGuard aLock; + + // Timer nicht mehr anhalten, da ansonsten die UAE-Box + // auch nicht mehr gepaintet wird + ImplSVData* pSVData = ImplGetSVData(); + if ( pSVData->mpApp ) + { + sal_uInt16 nOldMode = Application::GetSystemWindowMode(); + Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE ); + pSVData->mpApp->Exception( nVCLException ); + Application::SetSystemWindowMode( nOldMode ); + } + bIn = false; + + return osl_Signal_ActCallNextHdl; + } + } + + return osl_Signal_ActCallNextHdl; + +} + +// ======================================================================= +BOOL ImplSVMain() +{ + // The 'real' SVMain() + RTL_LOGFILE_CONTEXT( aLog, "vcl (ss112471) ::SVMain" ); + + ImplSVData* pSVData = ImplGetSVData(); + + DBG_ASSERT( pSVData->mpApp, "no instance of class Application" ); + + Reference<XMultiServiceFactory> xMS; + + + BOOL bInit = InitVCL( xMS ); + + if( bInit ) + { + // Application-Main rufen + pSVData->maAppData.mbInAppMain = TRUE; + pSVData->mpApp->Main(); + pSVData->maAppData.mbInAppMain = FALSE; + } + + if( pSVData->mxDisplayConnection.is() ) + { + vcl::DisplayConnection* pConnection = + dynamic_cast<vcl::DisplayConnection*>(pSVData->mxDisplayConnection.get()); + + if( pConnection ) + pConnection->dispatchDowningEvent(); + pSVData->mxDisplayConnection.clear(); + } + + // This is a hack to work around the problem of the asynchronous nature + // of bridging accessibility through Java: on shutdown there might still + // be some events in the AWT EventQueue, which need the SolarMutex which + // - on the other hand - is destroyed in DeInitVCL(). So empty the queue + // here .. + Reference< XComponent > xComponent(pSVData->mxAccessBridge, UNO_QUERY); + if( xComponent.is() ) + { + ULONG nCount = Application::ReleaseSolarMutex(); + xComponent->dispose(); + Application::AcquireSolarMutex(nCount); + pSVData->mxAccessBridge.clear(); + } + + DeInitVCL(); + return bInit; +} + +BOOL SVMain() +{ + // #i47888# allow for alternative initialization as required for e.g. MacOSX + extern BOOL ImplSVMainHook( BOOL* ); + + BOOL bInit; + if( ImplSVMainHook( &bInit ) ) + return bInit; + else + return ImplSVMain(); +} +// This variable is set, when no Application object is instantiated +// before SVInit is called +static Application * pOwnSvApp = NULL; +// Exception handler. pExceptionHandler != NULL => VCL already inited +oslSignalHandler pExceptionHandler = NULL; + +class Application_Impl : public Application +{ +public: + void Main(){}; +}; + +class DesktopEnvironmentContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext > +{ +public: + DesktopEnvironmentContext( const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > & ctx) + : m_xNextContext( ctx ) {} + + // XCurrentContext + virtual com::sun::star::uno::Any SAL_CALL getValueByName( const rtl::OUString& Name ) + throw (com::sun::star::uno::RuntimeException); + +private: + com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_xNextContext; +}; + +Any SAL_CALL DesktopEnvironmentContext::getValueByName( const rtl::OUString& Name) throw (RuntimeException) +{ + Any retVal; + + if ( 0 == Name.compareToAscii( "system.desktop-environment" ) ) + { + retVal = makeAny( Application::GetDesktopEnvironment() ); + } + else if( m_xNextContext.is() ) + { + // Call next context in chain if found + retVal = m_xNextContext->getValueByName( Name ); + } + return retVal; +} + +BOOL InitVCL( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr ) +{ + RTL_LOGFILE_CONTEXT( aLog, "vcl (ss112471) ::InitVCL" ); + + if( pExceptionHandler != NULL ) + return FALSE; + + if( ! ImplGetSVData() ) + ImplInitSVData(); + + if( !ImplGetSVData()->mpApp ) + { + pOwnSvApp = new Application_Impl(); + } + InitSalMain(); + + /*AllSettings aAS; + Application::SetSettings( aAS );// ??? + */ + ImplSVData* pSVData = ImplGetSVData(); + + // SV bei den Tools anmelden + InitTools(); + + DBG_ASSERT( !pSVData->maAppData.mxMSF.is(), "VCL service factory already set" ); + pSVData->maAppData.mxMSF = rSMgr; + + // Main-Thread-Id merken + pSVData->mnMainThreadId = ::osl::Thread::getCurrentIdentifier(); + + // Sal initialisieren + RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ ::CreateSalInstance" ); + pSVData->mpDefInst = CreateSalInstance(); + if ( !pSVData->mpDefInst ) + return FALSE; + RTL_LOGFILE_CONTEXT_TRACE( aLog, "} ::CreateSalInstance" ); + + // Desktop Environment context (to be able to get value of "system.desktop-environment" as soon as possible) + com::sun::star::uno::setCurrentContext( + new DesktopEnvironmentContext( com::sun::star::uno::getCurrentContext() ) ); + + // Initialize application instance (should be done after initialization of VCL SAL part) + if( pSVData->mpApp ) + // call init to initialize application class + // soffice/sfx implementation creates the global service manager + pSVData->mpApp->Init(); + + // Den AppFileName gleich holen und absolut machen, bevor das + // WorkingDirectory sich aendert... + rtl::OUString aExeFileName; + osl_getExecutableFile( &aExeFileName.pData ); + + // convert path to native file format + rtl::OUString aNativeFileName; + osl::FileBase::getSystemPathFromFileURL( aExeFileName, aNativeFileName ); + pSVData->maAppData.mpAppFileName = new String( aNativeFileName ); + + // Initialize global data + pSVData->maGDIData.mpScreenFontList = new ImplDevFontList; + pSVData->maGDIData.mpScreenFontCache = new ImplFontCache( FALSE ); + pSVData->maGDIData.mpGrfConverter = new GraphicConverter; + + // Exception-Handler setzen + pExceptionHandler = osl_addSignalHandler(VCLExceptionSignal_impl, NULL); + + // Debug-Daten initialisieren + DBGGUI_INIT(); + + return TRUE; +} + +void DeInitVCL() +{ + ImplSVData* pSVData = ImplGetSVData(); + pSVData->mbDeInit = TRUE; + + vcl::DeleteOnDeinitBase::ImplDeleteOnDeInit(); + + // give ime status a chance to destroy its own windows + delete pSVData->mpImeStatus; + pSVData->mpImeStatus = NULL; + + #if OSL_DEBUG_LEVEL > 0 + rtl::OStringBuffer aBuf( 256 ); + aBuf.append( "DeInitVCL: some top Windows are still alive\n" ); + long nTopWindowCount = Application::GetTopWindowCount(); + long nBadTopWindows = nTopWindowCount; + for( long i = 0; i < nTopWindowCount; i++ ) + { + Window* pWin = Application::GetTopWindow( i ); + // default window will be destroyed further down + // but may still be useful during deinit up to that point + if( pWin == pSVData->mpDefaultWin ) + nBadTopWindows--; + else + { + aBuf.append( "text = \"" ); + aBuf.append( rtl::OUStringToOString( pWin->GetText(), osl_getThreadTextEncoding() ) ); + aBuf.append( "\" type = \"" ); + aBuf.append( typeid(*pWin).name() ); + aBuf.append( "\"\n" ); + } + } + DBG_ASSERT( nBadTopWindows==0, aBuf.getStr() ); + #endif + + ImplImageTreeSingletonRef()->shutDown(); + + osl_removeSignalHandler( pExceptionHandler); + pExceptionHandler = NULL; + + // Debug Daten zuruecksetzen + DBGGUI_DEINIT(); + + // free global data + delete pSVData->maGDIData.mpGrfConverter; + + if( pSVData->mpSettingsConfigItem ) + delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = NULL; + if( pSVData->maGDIData.mpDefaultFontConfiguration ) + delete pSVData->maGDIData.mpDefaultFontConfiguration, pSVData->maGDIData.mpDefaultFontConfiguration = NULL; + if( pSVData->maGDIData.mpFontSubstConfiguration ) + delete pSVData->maGDIData.mpFontSubstConfiguration, pSVData->maGDIData.mpFontSubstConfiguration = NULL; + + if ( pSVData->maAppData.mpIdleMgr ) + delete pSVData->maAppData.mpIdleMgr; + Timer::ImplDeInitTimer(); + + if ( pSVData->maWinData.mpMsgBoxImgList ) + { + delete pSVData->maWinData.mpMsgBoxImgList; + pSVData->maWinData.mpMsgBoxImgList = NULL; + } + if ( pSVData->maWinData.mpMsgBoxHCImgList ) + { + delete pSVData->maWinData.mpMsgBoxHCImgList; + pSVData->maWinData.mpMsgBoxHCImgList = NULL; + } + if ( pSVData->maCtrlData.mpCheckImgList ) + { + delete pSVData->maCtrlData.mpCheckImgList; + pSVData->maCtrlData.mpCheckImgList = NULL; + } + if ( pSVData->maCtrlData.mpRadioImgList ) + { + delete pSVData->maCtrlData.mpRadioImgList; + pSVData->maCtrlData.mpRadioImgList = NULL; + } + if ( pSVData->maCtrlData.mpPinImgList ) + { + delete pSVData->maCtrlData.mpPinImgList; + pSVData->maCtrlData.mpPinImgList = NULL; + } + if ( pSVData->maCtrlData.mpSplitHPinImgList ) + { + delete pSVData->maCtrlData.mpSplitHPinImgList; + pSVData->maCtrlData.mpSplitHPinImgList = NULL; + } + if ( pSVData->maCtrlData.mpSplitVPinImgList ) + { + delete pSVData->maCtrlData.mpSplitVPinImgList; + pSVData->maCtrlData.mpSplitVPinImgList = NULL; + } + if ( pSVData->maCtrlData.mpSplitHArwImgList ) + { + delete pSVData->maCtrlData.mpSplitHArwImgList; + pSVData->maCtrlData.mpSplitHArwImgList = NULL; + } + if ( pSVData->maCtrlData.mpSplitVArwImgList ) + { + delete pSVData->maCtrlData.mpSplitVArwImgList; + pSVData->maCtrlData.mpSplitVArwImgList = NULL; + } + if ( pSVData->maCtrlData.mpDisclosurePlus ) + { + delete pSVData->maCtrlData.mpDisclosurePlus; + pSVData->maCtrlData.mpDisclosurePlus = NULL; + } + if ( pSVData->maCtrlData.mpDisclosurePlusHC ) + { + delete pSVData->maCtrlData.mpDisclosurePlusHC; + pSVData->maCtrlData.mpDisclosurePlusHC = NULL; + } + if ( pSVData->maCtrlData.mpDisclosureMinus ) + { + delete pSVData->maCtrlData.mpDisclosureMinus; + pSVData->maCtrlData.mpDisclosureMinus = NULL; + } + if ( pSVData->maCtrlData.mpDisclosureMinusHC ) + { + delete pSVData->maCtrlData.mpDisclosureMinusHC; + pSVData->maCtrlData.mpDisclosureMinusHC = NULL; + } + if ( pSVData->mpDefaultWin ) + { + delete pSVData->mpDefaultWin; + pSVData->mpDefaultWin = NULL; + } + + // #114285# Moved here from ImplDeInitSVData... + if ( pSVData->mpUnoWrapper ) + { + pSVData->mpUnoWrapper->Destroy(); + pSVData->mpUnoWrapper = NULL; + } + + pSVData->maAppData.mxMSF.clear(); + + if( pSVData->mpApp ) + // call deinit to deinitialize application class + // soffice/sfx implementation disposes the global service manager + // Warning: After this call you can't call uno services + pSVData->mpApp->DeInit(); + + if ( pSVData->maAppData.mpSettings ) + { + if ( pSVData->maAppData.mpCfgListener ) + { + pSVData->maAppData.mpSettings->GetSysLocale().GetOptions().RemoveListener( pSVData->maAppData.mpCfgListener ); + delete pSVData->maAppData.mpCfgListener; + } + + delete pSVData->maAppData.mpSettings; + pSVData->maAppData.mpSettings = NULL; + } + if ( pSVData->maAppData.mpAccelMgr ) + { + delete pSVData->maAppData.mpAccelMgr; + pSVData->maAppData.mpAccelMgr = NULL; + } + if ( pSVData->maAppData.mpUniqueIdCont ) + { + delete pSVData->maAppData.mpUniqueIdCont; + pSVData->maAppData.mpUniqueIdCont = NULL; + } + if ( pSVData->maAppData.mpAppFileName ) + { + delete pSVData->maAppData.mpAppFileName; + pSVData->maAppData.mpAppFileName = NULL; + } + if ( pSVData->maAppData.mpAppName ) + { + delete pSVData->maAppData.mpAppName; + pSVData->maAppData.mpAppName = NULL; + } + if ( pSVData->maAppData.mpDisplayName ) + { + delete pSVData->maAppData.mpDisplayName; + pSVData->maAppData.mpDisplayName = NULL; + } + if ( pSVData->maAppData.mpEventListeners ) + { + delete pSVData->maAppData.mpEventListeners; + pSVData->maAppData.mpEventListeners = NULL; + } + if ( pSVData->maAppData.mpKeyListeners ) + { + delete pSVData->maAppData.mpKeyListeners; + pSVData->maAppData.mpKeyListeners = NULL; + } + + if ( pSVData->maAppData.mpFirstHotKey ) + ImplFreeHotKeyData(); + if ( pSVData->maAppData.mpFirstEventHook ) + ImplFreeEventHookData(); + + ImplDeletePrnQueueList(); + delete pSVData->maGDIData.mpScreenFontList; + pSVData->maGDIData.mpScreenFontList = NULL; + delete pSVData->maGDIData.mpScreenFontCache; + pSVData->maGDIData.mpScreenFontCache = NULL; + ImplFreeOutDevFontData(); + + if ( pSVData->mpResMgr ) + { + delete pSVData->mpResMgr; + pSVData->mpResMgr = NULL; + } + + ResMgr::DestroyAllResMgr(); + + // destroy all Sal interfaces before destorying the instance + // and thereby unloading the plugin + delete pSVData->mpSalSystem; + pSVData->mpSalSystem = NULL; + delete pSVData->mpSalTimer; + pSVData->mpSalTimer = NULL; + + // Sal deinitialisieren + DestroySalInstance( pSVData->mpDefInst ); + + DeInitTools(); + + DeInitSalMain(); + + if( pOwnSvApp ) + { + delete pOwnSvApp; + pOwnSvApp = NULL; + } +} + +// only one call is allowed +struct WorkerThreadData +{ + oslWorkerFunction pWorker; + void * pThreadData; + WorkerThreadData( oslWorkerFunction pWorker_, void * pThreadData_ ) + : pWorker( pWorker_ ) + , pThreadData( pThreadData_ ) + { + } +}; + +#ifdef WNT +static HANDLE hThreadID = 0; +static unsigned __stdcall _threadmain( void *pArgs ) +{ + OleInitialize( NULL ); + ((WorkerThreadData*)pArgs)->pWorker( ((WorkerThreadData*)pArgs)->pThreadData ); + delete (WorkerThreadData*)pArgs; + OleUninitialize(); + hThreadID = 0; + return 0; +} +#else +static oslThread hThreadID = 0; +extern "C" +{ +static void SAL_CALL MainWorkerFunction( void* pArgs ) +{ + ((WorkerThreadData*)pArgs)->pWorker( ((WorkerThreadData*)pArgs)->pThreadData ); + delete (WorkerThreadData*)pArgs; + hThreadID = 0; +} +} // extern "C" +#endif + +void CreateMainLoopThread( oslWorkerFunction pWorker, void * pThreadData ) +{ +#ifdef WNT + // sal thread alway call CoInitializeEx, so a sysdepen implementation is necessary + + unsigned uThreadID; + hThreadID = (HANDLE)_beginthreadex( + NULL, // no security handle + 0, // stacksize 0 means default + _threadmain, // thread worker function + new WorkerThreadData( pWorker, pThreadData ), // arguments for worker function + 0, // 0 means: create immediatly otherwise use CREATE_SUSPENDED + &uThreadID ); // thread id to fill +#else + hThreadID = osl_createThread( MainWorkerFunction, new WorkerThreadData( pWorker, pThreadData ) ); +#endif +} + +void JoinMainLoopThread() +{ + if( hThreadID ) + { +#ifdef WNT + WaitForSingleObject(hThreadID, INFINITE); +#else + osl_joinWithThread(hThreadID); + osl_destroyThread( hThreadID ); +#endif + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/svmainhook.cxx b/vcl/source/app/svmainhook.cxx new file mode 100644 index 000000000000..8b6e5fe61255 --- /dev/null +++ b/vcl/source/app/svmainhook.cxx @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" +#include <tools/tools.h> + +#ifndef MACOSX + +BOOL ImplSVMainHook( BOOL * ) +{ + return FALSE; // indicate that ImplSVMainHook is not implemented +} + +#else +// MACOSX cocoa implementation of ImplSVMainHook is in aqua/source/app/salinst.cxx +#ifndef QUARTZ // MACOSX (X11) needs the CFRunLoop() +#include <osl/thread.h> +#include <premac.h> +#include <CoreFoundation/CoreFoundation.h> +#include <postmac.h> +#include <unistd.h> + +extern BOOL ImplSVMain(); + +// ============================================================================ + + +static void SourceContextCallBack( void *pInfo ) +{ +} + +struct ThreadContext +{ + BOOL* pRet; + CFRunLoopRef* pRunLoopRef; +}; + +static void RunSVMain(void *pData) +{ + ThreadContext* tcx = reinterpret_cast<ThreadContext*>(pData); + + // busy waiting (ok in this case) until the run loop is + // running + while (!CFRunLoopIsWaiting(*tcx->pRunLoopRef)) + usleep(100); + + *tcx->pRet = ImplSVMain(); + + // Force exit since some JVMs won't shutdown when only exit() is invoked + _exit( 0 ); +} + +BOOL ImplSVMainHook( BOOL *pbInit ) +{ + // Mac OS X requires that any Cocoa code have a CFRunLoop started in the + // primordial thread. Since all of the AWT classes in Java 1.4 and higher + // are written in Cocoa, we need to start the CFRunLoop here and run + // ImplSVMain() in a secondary thread. + // See http://developer.apple.com/samplecode/simpleJavaLauncher/listing3.html + // for further details and an example + + CFRunLoopRef runLoopRef = CFRunLoopGetCurrent(); + ThreadContext tcx; + tcx.pRet = pbInit; // the return value + tcx.pRunLoopRef = &runLoopRef; + oslThread hThreadID = osl_createThread(RunSVMain, &tcx); + + // Start the CFRunLoop + CFRunLoopSourceContext aSourceContext; + aSourceContext.version = 0; + aSourceContext.info = NULL; + aSourceContext.retain = NULL; + aSourceContext.release = NULL; + aSourceContext.copyDescription = NULL; + aSourceContext.equal = NULL; + aSourceContext.hash = NULL; + aSourceContext.schedule = NULL; + aSourceContext.cancel = NULL; + aSourceContext.perform = &SourceContextCallBack; + CFRunLoopSourceRef aSourceRef = CFRunLoopSourceCreate(NULL, 0, &aSourceContext); + CFRunLoopAddSource(runLoopRef, aSourceRef, kCFRunLoopCommonModes); + CFRunLoopRun(); + + osl_joinWithThread( hThreadID ); + osl_destroyThread( hThreadID ); + + return TRUE; // indicate that ImplSVMainHook is implemented +} + +#endif // MACOSX +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx new file mode 100644 index 000000000000..80b1f1047e63 --- /dev/null +++ b/vcl/source/app/timer.cxx @@ -0,0 +1,381 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include <svsys.h> +#include <vcl/saltimer.hxx> +#include <tools/time.hxx> +#include <vcl/svdata.hxx> +#include <vcl/svapp.hxx> +#include <vcl/salinst.hxx> +#include <tools/debug.hxx> +#include <vcl/timer.hxx> + + + +// ======================================================================= + +#define MAX_TIMER_PERIOD ((ULONG)0xFFFFFFFF) + +// --------------------- +// - TimeManager-Types - +// --------------------- + +struct ImplTimerData +{ + ImplTimerData* mpNext; // Pointer to the next Instance + Timer* mpSVTimer; // Pointer to SV Timer instance + ULONG mnUpdateTime; // Last Update Time + ULONG mnTimerUpdate; // TimerCallbackProcs on stack + BOOL mbDelete; // Wurde Timer waehren Update() geloescht + BOOL mbInTimeout; // Befinden wir uns im Timeout-Handler +}; + +// ======================================================================= + +void Timer::ImplDeInitTimer() +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplTimerData* pTimerData = pSVData->mpFirstTimerData; + + if ( pTimerData ) + { + do + { + ImplTimerData* pTempTimerData = pTimerData; + if ( pTimerData->mpSVTimer ) + { + pTimerData->mpSVTimer->mbActive = FALSE; + pTimerData->mpSVTimer->mpTimerData = NULL; + } + pTimerData = pTimerData->mpNext; + delete pTempTimerData; + } + while ( pTimerData ); + + pSVData->mpFirstTimerData = NULL; + pSVData->mnTimerPeriod = 0; + delete pSVData->mpSalTimer; + pSVData->mpSalTimer = NULL; + } +} + +// ----------------------------------------------------------------------- + +static void ImplStartTimer( ImplSVData* pSVData, ULONG nMS ) +{ + if ( !nMS ) + nMS = 1; + + if ( nMS != pSVData->mnTimerPeriod ) + { + pSVData->mnTimerPeriod = nMS; + pSVData->mpSalTimer->Start( nMS ); + } +} + +// ----------------------------------------------------------------------- + +void Timer::ImplTimerCallbackProc() +{ + ImplSVData* pSVData = ImplGetSVData(); + ImplTimerData* pTimerData; + ImplTimerData* pPrevTimerData; + ULONG nMinPeriod = MAX_TIMER_PERIOD; + ULONG nDeltaTime; + ULONG nTime = Time::GetSystemTicks(); + + if ( pSVData->mbNoCallTimer ) + return; + + pSVData->mnTimerUpdate++; + pSVData->mbNotAllTimerCalled = TRUE; + + // Suche Timer raus, wo der Timeout-Handler gerufen werden muss + pTimerData = pSVData->mpFirstTimerData; + while ( pTimerData ) + { + // Wenn Timer noch nicht neu ist und noch nicht geloescht wurde + // und er sich nicht im Timeout-Handler befindet, + // dann den Handler rufen, wenn die Zeit abgelaufen ist + if ( (pTimerData->mnTimerUpdate < pSVData->mnTimerUpdate) && + !pTimerData->mbDelete && !pTimerData->mbInTimeout ) + { + // Zeit abgelaufen + if ( (pTimerData->mnUpdateTime+pTimerData->mpSVTimer->mnTimeout) <= nTime ) + { + // Neue Updatezeit setzen + pTimerData->mnUpdateTime = nTime; + + // kein AutoTimer, dann anhalten + if ( !pTimerData->mpSVTimer->mbAuto ) + { + pTimerData->mpSVTimer->mbActive = FALSE; + pTimerData->mbDelete = TRUE; + } + + // call Timeout + pTimerData->mbInTimeout = TRUE; + pTimerData->mpSVTimer->Timeout(); + pTimerData->mbInTimeout = FALSE; + } + } + + pTimerData = pTimerData->mpNext; + } + + // Neue Zeit ermitteln + ULONG nNewTime = Time::GetSystemTicks(); + pPrevTimerData = NULL; + pTimerData = pSVData->mpFirstTimerData; + while ( pTimerData ) + { + // Befindet sich Timer noch im Timeout-Handler, dann ignorieren + if ( pTimerData->mbInTimeout ) + { + pPrevTimerData = pTimerData; + pTimerData = pTimerData->mpNext; + } + // Wurde Timer zwischenzeitlich zerstoert ? + else if ( pTimerData->mbDelete ) + { + if ( pPrevTimerData ) + pPrevTimerData->mpNext = pTimerData->mpNext; + else + pSVData->mpFirstTimerData = pTimerData->mpNext; + if ( pTimerData->mpSVTimer ) + pTimerData->mpSVTimer->mpTimerData = NULL; + ImplTimerData* pTempTimerData = pTimerData; + pTimerData = pTimerData->mpNext; + delete pTempTimerData; + } + else + { + pTimerData->mnTimerUpdate = 0; + // kleinste Zeitspanne ermitteln + if ( pTimerData->mnUpdateTime == nTime ) + { + nDeltaTime = pTimerData->mpSVTimer->mnTimeout; + if ( nDeltaTime < nMinPeriod ) + nMinPeriod = nDeltaTime; + } + else + { + nDeltaTime = pTimerData->mnUpdateTime + pTimerData->mpSVTimer->mnTimeout; + if ( nDeltaTime < nNewTime ) + nMinPeriod = 1; + else + { + nDeltaTime -= nNewTime; + if ( nDeltaTime < nMinPeriod ) + nMinPeriod = nDeltaTime; + } + } + pPrevTimerData = pTimerData; + pTimerData = pTimerData->mpNext; + } + } + + // Wenn keine Timer mehr existieren, dann Clock loeschen + if ( !pSVData->mpFirstTimerData ) + { + pSVData->mpSalTimer->Stop(); + pSVData->mnTimerPeriod = MAX_TIMER_PERIOD; + } + else + ImplStartTimer( pSVData, nMinPeriod ); + + pSVData->mnTimerUpdate--; + pSVData->mbNotAllTimerCalled = FALSE; +} + +// ======================================================================= + +Timer::Timer() +{ + mpTimerData = NULL; + mnTimeout = 1; + mbAuto = FALSE; + mbActive = FALSE; +} + +// ----------------------------------------------------------------------- + +Timer::Timer( const Timer& rTimer ) +{ + mpTimerData = NULL; + mnTimeout = rTimer.mnTimeout; + mbAuto = FALSE; + mbActive = FALSE; + maTimeoutHdl = rTimer.maTimeoutHdl; + + if ( rTimer.IsActive() ) + Start(); +} + +// ----------------------------------------------------------------------- + +Timer::~Timer() +{ + if ( mpTimerData ) + { + mpTimerData->mbDelete = TRUE; + mpTimerData->mpSVTimer = NULL; + } +} + +// ----------------------------------------------------------------------- + +void Timer::Timeout() +{ + maTimeoutHdl.Call( this ); +} + +// ----------------------------------------------------------------------- + +void Timer::SetTimeout( ULONG nNewTimeout ) +{ + mnTimeout = nNewTimeout; + + // Wenn Timer aktiv, dann Clock erneuern + if ( mbActive ) + { + ImplSVData* pSVData = ImplGetSVData(); + if ( !pSVData->mnTimerUpdate && (mnTimeout < pSVData->mnTimerPeriod) ) + ImplStartTimer( pSVData, mnTimeout ); + } +} + +// ----------------------------------------------------------------------- + +void Timer::Start() +{ + mbActive = TRUE; + + ImplSVData* pSVData = ImplGetSVData(); + if ( !mpTimerData ) + { + if ( !pSVData->mpFirstTimerData ) + { + pSVData->mnTimerPeriod = MAX_TIMER_PERIOD; + if( ! pSVData->mpSalTimer ) + { + pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer(); + pSVData->mpSalTimer->SetCallback( ImplTimerCallbackProc ); + } + } + + // insert timer and start + mpTimerData = new ImplTimerData; + mpTimerData->mpSVTimer = this; + mpTimerData->mnUpdateTime = Time::GetSystemTicks(); + mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate; + mpTimerData->mbDelete = FALSE; + mpTimerData->mbInTimeout = FALSE; + + // !!!!! Wegen SFX hinten einordnen !!!!! + ImplTimerData* pPrev = NULL; + ImplTimerData* pData = pSVData->mpFirstTimerData; + while ( pData ) + { + pPrev = pData; + pData = pData->mpNext; + } + mpTimerData->mpNext = NULL; + if ( pPrev ) + pPrev->mpNext = mpTimerData; + else + pSVData->mpFirstTimerData = mpTimerData; + + if ( mnTimeout < pSVData->mnTimerPeriod ) + ImplStartTimer( pSVData, mnTimeout ); + } + else if( !mpTimerData->mpSVTimer ) // TODO: remove when guilty found + { + DBG_ERROR( "Timer::Start() on a destroyed Timer!" ); + } + else + { + mpTimerData->mnUpdateTime = Time::GetSystemTicks(); + mpTimerData->mnTimerUpdate = pSVData->mnTimerUpdate; + mpTimerData->mbDelete = FALSE; + } +} + +// ----------------------------------------------------------------------- + +void Timer::Stop() +{ + mbActive = FALSE; + + if ( mpTimerData ) + mpTimerData->mbDelete = TRUE; +} + +// ----------------------------------------------------------------------- + +Timer& Timer::operator=( const Timer& rTimer ) +{ + if ( IsActive() ) + Stop(); + + mbActive = FALSE; + mnTimeout = rTimer.mnTimeout; + maTimeoutHdl = rTimer.maTimeoutHdl; + + if ( rTimer.IsActive() ) + Start(); + + return *this; +} + +// ======================================================================= + +AutoTimer::AutoTimer() +{ + mbAuto = TRUE; +} + +// ----------------------------------------------------------------------- + +AutoTimer::AutoTimer( const AutoTimer& rTimer ) : Timer( rTimer ) +{ + mbAuto = TRUE; +} + +// ----------------------------------------------------------------------- + +AutoTimer& AutoTimer::operator=( const AutoTimer& rTimer ) +{ + Timer::operator=( rTimer ); + return *this; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/unohelp.cxx b/vcl/source/app/unohelp.cxx new file mode 100644 index 000000000000..d49f5f888acb --- /dev/null +++ b/vcl/source/app/unohelp.cxx @@ -0,0 +1,241 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + + + +#include <vcl/unohelp.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <comphelper/processfactory.hxx> + +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include <com/sun/star/i18n/XCharacterClassification.hpp> + +#include <com/sun/star/i18n/XCollator.hpp> +#include <com/sun/star/awt/XExtendedToolkit.hpp> +#include <com/sun/star/accessibility/AccessibleEventObject.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> + + +#include <com/sun/star/registry/XImplementationRegistration.hpp> + +#include <cppuhelper/servicefactory.hxx> + +#include <tools/tempfile.hxx> +#include <osl/file.hxx> + +#include <vcl/svdata.hxx> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; +using namespace ::rtl; + +#define DOSTRING( x ) #x +#define STRING( x ) DOSTRING( x ) + +struct VCLRegServiceInfo +{ + const sal_Char* pLibName; + sal_Bool bHasSUPD; +}; + +static VCLRegServiceInfo aVCLComponentsArray[] = +{ + {"i18n", sal_True}, + {"i18npool", sal_True}, +#ifdef UNX +#ifdef MACOSX + {"dtransaqua", sal_True}, +#else + {"dtransX11", sal_True}, +#endif +#endif +#if defined(WNT) || defined(OS2) + {"sysdtrans", sal_False}, +#endif + {"dtrans", sal_False}, + {"mcnttype", sal_False}, + {"ftransl", sal_False}, + {"dnd", sal_False}, + {NULL, sal_False} +}; + +uno::Reference< lang::XMultiServiceFactory > vcl::unohelper::GetMultiServiceFactory() +{ + ImplSVData* pSVData = ImplGetSVData(); + if ( !pSVData->maAppData.mxMSF.is() ) + { + pSVData->maAppData.mxMSF = ::comphelper::getProcessServiceFactory(); + } + if ( !pSVData->maAppData.mxMSF.is() ) + { + TempFile aTempFile; + OUString aTempFileName; + osl::FileBase::getSystemPathFromFileURL( aTempFile.GetName(), aTempFileName ); + pSVData->maAppData.mpMSFTempFileName = new String(aTempFileName); + + try + { + pSVData->maAppData.mxMSF = ::cppu::createRegistryServiceFactory( aTempFileName, rtl::OUString(), sal_False ); + uno::Reference < registry::XImplementationRegistration > xReg( + pSVData->maAppData.mxMSF->createInstance( OUString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" )), uno::UNO_QUERY ); + + if( xReg.is() ) + { + sal_Int32 nCompCount = 0; + while ( aVCLComponentsArray[ nCompCount ].pLibName ) + { + OUString aComponentPathString = CreateLibraryName( aVCLComponentsArray[ nCompCount ].pLibName, aVCLComponentsArray[ nCompCount ].bHasSUPD ); + if (aComponentPathString.getLength() ) + { + try + { + xReg->registerImplementation( + OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ),aComponentPathString, NULL ); + } + catch( ::com::sun::star::uno::Exception & ) + { + } + } + nCompCount++; + } + } + } + catch( ::com::sun::star::uno::Exception & ) + { + delete pSVData->maAppData.mpMSFTempFileName; + pSVData->maAppData.mpMSFTempFileName = NULL; + } + } + return pSVData->maAppData.mxMSF; +} + + +uno::Reference < i18n::XBreakIterator > vcl::unohelper::CreateBreakIterator() +{ + uno::Reference < i18n::XBreakIterator > xB; + uno::Reference< lang::XMultiServiceFactory > xMSF = GetMultiServiceFactory(); + if ( xMSF.is() ) + { + uno::Reference < uno::XInterface > xI = xMSF->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) ); + if ( xI.is() ) + { + uno::Any x = xI->queryInterface( ::getCppuType((const uno::Reference< i18n::XBreakIterator >*)0) ); + x >>= xB; + } + } + return xB; +} + +uno::Reference < i18n::XCharacterClassification > vcl::unohelper::CreateCharacterClassification() +{ + uno::Reference < i18n::XCharacterClassification > xB; + uno::Reference< lang::XMultiServiceFactory > xMSF = GetMultiServiceFactory(); + if ( xMSF.is() ) + { + uno::Reference < uno::XInterface > xI = xMSF->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.i18n.CharacterClassification" ) ); + if ( xI.is() ) + { + uno::Any x = xI->queryInterface( ::getCppuType((const uno::Reference< i18n::XCharacterClassification >*)0) ); + x >>= xB; + } + } + return xB; +} + +uno::Reference < i18n::XCollator > vcl::unohelper::CreateCollator() +{ + uno::Reference < i18n::XCollator > xB; + uno::Reference< lang::XMultiServiceFactory > xMSF = GetMultiServiceFactory(); + if ( xMSF.is() ) + { + uno::Reference < uno::XInterface > xI = xMSF->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ) ); + if ( xI.is() ) + { + uno::Any x = xI->queryInterface( ::getCppuType((const uno::Reference< i18n::XCollator >*)0) ); + x >>= xB; + } + } + return xB; +} + +::rtl::OUString vcl::unohelper::CreateLibraryName( const sal_Char* pModName, sal_Bool bSUPD ) +{ + // create variable library name suffixes + OUString aDLLSuffix = OUString::createFromAscii( STRING(DLLPOSTFIX) ); + + OUString aLibName; + +#if defined( WNT) || defined(OS2) + aLibName = OUString::createFromAscii( pModName ); + if ( bSUPD ) + { + aLibName += aDLLSuffix; + } + aLibName += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".dll" )); +#else + aLibName = OUString( RTL_CONSTASCII_USTRINGPARAM( "lib" )); + aLibName += OUString::createFromAscii( pModName ); + if ( bSUPD ) + { + aLibName += aDLLSuffix; + } +#ifdef MACOSX + aLibName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".dylib" )); +#else + aLibName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".so" )); +#endif +#endif + + return aLibName; +} + +void vcl::unohelper::NotifyAccessibleStateEventGlobally( const ::com::sun::star::accessibility::AccessibleEventObject& rEventObject ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XExtendedToolkit > xExtToolkit( Application::GetVCLToolkit(), uno::UNO_QUERY ); + if ( xExtToolkit.is() ) + { + // Only for focus events + sal_Int16 nType = ::com::sun::star::accessibility::AccessibleStateType::INVALID; + rEventObject.NewValue >>= nType; + if ( nType == ::com::sun::star::accessibility::AccessibleStateType::FOCUSED ) + xExtToolkit->fireFocusGained( rEventObject.Source ); + else + { + rEventObject.OldValue >>= nType; + if ( nType == ::com::sun::star::accessibility::AccessibleStateType::FOCUSED ) + xExtToolkit->fireFocusLost( rEventObject.Source ); + } + + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/unohelp2.cxx b/vcl/source/app/unohelp2.cxx new file mode 100644 index 000000000000..15e8aec9063d --- /dev/null +++ b/vcl/source/app/unohelp2.cxx @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" +#include <vcl/unohelp2.hxx> +#include <sot/exchange.hxx> +#include <sot/formats.hxx> +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> +#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> + + +using namespace ::com::sun::star; + +namespace vcl { namespace unohelper { + + TextDataObject::TextDataObject( const String& rText ) : maText( rText ) + { + } + + TextDataObject::~TextDataObject() + { + } + + void TextDataObject::CopyStringTo( const String& rContent, + const uno::Reference< datatransfer::clipboard::XClipboard >& rxClipboard ) + { + DBG_ASSERT( rxClipboard.is(), "TextDataObject::CopyStringTo: invalid clipboard!" ); + if ( !rxClipboard.is() ) + return; + + TextDataObject* pDataObj = new TextDataObject( rContent ); + + const sal_uInt32 nRef = Application::ReleaseSolarMutex(); + try + { + rxClipboard->setContents( pDataObj, NULL ); + + uno::Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( rxClipboard, uno::UNO_QUERY ); + if( xFlushableClipboard.is() ) + xFlushableClipboard->flushClipboard(); + } + catch( const uno::Exception& ) + { + } + Application::AcquireSolarMutex( nRef ); + } + + // ::com::sun::star::uno::XInterface + uno::Any TextDataObject::queryInterface( const uno::Type & rType ) throw(uno::RuntimeException) + { + uno::Any aRet = ::cppu::queryInterface( rType, SAL_STATIC_CAST( datatransfer::XTransferable*, this ) ); + return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); + } + + // ::com::sun::star::datatransfer::XTransferable + uno::Any TextDataObject::getTransferData( const datatransfer::DataFlavor& rFlavor ) throw(datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException) + { + uno::Any aAny; + + ULONG nT = SotExchange::GetFormat( rFlavor ); + if ( nT == SOT_FORMAT_STRING ) + { + aAny <<= (::rtl::OUString)GetString(); + } + else + { + throw datatransfer::UnsupportedFlavorException(); + } + return aAny; + } + + uno::Sequence< datatransfer::DataFlavor > TextDataObject::getTransferDataFlavors( ) throw(uno::RuntimeException) + { + uno::Sequence< datatransfer::DataFlavor > aDataFlavors(1); + SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aDataFlavors.getArray()[0] ); + return aDataFlavors; + } + + sal_Bool TextDataObject::isDataFlavorSupported( const datatransfer::DataFlavor& rFlavor ) throw(uno::RuntimeException) + { + ULONG nT = SotExchange::GetFormat( rFlavor ); + return ( nT == SOT_FORMAT_STRING ); + } + +}} // namespace vcl::unohelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/app/vclevent.cxx b/vcl/source/app/vclevent.cxx new file mode 100644 index 000000000000..65a490b5563b --- /dev/null +++ b/vcl/source/app/vclevent.cxx @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "vcl/vclevent.hxx" +#include "vcl/svdata.hxx" + +#include <com/sun/star/accessibility/XAccessible.hpp> + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::accessibility::XAccessible; + +TYPEINIT0(VclSimpleEvent); +TYPEINIT1(VclWindowEvent, VclSimpleEvent); +TYPEINIT1(VclMenuEvent, VclSimpleEvent); + +VclAccessibleEvent::VclAccessibleEvent( ULONG n, const Reference<XAccessible>& rxAccessible ) : + VclSimpleEvent(n), + mxAccessible(rxAccessible) +{ +} + +VclAccessibleEvent::~VclAccessibleEvent() +{ +} + +Reference<XAccessible> VclAccessibleEvent::GetAccessible() const +{ + return mxAccessible; +} + +void VclEventListeners::Call( VclSimpleEvent* pEvent ) const +{ + // Copy the list, because this can be destroyed when calling a Link... + std::list<Link> aCopy( *this ); + std::list<Link>::iterator aIter( aCopy.begin() ); + if( pEvent->IsA( VclWindowEvent::StaticType() ) ) + { + VclWindowEvent* pWinEvent = static_cast<VclWindowEvent*>(pEvent); + ImplDelData aDel( pWinEvent->GetWindow() ); + while ( aIter != aCopy.end() && ! aDel.IsDead() ) + { + (*aIter).Call( pEvent ); + aIter++; + } + } + else + { + while ( aIter != aCopy.end() ) + { + (*aIter).Call( pEvent ); + aIter++; + } + } +} + +BOOL VclEventListeners::Process( VclSimpleEvent* pEvent ) const +{ + BOOL bProcessed = FALSE; + // Copy the list, because this can be destroyed when calling a Link... + std::list<Link> aCopy( *this ); + std::list<Link>::iterator aIter( aCopy.begin() ); + while ( aIter != aCopy.end() ) + { + if( (*aIter).Call( pEvent ) != 0 ) + { + bProcessed = TRUE; + break; + } + aIter++; + } + return bProcessed; +} + +VclEventListeners2::VclEventListeners2() +{ +} + +VclEventListeners2::~VclEventListeners2() +{ +} + +void VclEventListeners2::addListener( const Link& i_rLink ) +{ + // ensure uniqueness + for( std::list< Link >::const_iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it ) + { + if( *it == i_rLink ) + return; + } + m_aListeners.push_back( i_rLink ); +} + +void VclEventListeners2::removeListener( const Link& i_rLink ) +{ + size_t n = m_aIterators.size(); + for( size_t i = 0; i < n; i++ ) + { + if( m_aIterators[i].m_aIt != m_aListeners.end() && *m_aIterators[i].m_aIt == i_rLink ) + { + m_aIterators[i].m_bWasInvalidated = true; + ++m_aIterators[i].m_aIt; + } + } + m_aListeners.remove( i_rLink ); +} + +void VclEventListeners2::callListeners( VclSimpleEvent* i_pEvent ) +{ + vcl::DeletionListener aDel( this ); + + m_aIterators.push_back(ListenerIt(m_aListeners.begin())); + size_t nIndex = m_aIterators.size() - 1; + while( ! aDel.isDeleted() && m_aIterators[ nIndex ].m_aIt != m_aListeners.end() ) + { + m_aIterators[ nIndex ].m_aIt->Call( i_pEvent ); + if( m_aIterators[ nIndex ].m_bWasInvalidated ) + // check if the current element was removed and the iterator increased in the meantime + m_aIterators[ nIndex ].m_bWasInvalidated = false; + else + ++m_aIterators[ nIndex ].m_aIt; + } + m_aIterators.pop_back(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |