1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <sal/config.h> 32 33 #ifdef DBG_UTIL 34 35 #include <cstdio> 36 #include <cstring> 37 #include <cmath> 38 #include <limits.h> 39 40 #include "tools/debug.hxx" 41 42 #include "vos/mutex.hxx" 43 44 #include "vcl/svapp.hxx" 45 #include "vcl/event.hxx" 46 #include "vcl/lstbox.hxx" 47 #include "vcl/button.hxx" 48 #include "vcl/edit.hxx" 49 #include "vcl/fixed.hxx" 50 #include "vcl/group.hxx" 51 #include "vcl/field.hxx" 52 #include "vcl/msgbox.hxx" 53 #include "vcl/wrkwin.hxx" 54 #include "vcl/sound.hxx" 55 #include "vcl/threadex.hxx" 56 57 #include "svdata.hxx" 58 #include "dbggui.hxx" 59 60 #include "vcl/unohelp.hxx" 61 #include "vcl/unohelp2.hxx" 62 63 #include "salinst.hxx" 64 #include "svdata.hxx" 65 #include "svsys.h" 66 67 #include "com/sun/star/i18n/XCharacterClassification.hpp" 68 69 #include <map> 70 #include <algorithm> 71 72 using namespace ::com::sun::star; 73 74 // ======================================================================= 75 76 static const sal_Char* pDbgHelpText[] = 77 { 78 "Object Test\n", 79 "------------------------------------------\n", 80 "\n", 81 "--- Macros ---\n", 82 "DBG_NAME( aName )\n", 83 "Defines the administration data for a class. This macro may only be used " 84 " in a source file with the same name.\n", 85 "\n", 86 "DBG_NAMEEX( aName )\n", 87 "Like DBG_NAME, only for other source files.\n", 88 "\n", 89 "DBG_CTOR( aName, fTest )\n", 90 "Must be used in all constructors of a class (also in the CopyCtor). " 91 "The first parameter must be the registered name (best would be the " 92 "class name) and the second parameter the test function or 0.\n", 93 "\n", 94 "DBG_DTOR( aName, fTest )\n", 95 "Must be used in the destructor of the class. The first parameter is " 96 "the registered name and the second parameter is the test function or " 97 "0.\n", 98 "\n", 99 "DBG_CHKTHIS( aName, fTest )\n", 100 "Can be used in methods of the class when constructors and the " 101 "desctructor of the class are equiped with the corresponding macros. " 102 "The first parameter is the registered name, the second parameter is " 103 "the test function or 0.\n", 104 "\n", 105 "DBG_CHKOBJ( pObj, aName, fTest )\n", 106 "Can be used on instances of a class where the constructors and the " 107 "destructor of the class are equiped with the corresponding macros. " 108 "The first parameter is the registered name, the second parameter is " 109 "the test function or 0.\n", 110 "\n", 111 "To make the macros work DBG_UTIL must be defined.\n", 112 "\n", 113 "--- Options ---\n", 114 "This\n", 115 "The This pointer is validated. This way all objects that are equiped " 116 "with it can be tested to make sure one is working with existing objects. " 117 "This way it's easier to find bugs in case of multiple inheritence, " 118 "alignment or compiler errors. Since almost all standard classes of SV " 119 "(String, List, Pen, Brush, Polygon, ...) are equiped with DBG_CHKTHIS() " 120 "a lot of errors are found, although this test will impact performance " 121 "accordingly.\n", 122 "\n", 123 "Function\n", 124 "When a function is passed with macros, it will be called.\n", 125 "\n", 126 "Exit\n", 127 "This- and Func-Test will also run when exiting the function.\n", 128 "\n", 129 "Report\n", 130 "At the end of the program the number of generated objects is produced " 131 "as output. Because all important SV classes have at least DBG_CTOR() / " 132 "DBG_DTOR() it can checked so called resource leaks (system objects which " 133 " are not freed) exist. These include OutputDevice, Window, VirtualDevice, " 134 " Printer and Menu. Note: Dtor calls of static objects are not taken into " 135 " account. Therefor each SV program leaves 2 strings and a bitmap behind.\n", 136 "\n", 137 "Trace\n", 138 "Creation, destruction and usage of objects which are equiped with " 139 "DBG_XTOR is logged.\n", 140 "\n", 141 "\n", 142 "Memory Test\n", 143 "------------------------------------------\n", 144 "\n", 145 "--- Macros ---\n", 146 "DBG_MEMTEST()\n", 147 "Run the specified memory tests.\n", 148 "\n", 149 "DBG_MEMTEST_PTR( p )\n", 150 "Runs the specified memory tests and validates the pointer that was " 151 "passed if the pointer test is enabled.\n", 152 "\n", 153 "--- Options ---\n", 154 "Initialize\n", 155 "Allocated memory is initialized with 0x77 and free or freed memory " 156 "is initialized with 0x33. This option has almost no impact on performance " 157 "and should thus always be enabled during development. This will also " 158 "make crashes more often reproducable.\n", 159 "\n", 160 "Overwrite\n", 161 "This test check whether writes occur before or after the blocks. Before " 162 "and after the block memory is initialized with 0x55. This option costs " 163 "performance, but should be enabled once in a while to test for common " 164 "memory overwrites (+-1 errors). This option should also be enabled if the " 165 "program crashes in a new or delete operator.\n", 166 "\n", 167 "Free\n", 168 "This checks whether writes occur in free memory. This option costs lots " 169 " of performance and should thus only be used to test memory overwrites. " 170 " This option should perhaps also be enabled when the program crashes " 171 " in the new or delete operator.\n", 172 "\n", 173 "Pointer\n", 174 "The pointer is tested with delete and DBG_MEMTEST_PTR() to see if it was " 175 "created by new or SvMemAlloc(). When this option is enabled errors such as " 176 "double deletes, deletes on stack objects or invalid pointers will be found. " 177 "This option has an impact on performance and should therefor not be enabled " 178 "all the time. However, testing should be done with this option enabled once " 179 "in a while, because the memory manager does not always crash with delete and " 180 "invalid pointers. This option should also be enabled if the program crashes " 181 "in new or delete operators.\n", 182 "\n", 183 "Report\n", 184 "At the end of the program a small statistic and memory that was not freed are " 185 "output. Note: memory that is freed by global objects is also included in " 186 "the leak list.\n", 187 "\n", 188 "Trace\n", 189 "Allocating and freeing memory is logged.\n", 190 "\n", 191 "Leak report\n", 192 "Produces under WNT at the end of the program a list of memory leaks with " 193 "stack trace. Only blocks which were created inside Application::Execute() " 194 "are included. When this option and Overwrite are both enabled a memory " 195 "overwrite results in an attempt to output the stack where the block was " 196 "created. The output is included in the log file after the error message.\n" 197 "\n", 198 "New/Delete\n", 199 "Memory tests are performed on the entire memory with every new/delet. " 200 "Warning: this option makes programs very slow and should only be enabled " 201 "to track memory overwrites. Otherwise it is sufficient to enable " 202 "seperate options because (if no leak is present) every detectable " 203 "memory overwrite during run time should be found.\n", 204 "\n", 205 "Object Test\n", 206 "Memory test are performed on the entire memory with every object test. " 207 "Warning: this option makes programs very slow and should only be enabled " 208 "to track memory overwrite. Otherwise it is sufficient to enable " 209 "seperate options because (if no leak is present) every detectable " 210 "memory overwrite during run time should be found.\n", 211 "\n", 212 "Windows 16-bit and debug tests\n", 213 "Warning: when memory test are enabled (except for Initialize) memory with " 214 "offset 0 is never (even not in case of >= 64KB) returned. If necessary the " 215 "tests can be performed with 32-bit versions of the programs. To a certain " 216 "extend it is sufficient to create 64KB - 64 bytes instead of 64KB because " 217 "it will never come to a segment overflow.\n", 218 "Memory and object test should only be enabled when only one SV application " 219 "is running at one time. Otherwise uncontrolled errors may occur. In this " 220 "case only the use of 32-bit programs can help." 221 "\n", 222 "\n", 223 "\nOther tests and macros\n", 224 "------------------------------------------\n", 225 "\n", 226 "Profiling\n", 227 "DBG_PROFSTART() / DBG_PROFSTOP() / DBG_PROFCONTINUE() / DBG_PROFPAUSE() " 228 "are evaluated and at the end of the program the number of run throughs " 229 "and the time this took (including calls to children) in milliseconds is " 230 "output. These macros can be used to check the same function runs over the " 231 "entire development period, for example the startup speed. The registered name " 232 "which was registered with DBG_NAME() must be passed to the macros.\n", 233 "\n", 234 "Resources\n", 235 "In case of resource errors an error dialog is produced before the " 236 "exception handler is called.\n", 237 "\n", 238 "Dialog\n", 239 "FixedTexts, CheckBoxes, TriStateBoxes and RadioButtons are equiped with " 240 "a different background color to determine the size of the controls. This " 241 "test also shows whether controls overlap, whether the tab order is correct " 242 "and whether the mnemonic characters are correctly assigned. With dialogs " 243 "it is indicated when no default button or no OK/CancelButton is present. " 244 "These tests are not 100% correct (e.g. too many warnings are given) and " 245 "do not form any guarantee that all problematic cases are covered. For " 246 "example only initial and only visible controls are tested. No errors are " 247 "found which will occur during the use of a dialog.\n", 248 "\n", 249 "Bold AppFont\n", 250 "The application font is set to bold to see if the position of texts is " 251 "sufficient for other systems or other system settings. With very narrow " 252 "fonts the dialogs are made wider because they otherwise appear too narrow.\n", 253 "\n", 254 "Trace output\n", 255 "DBG_TRACE() can be use to produce TRACE output. DBG_TRACEFILE() also outputs " 256 "the file and line number where the macro is located. DBG_TRACE1() to " 257 "DBG_TRACE5() can be used to produce formatted output (printf format string) " 258 "Trace output is enabled when the corresponding option is selected in the " 259 "dropdown list.\n" 260 "\n", 261 "Warnings\n", 262 "DBG_WARNING() can be used to output warnings. DBG_WARNINGFILE() also outputs " 263 "the file and the line number where the macro is located. DBG_WARNING1() to " 264 "DBG_WARNING5() can be used to produce formatted output (printf format string). " 265 "In case you want to have conditional warnings DBG_ASSERTWARNING() can be " 266 "used. The warning will be produced if the condition was not met. The first " 267 "parameter is the condition and the second parameter is the message to be " 268 "produced. Warnings are enabled if the corresponding option is selected in the " 269 "dropdown box. When none are selected the condition with DBG_ASSERTWARNING() " 270 "is not evaluated.\n", 271 "\n", 272 "Errors\n", 273 "DBG_ERROR() can be used to produce error messages. DBG_ERRORFILE() also " 274 "produces the file and the line number where the macro is located. " 275 "DBG_ERROR1() bis DBG_ERROR5() can be used to produce formatted output " 276 "(print format string). " 277 "In case you want to have conditional warnings DBG_ASSERT() can be " 278 "used. The warning will be produced if the condition was not met. The first " 279 "parameter is the condition and the second parameter is the message to be " 280 "produced. Warnings are enabled if the corresponding option is selected in the " 281 "dropdown box. When none are selected the condition with DBG_ASSERT() " 282 "is not evaluated.\n", 283 "\n", 284 "\n", 285 "Output\n", 286 "------------------------------------------\n", 287 "\n", 288 "Overwrite - CheckBox\n", 289 "With every new program start the log file is overwritten if output has been " 290 "generated.\n", 291 "\n", 292 "Include ObjectTest filters\n", 293 "Only classes which contain one of the indicated filters are evaluated with " 294 "the object test. Filters are seperated by ';' and are case sensitive. " 295 "Wildcards are not supported. If no text is indicated the filters are not " 296 "active.\n", 297 "\n", 298 "Exclude ObjectTest filters\n", 299 "Only classes which do not contain one of the indicated filters are evaluated " 300 "with the object test. Filters are seperated by ';' and are case sensitive. " 301 "Wildcards are not supported. If no text is indicated the filters are not " 302 "active.\n", 303 "\n", 304 "Include filters\n", 305 "Only those texts which include the indicated filters are output. " 306 "Filters are seperated by ';' and are case sensitive. " 307 "Wildcards are not supported. The filter is used for all output (except for " 308 "errors). If no text is indicated the filters are not active.\n", 309 "\n", 310 "Exclude filters\n", 311 "Only those texts which do not include the indicated filters are output. " 312 "Filters are seperated by ';' and are case sensitive. " 313 "Wildcards are not supported. The filter is used for all output (except for " 314 "errors). If no text is indicated the filters are not active.\n", 315 "\n", 316 "Furthermore you can indicate where the data will be output:\n", 317 "\n", 318 "None\n", 319 "Output is surpressed.\n", 320 "\n", 321 "File\n", 322 "Outputi n debug file. Filename can be entered in the Editfield.\n", 323 "\n", 324 "Window\n", 325 "Output to a small debug window. The window size is stored if the debug " 326 "dialog is closed with OK and if the window is visible. Each assertion text can " 327 "be copied to the clipboard via the context menu of the respective entry.\n", 328 "\n", 329 "Shell\n", 330 "Output to a debug system (Windows debug window) when available or under " 331 "Unix in the shell window. Otherwise the same as Window.\n", 332 "\n", 333 "MessageBox\n", 334 "Output to a MessageBox. In this case you can select whether the program " 335 "must be continued, terminated (Application::Abort) or interrupted with " 336 "CoreDump. Additionally on some systems you get a \"Copy\" button pressing which " 337 "copies the text of the MessageBox to the clipboard. Because a MessageBox allows " 338 "further event processing other errors caused by Paint, Activate/Deactivate, " 339 "GetFocus/LoseFocus can cause more errors or incorrect errors and messages. " 340 "Therefor the message should also be directed to a file/debugger in case of " 341 "problems in order to produce the (right) error messages.\n", 342 "\n", 343 "TestTool\n", 344 "When the TestTool runs messages will be redirected inside the TestTool.\n", 345 "\n", 346 "Debugger\n", 347 "Attempt to activate the debugger and produce the message there, in order to " 348 "always obtain the corresponding stack trace in the debugger.\n", 349 "\n", 350 "Abort\n", 351 "Aborts the application\n", 352 "\n", 353 "\n", 354 "Reroute osl messages - Checkbox\n", 355 "OSL_ASSERT and similar messages can be intercepted by the general DBG GUI\n", 356 "or handled system specific as per normal handling in the sal library.\n", 357 "default is to reroute osl assertions\n", 358 "\n", 359 "\n", 360 "Settings\n", 361 "------------------------------------------\n", 362 "\n", 363 "Where by default the INI and LOG file is read and written the following " 364 "can be set:\n", 365 "\n", 366 "WIN/WNT (WIN.INI, Group SV, Default: dbgsv.ini and dbgsv.log):\n", 367 "INI: dbgsv\n", 368 "LOG: dbgsvlog\n", 369 "\n", 370 "OS2 (OS2.INI, Application SV, Default: dbgsv.ini and dbgsv.log):\n", 371 "INI: DBGSV\n", 372 "LOG: DBGSVLOG\n", 373 "\n", 374 "UNIX (Environment variable, Default: .dbgsv.init and dbgsv.log):\n", 375 "INI: DBGSV_INIT\n", 376 "LOG: DBGSV_LOG\n", 377 "\n", 378 "MAC (Default: dbgsv.ini and dbgsv.log):\n", 379 "INI: not possible\n", 380 "LOG: only debug dialog settings\n", 381 "\n", 382 "The path and file name must always be specified. The name of the log " 383 "file that was entered in the debug dialog has always priority.\n", 384 "\n", 385 "\n", 386 "Example\n", 387 "------------------------------------------\n", 388 "\n", 389 "DBG_NAME( String );\n", 390 "\n", 391 "#ifdef DBG_UTIL\n", 392 "const sal_Char* DbgCheckString( const void* pString )\n", 393 "{\n", 394 " String* p = (String*)pString;\n", 395 "\n", 396 " if ( p->mpData->maStr[p->mpData->mnLen] != 0 )\n", 397 " return \"String damaged: aStr[nLen] != 0\";\n", 398 "\n", 399 " return NULL;\n", 400 "}\n", 401 "#endif\n", 402 "\n", 403 "String::String()\n", 404 "{\n", 405 " DBG_CTOR( String, DbgCheckString );\n", 406 " // ...\n", 407 "}\n", 408 "\n", 409 "String::~String()\n", 410 "{\n", 411 " DBG_DTOR( String, DbgCheckString );\n", 412 " //...\n", 413 "}\n", 414 "\n", 415 "char& String::operator [] ( sal_uInt16 nIndex )\n", 416 "{\n", 417 " DBG_CHKTHIS( String, DbgCheckString );\n", 418 " DBG_ASSERT( nIndex <= pData->nLen, \"String::[] : nIndex > Len\" );\n", 419 "\n", 420 " //...\n", 421 "}\n", 422 "\n", 423 "sal_uInt16 String::Search( const String& rStr, sal_uInt16 nIndex ) const\n", 424 "{\n", 425 " DBG_CHKTHIS( String, DbgCheckString );\n", 426 " DBG_CHKOBJ( &rStr, String, DbgCheckString );\n", 427 "\n", 428 " //...\n", 429 "}", 430 "\n", 431 NULL 432 }; 433 434 // ======================================================================= 435 436 namespace 437 { 438 // ------------------------------------------------------------------- 439 typedef ::std::map< XubString, DbgChannelId > UserDefinedChannels; 440 UserDefinedChannels& ImplDbgGetUserDefinedChannels() 441 { 442 static UserDefinedChannels s_aChannels; 443 return s_aChannels; 444 } 445 446 // ------------------------------------------------------------------- 447 void ImplAppendUserDefinedChannels( ListBox& rList ) 448 { 449 const UserDefinedChannels& rChannels = ImplDbgGetUserDefinedChannels(); 450 for ( UserDefinedChannels::const_iterator channel = rChannels.begin(); 451 channel != rChannels.end(); 452 ++channel 453 ) 454 { 455 sal_uInt16 nEntryPos = rList.InsertEntry( channel->first ); 456 rList.SetEntryData( nEntryPos, reinterpret_cast< void* >( channel->second ) ); 457 } 458 } 459 460 // ------------------------------------------------------------------- 461 void ImplSelectChannel( ListBox& rList, sal_uLong nChannelToSelect, sal_uInt16 nPositionOffset ) 462 { 463 if ( nChannelToSelect < DBG_OUT_USER_CHANNEL_0 ) 464 rList.SelectEntryPos( (sal_uInt16)( nChannelToSelect - nPositionOffset ) ); 465 else 466 { 467 for ( sal_uInt16 pos = 0; pos < rList.GetEntryCount(); ++pos ) 468 { 469 DbgChannelId nChannelId = static_cast< DbgChannelId >( reinterpret_cast<sal_IntPtr>(rList.GetEntryData( pos )) ); 470 if ( nChannelId == nChannelToSelect ) 471 { 472 rList.SelectEntryPos( pos ); 473 return; 474 } 475 } 476 } 477 } 478 // ------------------------------------------------------------------- 479 DbgChannelId ImplGetChannelId( const ListBox& rList, sal_uInt16 nPositionOffset ) 480 { 481 sal_uInt16 nSelectedChannelPos = rList.GetSelectEntryPos(); 482 DbgChannelId nSelectedChannel = static_cast< DbgChannelId >( reinterpret_cast<sal_IntPtr>(rList.GetEntryData( nSelectedChannelPos )) ); 483 if ( nSelectedChannel == 0) 484 return (DbgChannelId)( nSelectedChannelPos + nPositionOffset ); 485 return nSelectedChannel; 486 } 487 } 488 489 // ======================================================================= 490 491 // ------------- 492 // - DbgWindow - 493 // ------------- 494 495 #define DBGWIN_MAXLINES 100 496 497 class DbgWindow : public WorkWindow 498 { 499 private: 500 ListBox maLstBox; 501 502 public: 503 DbgWindow(); 504 505 virtual sal_Bool Close(); 506 virtual void Resize(); 507 virtual long PreNotify( NotifyEvent& rNEvt ); 508 void InsertLine( const XubString& rLine ); 509 void Update() { WorkWindow::Update(); maLstBox.Update(); } 510 511 private: 512 void GetAssertionEntryRange( sal_uInt16 nInbetweenEntry, sal_uInt16& nFirst, sal_uInt16& nLast ); 513 }; 514 515 // ----------------- 516 // - DbgInfoDialog - 517 // ----------------- 518 519 class DbgInfoDialog : public ModalDialog 520 { 521 private: 522 ListBox maListBox; 523 OKButton maOKButton; 524 sal_Bool mbHelpText; 525 526 public: 527 DbgInfoDialog( Window* pParent, sal_Bool bHelpText = sal_False ); 528 529 void SetInfoText( const XubString& rStr ); 530 }; 531 532 // ------------- 533 // - DbgDialog - 534 // ------------- 535 536 class DbgDialog : public ModalDialog 537 { 538 private: 539 CheckBox maXtorThis; 540 CheckBox maXtorFunc; 541 CheckBox maXtorExit; 542 CheckBox maXtorReport; 543 CheckBox maXtorTrace; 544 GroupBox maBox1; 545 546 CheckBox maMemInit; 547 CheckBox maMemOverwrite; 548 CheckBox maMemOverwriteFree; 549 CheckBox maMemPtr; 550 CheckBox maMemReport; 551 CheckBox maMemTrace; 552 CheckBox maMemLeakReport; 553 CheckBox maMemNewDel; 554 CheckBox maMemXtor; 555 GroupBox maBox2; 556 557 CheckBox maProf; 558 CheckBox maRes; 559 CheckBox maDialog; 560 CheckBox maBoldAppFont; 561 GroupBox maBox3; 562 563 Edit maDebugName; 564 CheckBox maOverwrite; 565 FixedText maInclClassText; 566 Edit maInclClassFilter; 567 FixedText maExclClassText; 568 Edit maExclClassFilter; 569 FixedText maInclText; 570 Edit maInclFilter; 571 FixedText maExclText; 572 Edit maExclFilter; 573 FixedText maTraceText; 574 ListBox maTraceBox; 575 FixedText maWarningText; 576 ListBox maWarningBox; 577 FixedText maErrorText; 578 ListBox maErrorBox; 579 CheckBox maHookOSLBox; 580 GroupBox maBox4; 581 582 OKButton maOKButton; 583 CancelButton maCancelButton; 584 PushButton maInfoButton; 585 HelpButton maHelpButton; 586 sal_uInt16 mnErrorOff; 587 588 public: 589 DbgDialog(); 590 591 DECL_LINK( ClickHdl, Button* ); 592 void RequestHelp( const HelpEvent& rHEvt ); 593 }; 594 595 // ======================================================================= 596 597 static sal_Char aDbgInfoBuf[12288]; 598 static sal_Char aDbgOutBuf[DBG_BUF_MAXLEN]; 599 600 // ======================================================================= 601 602 DbgWindow::DbgWindow() : 603 WorkWindow( NULL, WB_STDWORK ), 604 maLstBox( this, WB_AUTOHSCROLL ) 605 { 606 DbgData* pData = DbgGetData(); 607 608 maLstBox.Show(); 609 maLstBox.SetPosPixel( Point( 0, 0 ) ); 610 611 SetOutputSizePixel( Size( 600, 480 ) ); 612 if ( pData->aDbgWinState ) 613 { 614 ByteString aState( pData->aDbgWinState ); 615 SetWindowState( aState ); 616 } 617 618 SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "StarView Debug Window" ) ) ); 619 Show(); 620 Update(); 621 } 622 623 // ----------------------------------------------------------------------- 624 625 sal_Bool DbgWindow::Close() 626 { 627 // remember window position 628 ByteString aState( GetWindowState() ); 629 DbgData* pData = DbgGetData(); 630 size_t nCopy = (sizeof( pData->aDbgWinState ) < size_t(aState.Len() + 1U )) 631 ? sizeof( pData->aDbgWinState ) : size_t(aState.Len() + 1U ); 632 strncpy( pData->aDbgWinState, aState.GetBuffer(), nCopy ); 633 pData->aDbgWinState[ sizeof( pData->aDbgWinState ) - 1 ] = 0; 634 // and save for next session 635 DbgSaveData( *pData ); 636 637 delete this; 638 ImplGetSVData()->maWinData.mpDbgWin = NULL; 639 return sal_True; 640 } 641 642 // ----------------------------------------------------------------------- 643 644 void DbgWindow::Resize() 645 { 646 maLstBox.SetSizePixel( GetOutputSizePixel() ); 647 } 648 649 // ----------------------------------------------------------------------- 650 651 void DbgWindow::GetAssertionEntryRange( sal_uInt16 nInbetweenEntry, sal_uInt16& nFirst, sal_uInt16& nLast ) 652 { 653 nFirst = nInbetweenEntry; 654 while ( nFirst > 0 ) 655 { 656 if ( maLstBox.GetEntryData( nFirst ) != NULL ) 657 break; 658 --nFirst; 659 } 660 sal_uInt16 nEntryCount = maLstBox.GetEntryCount(); 661 nLast = nInbetweenEntry + 1; 662 while ( nLast < nEntryCount ) 663 { 664 if ( maLstBox.GetEntryData( nLast ) != NULL ) 665 break; 666 ++nLast; 667 } 668 } 669 670 // ----------------------------------------------------------------------- 671 672 long DbgWindow::PreNotify( NotifyEvent& rNEvt ) 673 { 674 if ( rNEvt.GetType() == EVENT_COMMAND ) 675 { 676 if ( maLstBox.IsWindowOrChild( rNEvt.GetWindow() ) ) 677 { 678 const CommandEvent& rCommand = *rNEvt.GetCommandEvent(); 679 if ( rCommand.GetCommand() == COMMAND_CONTEXTMENU ) 680 { 681 PopupMenu aMenu; 682 aMenu.InsertItem( 1, String::CreateFromAscii( "copy to clipboard" ) ); 683 684 Point aPos; 685 if ( rCommand.IsMouseEvent() ) 686 aPos = rCommand.GetMousePosPixel(); 687 else 688 { 689 Rectangle aEntryRect( maLstBox.GetBoundingRectangle( maLstBox.GetSelectEntryPos() ) ); 690 aPos = aEntryRect.Center(); 691 } 692 sal_uInt16 nSelected = aMenu.Execute( rNEvt.GetWindow(), aPos ); 693 if ( nSelected == 1 ) 694 { 695 // search all entries which belong to this assertion 696 sal_uInt16 nAssertionFirst = 0; 697 sal_uInt16 nAssertionLast = 0; 698 GetAssertionEntryRange( maLstBox.GetSelectEntryPos(), nAssertionFirst, nAssertionLast ); 699 700 // build the string to copy to the clipboard 701 String sAssertion; 702 String sLineFeed = String::CreateFromAscii( "\n" ); 703 sLineFeed.ConvertLineEnd( GetSystemLineEnd() ); 704 while ( nAssertionFirst < nAssertionLast ) 705 { 706 sAssertion += maLstBox.GetEntry( nAssertionFirst++ ); 707 sAssertion += sLineFeed; 708 } 709 710 ::vcl::unohelper::TextDataObject::CopyStringTo( sAssertion, GetClipboard() ); 711 } 712 } 713 return 1; // handled 714 } 715 } 716 return WorkWindow::PreNotify( rNEvt ); 717 } 718 719 // ----------------------------------------------------------------------- 720 721 void DbgWindow::InsertLine( const XubString& rLine ) 722 { 723 XubString aStr = rLine; 724 aStr.ConvertLineEnd( LINEEND_LF ); 725 xub_StrLen nPos = aStr.Search( _LF ); 726 sal_Bool bFirstEntry = sal_True; 727 while ( nPos != STRING_NOTFOUND ) 728 { 729 if ( maLstBox.GetEntryCount() >= DBGWIN_MAXLINES ) 730 maLstBox.RemoveEntry( 0 ); 731 732 sal_uInt16 nInsertionPos = maLstBox.InsertEntry( aStr.Copy( 0, nPos ) ); 733 if ( bFirstEntry ) 734 maLstBox.SetEntryData( nInsertionPos, reinterpret_cast< void* >( 0x00000001 ) ); 735 bFirstEntry = sal_False; 736 737 aStr.Erase( 0, nPos+1 ); 738 nPos = aStr.Search( _LF ); 739 } 740 if ( maLstBox.GetEntryCount() >= DBGWIN_MAXLINES ) 741 maLstBox.RemoveEntry( 0 ); 742 sal_uInt16 nInsertionPos = maLstBox.InsertEntry( aStr ); 743 if ( bFirstEntry ) 744 maLstBox.SetEntryData( nInsertionPos, reinterpret_cast< void* >( 0x00000001 ) ); 745 maLstBox.SetTopEntry( DBGWIN_MAXLINES-1 ); 746 maLstBox.Update(); 747 } 748 749 // ======================================================================= 750 751 DbgDialog::DbgDialog() : 752 ModalDialog( NULL, WB_STDMODAL | WB_SYSTEMWINDOW ), 753 maXtorThis( this ), 754 maXtorFunc( this ), 755 maXtorExit( this ), 756 maXtorReport( this ), 757 maXtorTrace( this ), 758 maBox1( this ), 759 maMemInit( this ), 760 maMemOverwrite( this ), 761 maMemOverwriteFree( this ), 762 maMemPtr( this ), 763 maMemReport( this ), 764 maMemTrace( this ), 765 maMemLeakReport( this ), 766 maMemNewDel( this ), 767 maMemXtor( this ), 768 maBox2( this ), 769 maProf( this ), 770 maRes( this ), 771 maDialog( this ), 772 maBoldAppFont( this ), 773 maBox3( this ), 774 maDebugName( this ), 775 maOverwrite( this ), 776 maInclClassText( this ), 777 maInclClassFilter( this ), 778 maExclClassText( this ), 779 maExclClassFilter( this ), 780 maInclText( this ), 781 maInclFilter( this ), 782 maExclText( this ), 783 maExclFilter( this ), 784 maTraceText( this ), 785 maTraceBox( this, WB_DROPDOWN ), 786 maWarningText( this ), 787 maWarningBox( this, WB_DROPDOWN ), 788 maErrorText( this ), 789 maErrorBox( this, WB_DROPDOWN ), 790 maHookOSLBox( this ), 791 maBox4( this ), 792 maOKButton( this, WB_DEFBUTTON ), 793 maCancelButton( this ), 794 maInfoButton( this ), 795 maHelpButton( this ) 796 { 797 DbgData* pData = DbgGetData(); 798 MapMode aAppMap( MAP_APPFONT ); 799 Size aButtonSize = LogicToPixel( Size( 60, 12 ), aAppMap ); 800 801 { 802 maXtorThis.Show(); 803 maXtorThis.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "T~his" ) ) ); 804 if ( pData->nTestFlags & DBG_TEST_XTOR_THIS ) 805 maXtorThis.Check( sal_True ); 806 maXtorThis.SetPosSizePixel( LogicToPixel( Point( 10, 15 ), aAppMap ), 807 aButtonSize ); 808 } 809 810 { 811 maXtorFunc.Show(); 812 maXtorFunc.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Function" ) ) ); 813 if ( pData->nTestFlags & DBG_TEST_XTOR_FUNC ) 814 maXtorFunc.Check( sal_True ); 815 maXtorFunc.SetPosSizePixel( LogicToPixel( Point( 75, 15 ), aAppMap ), 816 aButtonSize ); 817 } 818 819 { 820 maXtorExit.Show(); 821 maXtorExit.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "E~xit" ) ) ); 822 if ( pData->nTestFlags & DBG_TEST_XTOR_EXIT ) 823 maXtorExit.Check( sal_True ); 824 maXtorExit.SetPosSizePixel( LogicToPixel( Point( 140, 15 ), aAppMap ), 825 aButtonSize ); 826 } 827 828 { 829 maXtorReport.Show(); 830 maXtorReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Report" ) ) ); 831 if ( pData->nTestFlags & DBG_TEST_XTOR_REPORT ) 832 maXtorReport.Check( sal_True ); 833 maXtorReport.SetPosSizePixel( LogicToPixel( Point( 205, 15 ), aAppMap ), 834 aButtonSize ); 835 } 836 837 { 838 maXtorTrace.Show(); 839 maXtorTrace.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) ); 840 if ( pData->nTestFlags & DBG_TEST_XTOR_TRACE ) 841 maXtorTrace.Check( sal_True ); 842 maXtorTrace.SetPosSizePixel( LogicToPixel( Point( 270, 15 ), aAppMap ), 843 aButtonSize ); 844 } 845 846 { 847 maBox1.Show(); 848 maBox1.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Object Tests" ) ) ); 849 maBox1.SetPosSizePixel( LogicToPixel( Point( 5, 5 ), aAppMap ), 850 LogicToPixel( Size( 330, 30 ), aAppMap ) ); 851 } 852 853 { 854 maMemInit.Show(); 855 maMemInit.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Initialize" ) ) ); 856 if ( pData->nTestFlags & DBG_TEST_MEM_INIT ) 857 maMemInit.Check( sal_True ); 858 maMemInit.SetPosSizePixel( LogicToPixel( Point( 10, 50 ), aAppMap ), 859 aButtonSize ); 860 } 861 862 { 863 maMemOverwrite.Show(); 864 maMemOverwrite.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Overwrite" )) ); 865 if ( pData->nTestFlags & DBG_TEST_MEM_OVERWRITE ) 866 maMemOverwrite.Check( sal_True ); 867 maMemOverwrite.SetPosSizePixel( LogicToPixel( Point( 75, 50 ), aAppMap ), 868 aButtonSize ); 869 } 870 871 { 872 maMemOverwriteFree.Show(); 873 maMemOverwriteFree.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Free" ) ) ); 874 if ( pData->nTestFlags & DBG_TEST_MEM_OVERWRITEFREE ) 875 maMemOverwriteFree.Check( sal_True ); 876 maMemOverwriteFree.SetPosSizePixel( LogicToPixel( Point( 140, 50 ), aAppMap ), 877 aButtonSize ); 878 } 879 880 { 881 maMemPtr.Show(); 882 maMemPtr.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Pointer" ) ) ); 883 if ( pData->nTestFlags & DBG_TEST_MEM_POINTER ) 884 maMemPtr.Check( sal_True ); 885 maMemPtr.SetPosSizePixel( LogicToPixel( Point( 205, 50 ), aAppMap ), 886 aButtonSize ); 887 } 888 889 { 890 maMemReport.Show(); 891 maMemReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Report" ) ) ); 892 if ( pData->nTestFlags & DBG_TEST_MEM_REPORT ) 893 maMemReport.Check( sal_True ); 894 maMemReport.SetPosSizePixel( LogicToPixel( Point( 270, 50 ), aAppMap ), 895 aButtonSize ); 896 } 897 898 { 899 maMemTrace.Show(); 900 maMemTrace.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) ); 901 if ( pData->nTestFlags & DBG_TEST_MEM_TRACE ) 902 maMemTrace.Check( sal_True ); 903 maMemTrace.SetPosSizePixel( LogicToPixel( Point( 10, 65 ), aAppMap ), 904 aButtonSize ); 905 } 906 907 { 908 maMemLeakReport.Show(); 909 maMemLeakReport.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Leak-Report" ) ) ); 910 if ( pData->nTestFlags & DBG_TEST_MEM_LEAKREPORT ) 911 maMemLeakReport.Check( sal_True ); 912 maMemLeakReport.SetPosSizePixel( LogicToPixel( Point( 75, 65 ), aAppMap ), 913 aButtonSize ); 914 } 915 916 { 917 maMemNewDel.Show(); 918 maMemNewDel.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~New/Delete" ) ) ); 919 if ( pData->nTestFlags & DBG_TEST_MEM_NEWDEL ) 920 maMemNewDel.Check( sal_True ); 921 maMemNewDel.SetPosSizePixel( LogicToPixel( Point( 140, 65 ), aAppMap ), 922 aButtonSize ); 923 } 924 925 { 926 maMemXtor.Show(); 927 maMemXtor.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Ob~ject Test" ) ) ); 928 if ( pData->nTestFlags & DBG_TEST_MEM_XTOR ) 929 maMemXtor.Check( sal_True ); 930 maMemXtor.SetPosSizePixel( LogicToPixel( Point( 205, 65 ), aAppMap ), 931 aButtonSize ); 932 } 933 934 { 935 maBox2.Show(); 936 maBox2.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Memory Tests" ) ) ); 937 maBox2.SetPosSizePixel( LogicToPixel( Point( 5, 40 ), aAppMap ), 938 LogicToPixel( Size( 330, 40 ), aAppMap ) ); 939 } 940 941 { 942 maProf.Show(); 943 maProf.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Profiling" ) ) ); 944 if ( pData->nTestFlags & DBG_TEST_PROFILING ) 945 maProf.Check( sal_True ); 946 maProf.SetPosSizePixel( LogicToPixel( Point( 10, 95 ), aAppMap ), 947 aButtonSize ); 948 } 949 950 { 951 maRes.Show(); 952 maRes.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Resourcen" ) ) ); 953 if ( pData->nTestFlags & DBG_TEST_RESOURCE ) 954 maRes.Check( sal_True ); 955 maRes.SetPosSizePixel( LogicToPixel( Point( 75, 95 ), aAppMap ), 956 aButtonSize ); 957 } 958 959 { 960 maDialog.Show(); 961 maDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Dialog" ) ) ); 962 if ( pData->nTestFlags & DBG_TEST_DIALOG ) 963 maDialog.Check( sal_True ); 964 maDialog.SetPosSizePixel( LogicToPixel( Point( 140, 95 ), aAppMap ), 965 aButtonSize ); 966 } 967 968 { 969 maBoldAppFont.Show(); 970 maBoldAppFont.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Bold AppFont" ) ) ); 971 if ( pData->nTestFlags & DBG_TEST_BOLDAPPFONT ) 972 maBoldAppFont.Check( sal_True ); 973 maBoldAppFont.SetPosSizePixel( LogicToPixel( Point( 205, 95 ), aAppMap ), 974 aButtonSize ); 975 maBoldAppFont.SaveValue(); 976 } 977 978 { 979 maBox3.Show(); 980 maBox3.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Test Options" ) ) ); 981 maBox3.SetPosSizePixel( LogicToPixel( Point( 5, 85 ), aAppMap ), 982 LogicToPixel( Size( 330, 30 ), aAppMap ) ); 983 } 984 985 { 986 maDebugName.Show(); 987 maDebugName.SetText( XubString( pData->aDebugName, RTL_TEXTENCODING_UTF8 ) ); 988 maDebugName.SetMaxTextLen( sizeof( pData->aDebugName ) ); 989 maDebugName.SetPosSizePixel( LogicToPixel( Point( 10, 130 ), aAppMap ), 990 LogicToPixel( Size( 185, 14 ), aAppMap ) ); 991 } 992 993 { 994 maOverwrite.Show(); 995 maOverwrite.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Overwrite ~File" ) ) ); 996 if ( pData->bOverwrite ) 997 maOverwrite.Check( sal_True ); 998 maOverwrite.SetPosSizePixel( LogicToPixel( Point( 205, 130 ), aAppMap ), 999 aButtonSize ); 1000 } 1001 1002 { 1003 maHookOSLBox.Show(); 1004 maHookOSLBox.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Reroute osl debug ~messages" ) ) ); 1005 if ( pData->bHookOSLAssert ) 1006 maHookOSLBox.Check( sal_True ); 1007 maHookOSLBox.SetPosSizePixel( LogicToPixel( Point( 10, 240 ), aAppMap ), 1008 LogicToPixel( Size( 100, 12 ), aAppMap ) ); 1009 } 1010 1011 { 1012 maInclClassText.Show(); 1013 maInclClassText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Include-ObjectTest-Filter" ) ) ); 1014 maInclClassText.SetPosSizePixel( LogicToPixel( Point( 10, 150 ), aAppMap ), 1015 LogicToPixel( Size( 95, 9 ), aAppMap ) ); 1016 } 1017 1018 { 1019 maInclClassFilter.Show(); 1020 maInclClassFilter.SetText( XubString( pData->aInclClassFilter, RTL_TEXTENCODING_UTF8 ) ); 1021 maInclClassFilter.SetMaxTextLen( sizeof( pData->aInclClassFilter ) ); 1022 maInclClassFilter.SetPosSizePixel( LogicToPixel( Point( 10, 160 ), aAppMap ), 1023 LogicToPixel( Size( 95, 14 ), aAppMap ) ); 1024 } 1025 1026 { 1027 maExclClassText.Show(); 1028 maExclClassText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Exclude-ObjectTest-Filter" ) ) ); 1029 maExclClassText.SetPosSizePixel( LogicToPixel( Point( 115, 150 ), aAppMap ), 1030 LogicToPixel( Size( 95, 9 ), aAppMap ) ); 1031 } 1032 1033 { 1034 maExclClassFilter.Show(); 1035 maExclClassFilter.SetText( XubString( pData->aExclClassFilter, RTL_TEXTENCODING_UTF8 ) ); 1036 maExclClassFilter.SetMaxTextLen( sizeof( pData->aExclClassFilter ) ); 1037 maExclClassFilter.SetPosSizePixel( LogicToPixel( Point( 115, 160 ), aAppMap ), 1038 LogicToPixel( Size( 95, 14 ), aAppMap ) ); 1039 } 1040 1041 { 1042 maInclText.Show(); 1043 maInclText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Include-Filter" ) ) ); 1044 maInclText.SetPosSizePixel( LogicToPixel( Point( 10, 180 ), aAppMap ), 1045 LogicToPixel( Size( 95, 9 ), aAppMap ) ); 1046 } 1047 1048 { 1049 maInclFilter.Show(); 1050 maInclFilter.SetText( XubString( pData->aInclFilter, RTL_TEXTENCODING_UTF8 ) ); 1051 maInclFilter.SetMaxTextLen( sizeof( pData->aInclFilter ) ); 1052 maInclFilter.SetPosSizePixel( LogicToPixel( Point( 10, 190 ), aAppMap ), 1053 LogicToPixel( Size( 95, 14 ), aAppMap ) ); 1054 } 1055 1056 { 1057 maExclText.Show(); 1058 maExclText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Exclude-Filter" ) ) ); 1059 maExclText.SetPosSizePixel( LogicToPixel( Point( 115, 180 ), aAppMap ), 1060 LogicToPixel( Size( 95, 9 ), aAppMap ) ); 1061 } 1062 1063 { 1064 maExclFilter.Show(); 1065 maExclFilter.SetText( XubString( pData->aExclFilter, RTL_TEXTENCODING_UTF8 ) ); 1066 maExclFilter.SetMaxTextLen( sizeof( pData->aExclFilter ) ); 1067 maExclFilter.SetPosSizePixel( LogicToPixel( Point( 115, 190 ), aAppMap ), 1068 LogicToPixel( Size( 95, 14 ), aAppMap ) ); 1069 } 1070 1071 { 1072 maTraceText.Show(); 1073 maTraceText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Trace" ) ) ); 1074 maTraceText.SetPosSizePixel( LogicToPixel( Point( 10, 210 ), aAppMap ), 1075 LogicToPixel( Size( 95, 9 ), aAppMap ) ); 1076 } 1077 1078 { 1079 maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) ); 1080 maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) ); 1081 maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) ); 1082 maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) ); 1083 maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) ); 1084 maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) ); 1085 maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) ); 1086 maTraceBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Abort" ) ) ); 1087 ImplAppendUserDefinedChannels( maTraceBox ); 1088 ImplSelectChannel( maTraceBox, pData->nTraceOut, 0 ); 1089 maTraceBox.Show(); 1090 maTraceBox.SetPosSizePixel( LogicToPixel( Point( 10, 220 ), aAppMap ), 1091 LogicToPixel( Size( 95, 80 ), aAppMap ) ); 1092 } 1093 1094 { 1095 maWarningText.Show(); 1096 maWarningText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Warning" ) ) ); 1097 maWarningText.SetPosSizePixel( LogicToPixel( Point( 115, 210 ), aAppMap ), 1098 LogicToPixel( Size( 95, 9 ), aAppMap ) ); 1099 } 1100 1101 { 1102 maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) ); 1103 maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) ); 1104 maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) ); 1105 maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) ); 1106 maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) ); 1107 maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) ); 1108 maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) ); 1109 maWarningBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Abort" ) ) ); 1110 ImplAppendUserDefinedChannels( maWarningBox ); 1111 ImplSelectChannel( maWarningBox, pData->nWarningOut, 0 ); 1112 maWarningBox.Show(); 1113 maWarningBox.SetPosSizePixel( LogicToPixel( Point( 115, 220 ), aAppMap ), 1114 LogicToPixel( Size( 95, 80 ), aAppMap ) ); 1115 } 1116 1117 { 1118 maErrorText.Show(); 1119 maErrorText.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Error" ) ) ); 1120 maErrorText.SetPosSizePixel( LogicToPixel( Point( 220, 210 ), aAppMap ), 1121 LogicToPixel( Size( 95, 9 ), aAppMap ) ); 1122 } 1123 1124 { 1125 if ( DbgIsAllErrorOut() ) 1126 { 1127 maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) ); 1128 maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "File" ) ) ); 1129 maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Window" ) ) ); 1130 maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Shell" ) ) ); 1131 mnErrorOff = 0; 1132 } 1133 else 1134 mnErrorOff = 4; 1135 maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "MessageBox" ) ) ); 1136 maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "TestTool" ) ) ); 1137 maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debugger" ) ) ); 1138 maErrorBox.InsertEntry( XubString( RTL_CONSTASCII_USTRINGPARAM( "Abort" ) ) ); 1139 ImplAppendUserDefinedChannels( maErrorBox ); 1140 ImplSelectChannel( maErrorBox, pData->nErrorOut, mnErrorOff ); 1141 maErrorBox.Show(); 1142 maErrorBox.SetPosSizePixel( LogicToPixel( Point( 220, 220 ), aAppMap ), 1143 LogicToPixel( Size( 95, 80 ), aAppMap ) ); 1144 } 1145 1146 { 1147 maBox4.Show(); 1148 maBox4.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Output" ) ) ); 1149 maBox4.SetPosSizePixel( LogicToPixel( Point( 5, 120 ), aAppMap ), 1150 LogicToPixel( Size( 330, 135 ), aAppMap ) ); 1151 } 1152 1153 { 1154 maOKButton.Show(); 1155 maOKButton.SetClickHdl( LINK( this, DbgDialog, ClickHdl ) ); 1156 maOKButton.SetPosSizePixel( LogicToPixel( Point( 10, 260 ), aAppMap ), 1157 LogicToPixel( Size( 50, 15 ), aAppMap ) ); 1158 } 1159 { 1160 maCancelButton.Show(); 1161 maCancelButton.SetPosSizePixel( LogicToPixel( Point( 70, 260 ), aAppMap ), 1162 LogicToPixel( Size( 50, 15 ), aAppMap ) ); 1163 } 1164 { 1165 maInfoButton.Show(); 1166 maInfoButton.SetClickHdl( LINK( this, DbgDialog, ClickHdl ) ); 1167 maInfoButton.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "~Info..." ) ) ); 1168 maInfoButton.SetPosSizePixel( LogicToPixel( Point( 130, 260 ), aAppMap ), 1169 LogicToPixel( Size( 50, 15 ), aAppMap ) ); 1170 } 1171 { 1172 maHelpButton.Show(); 1173 maHelpButton.SetPosSizePixel( LogicToPixel( Point( 190, 260 ), aAppMap ), 1174 LogicToPixel( Size( 50, 15 ), aAppMap ) ); 1175 } 1176 1177 { 1178 SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "VCL Debug Options" ) ) ); 1179 SetOutputSizePixel( LogicToPixel( Size( 340, 280 ), aAppMap ) ); 1180 } 1181 } 1182 1183 // ----------------------------------------------------------------------- 1184 1185 IMPL_LINK( DbgDialog, ClickHdl, Button*, pButton ) 1186 { 1187 if ( pButton == &maOKButton ) 1188 { 1189 DbgData aData; 1190 1191 memcpy( &aData, DbgGetData(), sizeof( DbgData ) ); 1192 aData.nTestFlags = 0; 1193 1194 aData.nTraceOut = ImplGetChannelId( maTraceBox, 0 ); 1195 aData.nWarningOut = ImplGetChannelId( maWarningBox, 0 ); 1196 aData.nErrorOut = ImplGetChannelId( maErrorBox, mnErrorOff ); 1197 1198 strncpy( aData.aDebugName, ByteString( maDebugName.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aDebugName ) ); 1199 strncpy( aData.aInclClassFilter, ByteString( maInclClassFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aInclClassFilter ) ); 1200 strncpy( aData.aExclClassFilter, ByteString( maExclClassFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aExclClassFilter ) ); 1201 strncpy( aData.aInclFilter, ByteString( maInclFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aInclFilter ) ); 1202 strncpy( aData.aExclFilter, ByteString( maExclFilter.GetText(), RTL_TEXTENCODING_UTF8 ).GetBuffer(), sizeof( aData.aExclFilter ) ); 1203 aData.aDebugName[sizeof( aData.aDebugName )-1] = '\0'; 1204 aData.aInclClassFilter[sizeof( aData.aInclClassFilter )-1] = '\0'; 1205 aData.aExclClassFilter[sizeof( aData.aExclClassFilter )-1] = '\0'; 1206 aData.aInclFilter[sizeof( aData.aInclFilter )-1] = '\0'; 1207 aData.aExclFilter[sizeof( aData.aExclFilter )-1] = '\0'; 1208 1209 aData.bOverwrite = maOverwrite.IsChecked() ? sal_True : sal_False; 1210 aData.bHookOSLAssert = maHookOSLBox.IsChecked() ? sal_True : sal_False; 1211 1212 if ( maXtorThis.IsChecked() ) 1213 aData.nTestFlags |= DBG_TEST_XTOR_THIS; 1214 1215 if ( maXtorFunc.IsChecked() ) 1216 aData.nTestFlags |= DBG_TEST_XTOR_FUNC; 1217 1218 if ( maXtorExit.IsChecked() ) 1219 aData.nTestFlags |= DBG_TEST_XTOR_EXIT; 1220 1221 if ( maXtorReport.IsChecked() ) 1222 aData.nTestFlags |= DBG_TEST_XTOR_REPORT; 1223 1224 if ( maXtorTrace.IsChecked() ) 1225 aData.nTestFlags |= DBG_TEST_XTOR_TRACE; 1226 1227 if ( maMemInit.IsChecked() ) 1228 aData.nTestFlags |= DBG_TEST_MEM_INIT; 1229 1230 if ( maMemOverwrite.IsChecked() ) 1231 aData.nTestFlags |= DBG_TEST_MEM_OVERWRITE; 1232 1233 if ( maMemOverwriteFree.IsChecked() ) 1234 aData.nTestFlags |= DBG_TEST_MEM_OVERWRITEFREE; 1235 1236 if ( maMemPtr.IsChecked() ) 1237 aData.nTestFlags |= DBG_TEST_MEM_POINTER; 1238 1239 if ( maMemReport.IsChecked() ) 1240 aData.nTestFlags |= DBG_TEST_MEM_REPORT; 1241 1242 if ( maMemTrace.IsChecked() ) 1243 aData.nTestFlags |= DBG_TEST_MEM_TRACE; 1244 1245 if ( maMemLeakReport.IsChecked() ) 1246 aData.nTestFlags |= DBG_TEST_MEM_LEAKREPORT; 1247 1248 if ( maMemNewDel.IsChecked() ) 1249 aData.nTestFlags |= DBG_TEST_MEM_NEWDEL; 1250 1251 if ( maMemXtor.IsChecked() ) 1252 aData.nTestFlags |= DBG_TEST_MEM_XTOR; 1253 1254 if ( maProf.IsChecked() ) 1255 aData.nTestFlags |= DBG_TEST_PROFILING; 1256 1257 if ( maRes.IsChecked() ) 1258 aData.nTestFlags |= DBG_TEST_RESOURCE; 1259 1260 if ( maDialog.IsChecked() ) 1261 aData.nTestFlags |= DBG_TEST_DIALOG; 1262 1263 if ( maBoldAppFont.IsChecked() ) 1264 aData.nTestFlags |= DBG_TEST_BOLDAPPFONT; 1265 1266 // Daten speichern 1267 DbgSaveData( aData ); 1268 1269 // Umschalten der Laufzeitwerte 1270 DBG_INSTOUTTRACE( aData.nTraceOut ); 1271 DBG_INSTOUTWARNING( aData.nWarningOut ); 1272 DBG_INSTOUTERROR( aData.nErrorOut ); 1273 DbgUpdateOslHook( &aData ); 1274 1275 DbgData* pData = DbgGetData(); 1276 #define IMMEDIATE_FLAGS (DBG_TEST_MEM_INIT | DBG_TEST_RESOURCE | DBG_TEST_DIALOG | DBG_TEST_BOLDAPPFONT) 1277 pData->nTestFlags &= ~IMMEDIATE_FLAGS; 1278 pData->nTestFlags |= aData.nTestFlags & IMMEDIATE_FLAGS; 1279 strncpy( pData->aInclClassFilter, aData.aInclClassFilter, sizeof( pData->aInclClassFilter ) ); 1280 strncpy( pData->aExclClassFilter, aData.aExclClassFilter, sizeof( pData->aExclClassFilter ) ); 1281 strncpy( pData->aInclFilter, aData.aInclFilter, sizeof( pData->aInclFilter ) ); 1282 strncpy( pData->aExclFilter, aData.aExclFilter, sizeof( pData->aExclFilter ) ); 1283 if ( maBoldAppFont.GetSavedValue() != maBoldAppFont.IsChecked() ) 1284 { 1285 AllSettings aSettings = Application::GetSettings(); 1286 StyleSettings aStyleSettings = aSettings.GetStyleSettings(); 1287 Font aFont = aStyleSettings.GetAppFont(); 1288 if ( maBoldAppFont.IsChecked() ) 1289 aFont.SetWeight( WEIGHT_BOLD ); 1290 else 1291 aFont.SetWeight( WEIGHT_NORMAL ); 1292 aStyleSettings.SetAppFont( aFont ); 1293 aSettings.SetStyleSettings( aStyleSettings ); 1294 Application::SetSettings( aSettings ); 1295 } 1296 if( (aData.nTestFlags & ~IMMEDIATE_FLAGS) != (pData->nTestFlags & ~IMMEDIATE_FLAGS) ) 1297 { 1298 InfoBox aBox( this, String( RTL_CONSTASCII_USTRINGPARAM( 1299 "Some of the changed settings will only be active after " 1300 "restarting the process" 1301 ) ) ); 1302 aBox.Execute(); 1303 } 1304 EndDialog( sal_True ); 1305 } 1306 else if ( pButton == &maInfoButton ) 1307 { 1308 DbgInfoDialog aInfoDialog( this ); 1309 aDbgInfoBuf[0] = '\0'; 1310 DbgMemInfo( aDbgInfoBuf ); 1311 DbgXtorInfo( aDbgInfoBuf ); 1312 XubString aInfoText( aDbgInfoBuf, RTL_TEXTENCODING_UTF8 ); 1313 aInfoDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug InfoReport" ) ) ); 1314 aInfoDialog.SetInfoText( aInfoText ); 1315 aInfoDialog.Execute(); 1316 } 1317 1318 return 0; 1319 } 1320 1321 // ----------------------------------------------------------------------- 1322 1323 void DbgDialog::RequestHelp( const HelpEvent& rHEvt ) 1324 { 1325 if ( rHEvt.GetMode() & HELPMODE_CONTEXT ) 1326 { 1327 DbgInfoDialog aInfoDialog( this, sal_True ); 1328 XubString aHelpText; 1329 const sal_Char** pHelpStrs = pDbgHelpText; 1330 while ( *pHelpStrs ) 1331 { 1332 aHelpText.AppendAscii( *pHelpStrs ); 1333 pHelpStrs++; 1334 } 1335 aInfoDialog.SetText( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug Hilfe" ) ) ); 1336 aInfoDialog.SetInfoText( aHelpText ); 1337 aInfoDialog.Execute(); 1338 } 1339 } 1340 1341 // ======================================================================= 1342 1343 DbgInfoDialog::DbgInfoDialog( Window* pParent, sal_Bool bHelpText ) : 1344 ModalDialog( pParent, WB_STDMODAL ), 1345 maListBox( this, WB_BORDER | WB_AUTOHSCROLL ), 1346 maOKButton( this, WB_DEFBUTTON ) 1347 { 1348 mbHelpText = bHelpText; 1349 1350 if ( !bHelpText ) 1351 { 1352 Font aFont = GetDefaultFont( DEFAULTFONT_FIXED, LANGUAGE_ENGLISH_US, 0 ); 1353 aFont.SetHeight( 8 ); 1354 aFont.SetPitch( PITCH_FIXED ); 1355 maListBox.SetControlFont( aFont ); 1356 } 1357 maListBox.SetPosSizePixel( Point( 5, 5 ), Size( 630, 380 ) ); 1358 maListBox.Show(); 1359 1360 maOKButton.SetPosSizePixel( Point( 290, 390 ), Size( 60, 25 ) ); 1361 maOKButton.Show(); 1362 1363 SetOutputSizePixel( Size( 640, 420 ) ); 1364 } 1365 1366 // ----------------------------------------------------------------------- 1367 1368 void DbgInfoDialog::SetInfoText( const XubString& rStr ) 1369 { 1370 maListBox.SetUpdateMode( sal_False ); 1371 maListBox.Clear(); 1372 XubString aStr = rStr; 1373 aStr.ConvertLineEnd( LINEEND_LF ); 1374 sal_uInt16 nStrIndex = 0; 1375 sal_uInt16 nFoundIndex; 1376 do 1377 { 1378 nFoundIndex = aStr.Search( _LF, nStrIndex ); 1379 XubString aTextParagraph = aStr.Copy( nStrIndex, nFoundIndex-nStrIndex ); 1380 if ( mbHelpText ) 1381 { 1382 long nMaxWidth = maListBox.GetOutputSizePixel().Width()-30; 1383 sal_uInt16 nLastIndex = 0; 1384 sal_uInt16 nIndex = aTextParagraph.Search( ' ' ); 1385 while ( nIndex != STRING_NOTFOUND ) 1386 { 1387 if ( maListBox.GetTextWidth( aTextParagraph, 0, nIndex ) > nMaxWidth ) 1388 { 1389 if ( !nLastIndex ) 1390 nLastIndex = nIndex+1; 1391 XubString aTempStr = aTextParagraph.Copy( 0, nLastIndex ); 1392 aTextParagraph.Erase( 0, nLastIndex ); 1393 maListBox.InsertEntry( aTempStr ); 1394 nLastIndex = 0; 1395 } 1396 else 1397 nLastIndex = nIndex+1; 1398 nIndex = aTextParagraph.Search( ' ', nLastIndex ); 1399 } 1400 1401 if ( maListBox.GetTextWidth( aTextParagraph, 0, nIndex ) > nMaxWidth ) 1402 { 1403 if ( !nLastIndex ) 1404 nLastIndex = nIndex+1; 1405 XubString aTempStr = aTextParagraph.Copy( 0, nLastIndex ); 1406 aTextParagraph.Erase( 0, nLastIndex ); 1407 maListBox.InsertEntry( aTempStr ); 1408 } 1409 } 1410 maListBox.InsertEntry( aTextParagraph ); 1411 nStrIndex = nFoundIndex+1; 1412 } 1413 while ( nFoundIndex != STRING_NOTFOUND ); 1414 maListBox.SetUpdateMode( sal_True ); 1415 } 1416 1417 // ======================================================================= 1418 1419 void DbgDialogTest( Window* pWindow ) 1420 { 1421 sal_Bool aAccelBuf[65536]; 1422 sal_uInt16 nChildCount = pWindow->GetChildCount(); 1423 Window* pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); 1424 Window* pChild; 1425 Point aTabPos; 1426 1427 if ( !pGetChild ) 1428 return; 1429 1430 Rectangle* pRectAry = (Rectangle*)new long[(sizeof(Rectangle)*nChildCount)/sizeof(long)]; 1431 memset( aAccelBuf, 0, sizeof( aAccelBuf ) ); 1432 memset( pRectAry, 0, sizeof(Rectangle)*nChildCount ); 1433 1434 if ( pWindow->IsDialog() ) 1435 { 1436 sal_Bool bOKCancelButton = sal_False; 1437 sal_Bool bDefPushButton = sal_False; 1438 sal_Bool bButton = sal_False; 1439 pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); 1440 while ( pGetChild ) 1441 { 1442 pChild = pGetChild->ImplGetWindow(); 1443 1444 if ( pChild->ImplIsPushButton() ) 1445 { 1446 bButton = sal_True; 1447 if ( (pChild->GetType() == WINDOW_OKBUTTON) || (pChild->GetType() == WINDOW_CANCELBUTTON) ) 1448 bOKCancelButton = sal_True; 1449 if ( pChild->GetStyle() & WB_DEFBUTTON ) 1450 bDefPushButton = sal_True; 1451 } 1452 1453 pGetChild = pGetChild->GetWindow( WINDOW_NEXT ); 1454 } 1455 1456 if ( bButton ) 1457 { 1458 if ( !bOKCancelButton ) 1459 DbgError( "Dialogs should have a OK- or CancelButton" ); 1460 if ( !bDefPushButton ) 1461 DbgError( "Dialogs should have a Button with WB_DEFBUTTON" ); 1462 } 1463 } 1464 1465 sal_uInt16 i = 0; 1466 pGetChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); 1467 while ( pGetChild ) 1468 { 1469 pChild = pGetChild->ImplGetWindow(); 1470 1471 if ( (pChild->GetType() != WINDOW_TABCONTROL) && 1472 (pChild->GetType() != WINDOW_TABPAGE) && 1473 (pChild->GetType() != WINDOW_GROUPBOX) ) 1474 { 1475 XubString aText = pChild->GetText(); 1476 XubString aErrorText = aText; 1477 sal_uInt16 nAccelPos = STRING_NOTFOUND; 1478 xub_Unicode cAccel = 0; 1479 if ( aErrorText.Len() > 128 ) 1480 { 1481 aErrorText.Erase( 128 ); 1482 aErrorText.AppendAscii( "..." ); 1483 } 1484 if ( aText.Len() && (aText.Len() < 1024) ) 1485 { 1486 nAccelPos = aText.Search( '~' ); 1487 if ( nAccelPos != STRING_NOTFOUND ) 1488 { 1489 const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetLocale(); 1490 uno::Reference < i18n::XCharacterClassification > xCharClass = vcl::unohelper::CreateCharacterClassification(); 1491 XubString aUpperText = xCharClass->toUpper( aText, 0, aText.Len(), rLocale ); 1492 cAccel = aUpperText.GetChar( nAccelPos+1 ); 1493 if ( pChild->IsVisible() ) 1494 { 1495 if ( aAccelBuf[cAccel] ) 1496 DbgOutTypef( DBG_OUT_ERROR, "Double mnemonic char: %c", cAccel ); 1497 else 1498 aAccelBuf[cAccel] = sal_True; 1499 } 1500 } 1501 } 1502 1503 if ( (pChild->GetType() == WINDOW_RADIOBUTTON) || 1504 (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) || 1505 (pChild->GetType() == WINDOW_CHECKBOX) || 1506 (pChild->GetType() == WINDOW_TRISTATEBOX) || 1507 (pChild->GetType() == WINDOW_PUSHBUTTON) ) 1508 { 1509 if ( aText.Len() && !aText.EqualsAscii( "..." ) ) 1510 { 1511 const char* pClass; 1512 if ( pChild->GetType() == WINDOW_RADIOBUTTON ) 1513 pClass = "RadioButton"; 1514 else if ( pChild->GetType() == WINDOW_IMAGERADIOBUTTON ) 1515 pClass = "ImageRadioButton"; 1516 else if ( pChild->GetType() == WINDOW_CHECKBOX ) 1517 pClass = "CheckBox"; 1518 else if ( pChild->GetType() == WINDOW_TRISTATEBOX ) 1519 pClass = "TriStateBox"; 1520 else if ( pChild->GetType() == WINDOW_PUSHBUTTON ) 1521 pClass = "PushButton"; 1522 else 1523 pClass = "Dontknow"; 1524 if( !cAccel ) 1525 DbgOutTypef( DBG_OUT_ERROR, 1526 "%s should have a mnemonic char (~): %s", 1527 pClass, 1528 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1529 1530 // check text width 1531 int aWidth=0; 1532 switch( pChild->GetType() ) 1533 { 1534 case WINDOW_RADIOBUTTON: 1535 case WINDOW_IMAGERADIOBUTTON: 1536 aWidth = ((RadioButton*)pChild)->CalcMinimumSize(0).Width(); 1537 break; 1538 case WINDOW_CHECKBOX: 1539 case WINDOW_TRISTATEBOX: 1540 aWidth = ((CheckBox*)pChild)->CalcMinimumSize(0).Width(); 1541 break; 1542 case WINDOW_PUSHBUTTON: 1543 aWidth = ((PushButton*)pChild)->CalcMinimumSize(0).Width(); 1544 break; 1545 default: break; 1546 } 1547 if( pChild->IsVisible() && pChild->GetSizePixel().Width() < aWidth ) 1548 DbgOutTypef( DBG_OUT_ERROR, 1549 "%s exceeds window width: %s", 1550 pClass, 1551 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1552 } 1553 } 1554 1555 if ( pChild->GetType() == WINDOW_FIXEDLINE ) 1556 { 1557 if ( pChild->GetSizePixel().Width() < pChild->GetTextWidth( aText ) ) 1558 DbgOutTypef( DBG_OUT_ERROR, 1559 "FixedLine exceeds window width: %s", 1560 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1561 } 1562 1563 if ( pChild->GetType() == WINDOW_FIXEDTEXT ) 1564 { 1565 if ( (pChild->GetSizePixel().Height() >= pChild->GetTextHeight()*2) && 1566 !(pChild->GetStyle() & WB_WORDBREAK) ) 1567 { 1568 DbgOutTypef( DBG_OUT_ERROR, 1569 "FixedText greater than one line, but WordBreak is not set: %s", 1570 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1571 } 1572 1573 if ( pChild->IsVisible() ) 1574 { 1575 int aWidth=0; 1576 if( nAccelPos != STRING_NOTFOUND ) 1577 { 1578 aWidth = pChild->GetTextWidth( aText, 0, nAccelPos ) + 1579 pChild->GetTextWidth( aText, nAccelPos+1, aText.Len() - nAccelPos - 1); 1580 } 1581 else 1582 aWidth = pChild->GetTextWidth( aText ); 1583 1584 if ( pChild->GetSizePixel().Width() < aWidth && !(pChild->GetStyle() & WB_WORDBREAK) ) 1585 { 1586 DbgOutTypef( DBG_OUT_ERROR, 1587 "FixedText exceeds window width: %s", 1588 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1589 } 1590 } 1591 1592 if ( (i+1 < nChildCount) && aText.Len() ) 1593 { 1594 Window* pTempChild = pGetChild->GetWindow( WINDOW_NEXT )->ImplGetWindow(); 1595 if ( (pTempChild->GetType() == WINDOW_EDIT) || 1596 (pTempChild->GetType() == WINDOW_MULTILINEEDIT) || 1597 (pTempChild->GetType() == WINDOW_SPINFIELD) || 1598 (pTempChild->GetType() == WINDOW_PATTERNFIELD) || 1599 (pTempChild->GetType() == WINDOW_NUMERICFIELD) || 1600 (pTempChild->GetType() == WINDOW_METRICFIELD) || 1601 (pTempChild->GetType() == WINDOW_CURRENCYFIELD) || 1602 (pTempChild->GetType() == WINDOW_DATEFIELD) || 1603 (pTempChild->GetType() == WINDOW_TIMEFIELD) || 1604 (pTempChild->GetType() == WINDOW_LISTBOX) || 1605 (pTempChild->GetType() == WINDOW_MULTILISTBOX) || 1606 (pTempChild->GetType() == WINDOW_COMBOBOX) || 1607 (pTempChild->GetType() == WINDOW_PATTERNBOX) || 1608 (pTempChild->GetType() == WINDOW_NUMERICBOX) || 1609 (pTempChild->GetType() == WINDOW_METRICBOX) || 1610 (pTempChild->GetType() == WINDOW_CURRENCYBOX) || 1611 (pTempChild->GetType() == WINDOW_DATEBOX) || 1612 (pTempChild->GetType() == WINDOW_TIMEBOX) ) 1613 { 1614 if ( !cAccel ) 1615 { 1616 DbgOutTypef( DBG_OUT_ERROR, 1617 "Labels befor Fields (Edit,ListBox,...) should have a mnemonic char (~): %s", 1618 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1619 } 1620 if ( !pTempChild->IsEnabled() && pChild->IsEnabled() ) 1621 { 1622 DbgOutTypef( DBG_OUT_ERROR, 1623 "Labels befor Fields (Edit,ListBox,...) should be disabled, when the field is disabled: %s", 1624 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1625 } 1626 } 1627 } 1628 } 1629 1630 if ( pChild->GetType() == WINDOW_MULTILINEEDIT ) 1631 { 1632 if ( ( 0 == ( pChild->GetStyle() & WB_IGNORETAB ) ) 1633 && ( 0 == ( pChild->GetStyle() & WB_READONLY ) ) 1634 ) 1635 { 1636 DbgError( "editable MultiLineEdits in Dialogs should have the Style WB_IGNORETAB" ); 1637 } 1638 } 1639 1640 if ( (pChild->GetType() == WINDOW_RADIOBUTTON) || 1641 (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) || 1642 (pChild->GetType() == WINDOW_CHECKBOX) || 1643 (pChild->GetType() == WINDOW_TRISTATEBOX) || 1644 (pChild->GetType() == WINDOW_FIXEDTEXT) ) 1645 { 1646 pChild->SetBackground( Wallpaper( Color( COL_LIGHTGREEN ) ) ); 1647 } 1648 1649 if ( pChild->IsVisible() ) 1650 { 1651 sal_Bool bMaxWarning = sal_False; 1652 if ( pChild->GetType() == WINDOW_NUMERICFIELD ) 1653 { 1654 NumericField* pField = (NumericField*)pChild; 1655 if ( pField->GetMax() == LONG_MAX ) 1656 bMaxWarning = sal_True; 1657 } 1658 else if ( pChild->GetType() == WINDOW_METRICFIELD ) 1659 { 1660 MetricField* pField = (MetricField*)pChild; 1661 if ( pField->GetMax() == LONG_MAX ) 1662 bMaxWarning = sal_True; 1663 } 1664 else if ( pChild->GetType() == WINDOW_CURRENCYFIELD ) 1665 { 1666 CurrencyField* pField = (CurrencyField*)pChild; 1667 if ( pField->GetMax() == LONG_MAX ) 1668 bMaxWarning = sal_True; 1669 } 1670 else if ( pChild->GetType() == WINDOW_TIMEFIELD ) 1671 { 1672 TimeField* pField = (TimeField*)pChild; 1673 if ( pField->GetMax() == Time( 23, 59, 59, 99 ) ) 1674 bMaxWarning = sal_True; 1675 } 1676 else if ( pChild->GetType() == WINDOW_DATEFIELD ) 1677 { 1678 DateField* pField = (DateField*)pChild; 1679 if ( pField->GetMax() == Date( 31, 12, 9999 ) ) 1680 bMaxWarning = sal_True; 1681 } 1682 else if ( pChild->GetType() == WINDOW_NUMERICBOX ) 1683 { 1684 NumericBox* pBox = (NumericBox*)pChild; 1685 if ( pBox->GetMax() == LONG_MAX ) 1686 bMaxWarning = sal_True; 1687 } 1688 else if ( pChild->GetType() == WINDOW_METRICBOX ) 1689 { 1690 MetricBox* pBox = (MetricBox*)pChild; 1691 if ( pBox->GetMax() == LONG_MAX ) 1692 bMaxWarning = sal_True; 1693 } 1694 else if ( pChild->GetType() == WINDOW_CURRENCYBOX ) 1695 { 1696 CurrencyBox* pBox = (CurrencyBox*)pChild; 1697 if ( pBox->GetMax() == LONG_MAX ) 1698 bMaxWarning = sal_True; 1699 } 1700 else if ( pChild->GetType() == WINDOW_TIMEBOX ) 1701 { 1702 TimeBox* pBox = (TimeBox*)pChild; 1703 if ( pBox->GetMax() == Time( 23, 59, 59, 99 ) ) 1704 bMaxWarning = sal_True; 1705 } 1706 else if ( pChild->GetType() == WINDOW_DATEBOX ) 1707 { 1708 DateBox* pBox = (DateBox*)pChild; 1709 if ( pBox->GetMax() == Date( 31, 12, 9999 ) ) 1710 bMaxWarning = sal_True; 1711 } 1712 if ( bMaxWarning ) 1713 { 1714 DbgOutTypef( DBG_OUT_ERROR, 1715 "No Max-Value is set: %s", 1716 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1717 } 1718 1719 if ( (pChild->GetType() == WINDOW_RADIOBUTTON) || 1720 (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) || 1721 (pChild->GetType() == WINDOW_CHECKBOX) || 1722 (pChild->GetType() == WINDOW_TRISTATEBOX) || 1723 (pChild->GetType() == WINDOW_PUSHBUTTON) || 1724 (pChild->GetType() == WINDOW_OKBUTTON) || 1725 (pChild->GetType() == WINDOW_CANCELBUTTON) || 1726 (pChild->GetType() == WINDOW_HELPBUTTON) || 1727 (pChild->GetType() == WINDOW_IMAGEBUTTON) || 1728 (pChild->GetType() == WINDOW_FIXEDTEXT) || 1729 (pChild->GetType() == WINDOW_EDIT) || 1730 (pChild->GetType() == WINDOW_MULTILINEEDIT) || 1731 (pChild->GetType() == WINDOW_SPINFIELD) || 1732 (pChild->GetType() == WINDOW_PATTERNFIELD) || 1733 (pChild->GetType() == WINDOW_NUMERICFIELD) || 1734 (pChild->GetType() == WINDOW_METRICFIELD) || 1735 (pChild->GetType() == WINDOW_CURRENCYFIELD) || 1736 (pChild->GetType() == WINDOW_DATEFIELD) || 1737 (pChild->GetType() == WINDOW_TIMEFIELD) || 1738 (pChild->GetType() == WINDOW_LISTBOX) || 1739 (pChild->GetType() == WINDOW_MULTILISTBOX) || 1740 (pChild->GetType() == WINDOW_COMBOBOX) || 1741 (pChild->GetType() == WINDOW_PATTERNBOX) || 1742 (pChild->GetType() == WINDOW_NUMERICBOX) || 1743 (pChild->GetType() == WINDOW_METRICBOX) || 1744 (pChild->GetType() == WINDOW_CURRENCYBOX) || 1745 (pChild->GetType() == WINDOW_DATEBOX) || 1746 (pChild->GetType() == WINDOW_TIMEBOX) ) 1747 { 1748 Point aNewPos = pChild->GetPosPixel(); 1749 Rectangle aChildRect( aNewPos, pChild->GetSizePixel() ); 1750 1751 if ( cAccel || (pChild->GetStyle() & WB_TABSTOP) || 1752 (pChild->GetType() == WINDOW_RADIOBUTTON) || 1753 (pChild->GetType() == WINDOW_IMAGERADIOBUTTON) ) 1754 { 1755 if ( (aNewPos.X() <= aTabPos.X()) && (aNewPos.Y() <= aTabPos.Y()) ) 1756 { 1757 DbgOutTypef( DBG_OUT_ERROR, 1758 "Possible wrong childorder for dialogcontrol: %s", 1759 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1760 } 1761 aTabPos = aNewPos; 1762 } 1763 1764 for ( sal_uInt16 j = 0; j < i; j++ ) 1765 { 1766 if ( ((pRectAry[j].Right() != 0) || (pRectAry[j].Bottom() != 0)) && 1767 aChildRect.IsOver( pRectAry[j] ) ) 1768 { 1769 DbgOutTypef( DBG_OUT_ERROR, 1770 "Window overlaps with sibling window: %s", 1771 ByteString( aErrorText, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); 1772 } 1773 } 1774 pRectAry[i] = aChildRect; 1775 } 1776 } 1777 } 1778 1779 pGetChild = pGetChild->GetWindow( WINDOW_NEXT ); 1780 i++; 1781 } 1782 1783 delete [] pRectAry; 1784 } 1785 1786 // ======================================================================= 1787 #ifndef WNT 1788 #define USE_VCL_MSGBOX 1789 #define COPY_BUTTON_ID 25 1790 1791 class DbgMessageBox : public ErrorBox 1792 { 1793 String m_aMessage; 1794 public: 1795 DbgMessageBox( const String& rMessage ) : 1796 ErrorBox( NULL, WB_YES_NO_CANCEL | WB_DEF_NO, rMessage ), 1797 m_aMessage( rMessage ) 1798 { 1799 SetText( String( RTL_CONSTASCII_USTRINGPARAM("Debug Output") ) ); 1800 AddButton( String( RTL_CONSTASCII_USTRINGPARAM( "Copy" ) ), COPY_BUTTON_ID, 0 ); 1801 } 1802 1803 virtual void Click() 1804 { 1805 if( GetCurButtonId() == COPY_BUTTON_ID ) 1806 vcl::unohelper::TextDataObject::CopyStringTo( m_aMessage, GetClipboard() ); 1807 else 1808 ErrorBox::Click(); 1809 } 1810 }; 1811 1812 #endif 1813 1814 class SolarMessageBoxExecutor : public ::vcl::SolarThreadExecutor 1815 { 1816 private: 1817 String m_sDebugMessage; 1818 1819 public: 1820 SolarMessageBoxExecutor( const String& _rDebugMessage ) 1821 :m_sDebugMessage( _rDebugMessage ) 1822 { 1823 } 1824 1825 protected: 1826 virtual long doIt(); 1827 }; 1828 1829 long SolarMessageBoxExecutor::doIt() 1830 { 1831 long nResult = RET_NO; 1832 1833 // Tracking beenden und Mouse freigeben, damit die Boxen nicht haengen 1834 ImplSVData* pSVData = ImplGetSVData(); 1835 if ( pSVData->maWinData.mpTrackWin ) 1836 pSVData->maWinData.mpTrackWin->EndTracking( ENDTRACK_CANCEL ); 1837 if ( pSVData->maWinData.mpCaptureWin ) 1838 pSVData->maWinData.mpCaptureWin->ReleaseMouse(); 1839 1840 #if ! defined USE_VCL_MSGBOX 1841 #ifdef WNT 1842 sal_Bool bOldCallTimer = pSVData->mbNoCallTimer; 1843 pSVData->mbNoCallTimer = sal_True; 1844 MessageBeep( MB_ICONHAND ); 1845 nResult = MessageBoxW( 0, (LPWSTR)m_sDebugMessage.GetBuffer(), L"Debug Output", 1846 MB_TASKMODAL | MB_YESNOCANCEL | MB_DEFBUTTON2 | MB_ICONSTOP ); 1847 pSVData->mbNoCallTimer = bOldCallTimer; 1848 switch ( nResult ) 1849 { 1850 case IDYES: 1851 nResult = RET_YES; 1852 break; 1853 case IDNO: 1854 nResult = RET_NO; 1855 break; 1856 case IDCANCEL: 1857 nResult = RET_CANCEL; 1858 break; 1859 } 1860 #endif // WNT 1861 #else 1862 sal_uInt16 nOldMode = Application::GetSystemWindowMode(); 1863 Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE ); 1864 DbgMessageBox aBox( m_sDebugMessage ); 1865 Application::SetSystemWindowMode( nOldMode ); 1866 nResult = aBox.Execute(); 1867 #endif 1868 1869 return nResult; 1870 } 1871 1872 void DbgPrintMsgBox( const char* pLine ) 1873 { 1874 // are modal message boxes prohibited at the moment? 1875 if ( Application::IsDialogCancelEnabled() ) 1876 { 1877 #if defined( WNT ) 1878 // TODO: Shouldn't this be a IsDebuggerPresent()? 1879 if ( GetSystemMetrics( SM_DEBUG ) ) 1880 { 1881 MessageBeep( MB_ICONHAND ); 1882 strcpy( aDbgOutBuf, pLine ); 1883 strcat( aDbgOutBuf, "\r\n" ); 1884 OutputDebugString( aDbgOutBuf ); 1885 return; 1886 } 1887 #endif 1888 1889 Sound::Beep( SOUND_ERROR ); 1890 #ifdef UNX 1891 fprintf( stderr, "%s\n", pLine ); 1892 return; 1893 #else 1894 DbgPrintFile( pLine ); 1895 return; 1896 #endif 1897 } 1898 1899 strcpy( aDbgOutBuf, pLine ); 1900 strcat( aDbgOutBuf, "\nAbort ? (Yes=abort / No=ignore / Cancel=core dump)" ); 1901 1902 SolarMessageBoxExecutor aMessageBox( String( aDbgOutBuf, RTL_TEXTENCODING_UTF8 ) ); 1903 TimeValue aTimeout; aTimeout.Seconds = 2; aTimeout.Nanosec = 0; 1904 long nResult = aMessageBox.execute( aTimeout ); 1905 1906 if ( aMessageBox.didTimeout() ) 1907 DbgPrintShell( pLine ); 1908 else if ( nResult == RET_YES ) 1909 GetpApp()->Abort( XubString( RTL_CONSTASCII_USTRINGPARAM( "Debug-Utilities-Error" ) ) ); 1910 else if ( nResult == RET_CANCEL ) 1911 DbgCoreDump(); 1912 } 1913 1914 // ----------------------------------------------------------------------- 1915 1916 class SolarWindowPrinter : public ::vcl::SolarThreadExecutor 1917 { 1918 private: 1919 String m_sDebugMessage; 1920 1921 public: 1922 SolarWindowPrinter( const String& _rDebugMessage ) 1923 :m_sDebugMessage( _rDebugMessage ) 1924 { 1925 } 1926 1927 protected: 1928 virtual long doIt(); 1929 }; 1930 1931 long SolarWindowPrinter::doIt() 1932 { 1933 DbgWindow* pDbgWindow = ImplGetSVData()->maWinData.mpDbgWin; 1934 if ( !pDbgWindow ) 1935 { 1936 pDbgWindow = new DbgWindow; 1937 ImplGetSVData()->maWinData.mpDbgWin = pDbgWindow; 1938 } 1939 pDbgWindow->InsertLine( m_sDebugMessage ); 1940 1941 return 0L; 1942 } 1943 1944 // ----------------------------------------------------------------------- 1945 1946 void DbgPrintWindow( const char* pLine ) 1947 { 1948 static sal_Bool bIn = sal_False; 1949 1950 // keine rekursiven Traces 1951 if ( bIn ) 1952 return; 1953 bIn = sal_True; 1954 1955 SolarWindowPrinter aPrinter( String( pLine, RTL_TEXTENCODING_UTF8 ) ); 1956 TimeValue aTimeout; aTimeout.Seconds = 2; aTimeout.Nanosec = 0; 1957 aPrinter.execute( aTimeout ); 1958 1959 if ( aPrinter.didTimeout() ) 1960 DbgPrintShell( pLine ); 1961 1962 bIn = sal_False; 1963 } 1964 1965 // ----------------------------------------------------------------------- 1966 1967 void DbgAbort( char const * i_message ) 1968 { 1969 ::rtl::OUString const message( i_message, strlen( i_message ), osl_getThreadTextEncoding() ); 1970 Application::Abort( message ); 1971 } 1972 1973 // ======================================================================= 1974 1975 void ImplDbgTestSolarMutex() 1976 { 1977 bool bCheck = ImplGetSVData()->mpDefInst->CheckYieldMutex(); 1978 OSL_ENSURE( bCheck, "SolarMutex not locked" ); 1979 } 1980 1981 // ======================================================================= 1982 1983 void DbgGUIInit() 1984 { 1985 DbgSetPrintMsgBox( DbgPrintMsgBox ); 1986 DbgSetPrintWindow( DbgPrintWindow ); 1987 DbgSetTestSolarMutex( ImplDbgTestSolarMutex ); 1988 DbgSetAbort( DbgAbort ); 1989 } 1990 1991 // ----------------------------------------------------------------------- 1992 1993 void DbgGUIDeInit() 1994 { 1995 DbgSetPrintMsgBox( NULL ); 1996 DbgSetPrintWindow( NULL ); 1997 DbgSetTestSolarMutex( NULL ); 1998 DbgSetAbort( NULL ); 1999 2000 DbgWindow* pDbgWindow = ImplGetSVData()->maWinData.mpDbgWin; 2001 if ( pDbgWindow ) 2002 delete pDbgWindow; 2003 } 2004 2005 // ----------------------------------------------------------------------- 2006 2007 void DbgGUIStart() 2008 { 2009 DbgData* pData = DbgGetData(); 2010 2011 if ( pData ) 2012 { 2013 DbgDialog* pDialog = new DbgDialog; 2014 // Fuer den Debug-Dialog schalten wir Dialogtests aus 2015 sal_uLong nOldFlags = pData->nTestFlags; 2016 pData->nTestFlags &= ~DBG_TEST_DIALOG; 2017 if ( !pDialog->Execute() ) 2018 pData->nTestFlags |= (nOldFlags & DBG_TEST_DIALOG); 2019 delete pDialog; 2020 } 2021 else 2022 { 2023 ErrorBox( 0, WB_OK, 2024 XubString( RTL_CONSTASCII_USTRINGPARAM( "TOOLS Library has no Debug-Routines" ) ) ).Execute(); 2025 } 2026 } 2027 2028 // ----------------------------------------------------------------------- 2029 2030 sal_uInt16 DbgRegisterNamedUserChannel( const XubString& _rChannelUIName, DbgPrintLine pProc ) 2031 { 2032 DbgChannelId nChannelId = DbgRegisterUserChannel( pProc ); 2033 UserDefinedChannels& rChannels = ImplDbgGetUserDefinedChannels(); 2034 rChannels[ _rChannelUIName ] = nChannelId; 2035 return nChannelId; 2036 } 2037 2038 #endif // DBG_UTIL 2039