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