| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 "tools/debug.hxx" |
| |
| #include "vos/mutex.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 "svdata.hxx" |
| #include "dbggui.hxx" |
| |
| #include "vcl/unohelp.hxx" |
| #include "vcl/unohelp2.hxx" |
| |
| #include "salinst.hxx" |
| #include "svdata.hxx" |
| #include "svsys.h" |
| |
| #include "com/sun/star/i18n/XCharacterClassification.hpp" |
| |
| #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", |
| "Abort\n", |
| "Aborts the application\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 [] ( sal_uInt16 nIndex )\n", |
| "{\n", |
| " DBG_CHKTHIS( String, DbgCheckString );\n", |
| " DBG_ASSERT( nIndex <= pData->nLen, \"String::[] : nIndex > Len\" );\n", |
| "\n", |
| " //...\n", |
| "}\n", |
| "\n", |
| "sal_uInt16 String::Search( const String& rStr, sal_uInt16 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 |
| ) |
| { |
| sal_uInt16 nEntryPos = rList.InsertEntry( channel->first ); |
| rList.SetEntryData( nEntryPos, reinterpret_cast< void* >( channel->second ) ); |
| } |
| } |
| |
| // ------------------------------------------------------------------- |
| void ImplSelectChannel( ListBox& rList, sal_uLong nChannelToSelect, sal_uInt16 nPositionOffset ) |
| { |
| if ( nChannelToSelect < DBG_OUT_USER_CHANNEL_0 ) |
| rList.SelectEntryPos( (sal_uInt16)( nChannelToSelect - nPositionOffset ) ); |
| else |
| { |
| for ( sal_uInt16 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, sal_uInt16 nPositionOffset ) |
| { |
| sal_uInt16 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 sal_Bool Close(); |
| virtual void Resize(); |
| virtual long PreNotify( NotifyEvent& rNEvt ); |
| void InsertLine( const XubString& rLine ); |
| void Update() { WorkWindow::Update(); maLstBox.Update(); } |
| |
| private: |
| void GetAssertionEntryRange( sal_uInt16 nInbetweenEntry, sal_uInt16& nFirst, sal_uInt16& nLast ); |
| }; |
| |
| // ----------------- |
| // - DbgInfoDialog - |
| // ----------------- |
| |
| class DbgInfoDialog : public ModalDialog |
| { |
| private: |
| ListBox maListBox; |
| OKButton maOKButton; |
| sal_Bool mbHelpText; |
| |
| public: |
| DbgInfoDialog( Window* pParent, sal_Bool bHelpText = sal_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; |
| sal_uInt16 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(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool DbgWindow::Close() |
| { |
| // remember window position |
| ByteString aState( GetWindowState() ); |
| DbgData* pData = DbgGetData(); |
| size_t nCopy = (sizeof( pData->aDbgWinState ) < size_t(aState.Len() + 1U )) |
| ? sizeof( pData->aDbgWinState ) : size_t(aState.Len() + 1U ); |
| strncpy( pData->aDbgWinState, aState.GetBuffer(), nCopy ); |
| pData->aDbgWinState[ sizeof( pData->aDbgWinState ) - 1 ] = 0; |
| // and save for next session |
| DbgSaveData( *pData ); |
| |
| delete this; |
| ImplGetSVData()->maWinData.mpDbgWin = NULL; |
| return sal_True; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void DbgWindow::Resize() |
| { |
| maLstBox.SetSizePixel( GetOutputSizePixel() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void DbgWindow::GetAssertionEntryRange( sal_uInt16 nInbetweenEntry, sal_uInt16& nFirst, sal_uInt16& nLast ) |
| { |
| nFirst = nInbetweenEntry; |
| while ( nFirst > 0 ) |
| { |
| if ( maLstBox.GetEntryData( nFirst ) != NULL ) |
| break; |
| --nFirst; |
| } |
| sal_uInt16 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(); |
| } |
| sal_uInt16 nSelected = aMenu.Execute( rNEvt.GetWindow(), aPos ); |
| if ( nSelected == 1 ) |
| { |
| // search all entries which belong to this assertion |
| sal_uInt16 nAssertionFirst = 0; |
| sal_uInt16 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 ); |
| sal_Bool bFirstEntry = sal_True; |
| while ( nPos != STRING_NOTFOUND ) |
| { |
| if ( maLstBox.GetEntryCount() >= DBGWIN_MAXLINES ) |
| maLstBox.RemoveEntry( 0 ); |
| |
| sal_uInt16 nInsertionPos = maLstBox.InsertEntry( aStr.Copy( 0, nPos ) ); |
| if ( bFirstEntry ) |
| maLstBox.SetEntryData( nInsertionPos, reinterpret_cast< void* >( 0x00000001 ) ); |
| bFirstEntry = sal_False; |
| |
| aStr.Erase( 0, nPos+1 ); |
| nPos = aStr.Search( _LF ); |
| } |
| if ( maLstBox.GetEntryCount() >= DBGWIN_MAXLINES ) |
| maLstBox.RemoveEntry( 0 ); |
| sal_uInt16 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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( sal_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( "Abort" ) ) ); |
| 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( "Abort" ) ) ); |
| 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( "Abort" ) ) ); |
| 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() ? sal_True : sal_False; |
| aData.bHookOSLAssert = maHookOSLBox.IsChecked() ? sal_True : sal_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( sal_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, sal_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, sal_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( sal_False ); |
| maListBox.Clear(); |
| XubString aStr = rStr; |
| aStr.ConvertLineEnd( LINEEND_LF ); |
| sal_uInt16 nStrIndex = 0; |
| sal_uInt16 nFoundIndex; |
| do |
| { |
| nFoundIndex = aStr.Search( _LF, nStrIndex ); |
| XubString aTextParagraph = aStr.Copy( nStrIndex, nFoundIndex-nStrIndex ); |
| if ( mbHelpText ) |
| { |
| long nMaxWidth = maListBox.GetOutputSizePixel().Width()-30; |
| sal_uInt16 nLastIndex = 0; |
| sal_uInt16 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( sal_True ); |
| } |
| |
| // ======================================================================= |
| |
| void DbgDialogTest( Window* pWindow ) |
| { |
| sal_Bool aAccelBuf[65536]; |
| sal_uInt16 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() ) |
| { |
| sal_Bool bOKCancelButton = sal_False; |
| sal_Bool bDefPushButton = sal_False; |
| sal_Bool bButton = sal_False; |
| pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); |
| while ( pGetChild ) |
| { |
| pChild = pGetChild->ImplGetWindow(); |
| |
| if ( pChild->ImplIsPushButton() ) |
| { |
| bButton = sal_True; |
| if ( (pChild->GetType() == WINDOW_OKBUTTON) || (pChild->GetType() == WINDOW_CANCELBUTTON) ) |
| bOKCancelButton = sal_True; |
| if ( pChild->GetStyle() & WB_DEFBUTTON ) |
| bDefPushButton = sal_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" ); |
| } |
| } |
| |
| sal_uInt16 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; |
| sal_uInt16 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] = sal_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() ) |
| { |
| sal_Bool bMaxWarning = sal_False; |
| if ( pChild->GetType() == WINDOW_NUMERICFIELD ) |
| { |
| NumericField* pField = (NumericField*)pChild; |
| if ( pField->GetMax() == LONG_MAX ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_METRICFIELD ) |
| { |
| MetricField* pField = (MetricField*)pChild; |
| if ( pField->GetMax() == LONG_MAX ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_CURRENCYFIELD ) |
| { |
| CurrencyField* pField = (CurrencyField*)pChild; |
| if ( pField->GetMax() == LONG_MAX ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_TIMEFIELD ) |
| { |
| TimeField* pField = (TimeField*)pChild; |
| if ( pField->GetMax() == Time( 23, 59, 59, 99 ) ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_DATEFIELD ) |
| { |
| DateField* pField = (DateField*)pChild; |
| if ( pField->GetMax() == Date( 31, 12, 9999 ) ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_NUMERICBOX ) |
| { |
| NumericBox* pBox = (NumericBox*)pChild; |
| if ( pBox->GetMax() == LONG_MAX ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_METRICBOX ) |
| { |
| MetricBox* pBox = (MetricBox*)pChild; |
| if ( pBox->GetMax() == LONG_MAX ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_CURRENCYBOX ) |
| { |
| CurrencyBox* pBox = (CurrencyBox*)pChild; |
| if ( pBox->GetMax() == LONG_MAX ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_TIMEBOX ) |
| { |
| TimeBox* pBox = (TimeBox*)pChild; |
| if ( pBox->GetMax() == Time( 23, 59, 59, 99 ) ) |
| bMaxWarning = sal_True; |
| } |
| else if ( pChild->GetType() == WINDOW_DATEBOX ) |
| { |
| DateBox* pBox = (DateBox*)pChild; |
| if ( pBox->GetMax() == Date( 31, 12, 9999 ) ) |
| bMaxWarning = sal_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 ( sal_uInt16 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 |
| sal_Bool bOldCallTimer = pSVData->mbNoCallTimer; |
| pSVData->mbNoCallTimer = sal_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 |
| sal_uInt16 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 sal_Bool bIn = sal_False; |
| |
| // keine rekursiven Traces |
| if ( bIn ) |
| return; |
| bIn = sal_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 = sal_False; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void DbgAbort( char const * i_message ) |
| { |
| ::rtl::OUString const message( i_message, strlen( i_message ), osl_getThreadTextEncoding() ); |
| Application::Abort( message ); |
| } |
| |
| // ======================================================================= |
| |
| void ImplDbgTestSolarMutex() |
| { |
| bool bCheck = ImplGetSVData()->mpDefInst->CheckYieldMutex(); |
| OSL_ENSURE( bCheck, "SolarMutex not locked" ); |
| } |
| |
| // ======================================================================= |
| |
| void DbgGUIInit() |
| { |
| DbgSetPrintMsgBox( DbgPrintMsgBox ); |
| DbgSetPrintWindow( DbgPrintWindow ); |
| DbgSetTestSolarMutex( ImplDbgTestSolarMutex ); |
| DbgSetAbort( DbgAbort ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void DbgGUIDeInit() |
| { |
| DbgSetPrintMsgBox( NULL ); |
| DbgSetPrintWindow( NULL ); |
| DbgSetTestSolarMutex( NULL ); |
| DbgSetAbort( NULL ); |
| |
| 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 |
| sal_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(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 DbgRegisterNamedUserChannel( const XubString& _rChannelUIName, DbgPrintLine pProc ) |
| { |
| DbgChannelId nChannelId = DbgRegisterUserChannel( pProc ); |
| UserDefinedChannels& rChannels = ImplDbgGetUserDefinedChannels(); |
| rChannels[ _rChannelUIName ] = nChannelId; |
| return nChannelId; |
| } |
| |
| #endif // DBG_UTIL |