merge the formfield patch from ooo-build
[ooovba.git] / basic / source / app / msgedit.cxx
blob1ef046170d2d768d73db7b2202b35888704e17db
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: msgedit.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
33 /*************************************************************************
34 File Versions so far:
35 No Version Initial Implementation without Version Information
36 Version 2 changed order of entries(New Entries at the end)
37 Version 3 Changed Charset from CHARSET_IBMPC to RTL_TEXTENCODING_UTF8
39 *************************************************************************/
40 #include <cstdio>
41 #include <tools/time.hxx>
42 #include <tools/stream.hxx>
43 #ifndef _MSGBOX_HXX //autogen
44 #include <vcl/msgbox.hxx>
45 #endif
46 #ifndef _SOUND_HXX //autogen
47 #include <vcl/sound.hxx>
48 #endif
49 #include <tools/fsys.hxx>
50 #include <svtools/stringtransfer.hxx>
51 #include <svtools/syslocale.hxx>
52 #ifndef _BASIC_TTRESHLP_HXX
53 #include <basic/ttstrhlp.hxx>
54 #endif
55 #include "basic.hrc"
56 #include "msgedit.hxx"
57 #include "app.hxx"
58 #include "apperror.hxx"
59 #include "appbased.hxx"
60 #include "basmsg.hrc"
61 #include "basrid.hxx"
63 USHORT MsgEdit::nMaxLogLen = 0;
64 BOOL MsgEdit::bLimitLogLen = FALSE;
65 BOOL MsgEdit::bPrintLogToStdout = FALSE;
66 BOOL MsgEdit::bPrintLogToStdoutSet = FALSE;
68 #define WARNING_PREFIX String( SttResId( S_WARNING_PREFIX ) )
69 #define VERSION_STRING CUniString("File Format Version: ")
70 #define THIS_VERSION 2
72 #define LOGTYPE( pEntry ) ((pEntry && pEntry->GetUserData())?((TTDebugData*)pEntry->GetUserData())->aLogType:LOG_ERROR)
74 MsgEdit::MsgEdit( AppError* pParent, BasicFrame *pBF, const WinBits& aBits )
75 : pBasicFrame(pBF)
76 , pCurrentRun(NULL)
77 , pCurrentTestCase(NULL)
78 , pCurrentAssertion( NULL )
79 , pCurrentError(NULL)
80 , bModified(FALSE)
81 , bFileLoading(FALSE)
82 , nVersion(0)
83 , pAppError( pParent )
84 , aEditTree( pParent, pBF, aBits | WB_HASBUTTONS | WB_HASLINES | WB_HASBUTTONSATROOT )
86 // SetFont( aEditTree.GetDefaultFont( DEFAULTFONT_FIXED, aEditTree.GetSettings().GetLanguage(), 0, &aEditTree ) );
87 aEditTree.SetNodeBitmaps( Bitmap( SttResId (MBP_PLUS) ), Bitmap( SttResId (MBP_MINUS) ) );
88 aEditTree.SetSelectionMode( MULTIPLE_SELECTION );
89 if ( aEditTree.GetModel()->GetSortMode() != SortNone )
90 aEditTree.GetModel()->SetSortMode( SortNone );
92 if ( !bPrintLogToStdoutSet )
94 bPrintLogToStdoutSet = TRUE;
95 for ( USHORT i = 0 ; i < Application::GetCommandLineParamCount() ; i++ )
97 if ( Application::GetCommandLineParam( i ).Copy(0,9).CompareIgnoreCaseToAscii("-printlog") == COMPARE_EQUAL
98 #ifndef UNX
99 || Application::GetCommandLineParam( i ).Copy(0,9).CompareIgnoreCaseToAscii("/printlog") == COMPARE_EQUAL
100 #endif
102 bPrintLogToStdout = TRUE;
107 MsgEdit::~MsgEdit()
110 // set the LogType since calling the add method can be from other add methods
111 #define COPY_TTDEBUGDATA( LOGTYPE ) \
112 TTDebugData *pTTDebugData = new TTDebugData; \
113 *pTTDebugData = aDebugData; \
114 pTTDebugData->aLogType = LOGTYPE; \
117 void MsgEdit::AddAnyMsg( TTLogMsg *LogMsg )
119 if ( LogMsg->aDebugData.aFilename.Copy(0,2).CompareToAscii( "--" ) == COMPARE_EQUAL )
120 LogMsg->aDebugData.aFilename.Erase(0,2);
122 if ( LogMsg->aDebugData.aFilename.Len() && LogMsg->aDebugData.aFilename.GetChar(0) != '~' ) // do we want to convert
124 DirEntry aConvert( LogMsg->aDebugData.aFilename );
125 if ( pAppError->aBaseDir.Contains( aConvert ) )
127 aConvert.ToRel( pAppError->aBaseDir );
128 LogMsg->aDebugData.aFilename = CUniString("~"); // mark as converted
129 LogMsg->aDebugData.aFilename += aConvert.GetFull( FSYS_STYLE_VFAT );
131 else if ( !bFileLoading )
133 LogMsg->aDebugData.aFilename.Insert( CUniString("~-"), 0); // mark as unconvertable
136 xub_StrLen nPos;
137 LogMsg->aDebugData.aMsg.ConvertLineEnd();
138 // does the message have several lines -> repeat the call for each line
139 if ( (nPos = LogMsg->aDebugData.aMsg.Search( CUniString("\n").ConvertLineEnd() )) != STRING_NOTFOUND )
141 String aOriginalMsg = LogMsg->aDebugData.aMsg;
142 xub_StrLen nSysLineEndLen = CUniString("\n").ConvertLineEnd().Len();
143 String aLastPart = LogMsg->aDebugData.aMsg.Copy( nPos+nSysLineEndLen );
144 LogMsg->aDebugData.aMsg.Erase( nPos );
145 AddAnyMsg( LogMsg );
146 if ( aLastPart.Len() )
148 LogMsg->aDebugData.aMsg = aLastPart;
149 AddAnyMsg( LogMsg );
151 LogMsg->aDebugData.aMsg = aOriginalMsg;
153 else
155 String aUILogMsg( pBasicFrame->GenRealString( LogMsg->aDebugData.aMsg ) );
156 switch ( LogMsg->aDebugData.aLogType )
158 case LOG_RUN:
160 if ( LogMsg->aDebugData.aMsg.Len() == 0 )
162 SvtSysLocale aLocale;
163 LogMsg->aDebugData.aMsg = GEN_RES_STR2( S_PROG_START,
164 aLocale.GetLocaleData().getDate(Date()),
165 aLocale.GetLocaleData().getTime(Time()) );
166 aUILogMsg = pBasicFrame->GenRealString( LogMsg->aDebugData.aMsg );
168 AddRun( aUILogMsg, LogMsg->aDebugData ); break;
170 case LOG_TEST_CASE: AddTestCase( aUILogMsg, LogMsg->aDebugData ); break;
171 case LOG_ERROR: AddError( aUILogMsg, LogMsg->aDebugData ); break;
172 case LOG_CALL_STACK:AddCallStack( aUILogMsg, LogMsg->aDebugData ); break;
173 case LOG_MESSAGE: AddMessage( aUILogMsg, LogMsg->aDebugData ); break;
174 case LOG_WARNING: AddWarning( aUILogMsg, LogMsg->aDebugData ); break;
175 case LOG_ASSERTION: AddAssertion( aUILogMsg, LogMsg->aDebugData ); break;
176 case LOG_ASSERTION_STACK: AddAssertionStack( aUILogMsg, LogMsg->aDebugData ); break;
177 case LOG_QA_ERROR: AddQAError( aUILogMsg, LogMsg->aDebugData ); break;
178 default:DBG_ERROR("Unbekannter Typ in ResultFile. Speichern des ResultFile resultiert in Informationsverlust");
181 if ( !bFileLoading )
182 { // Comes from Testtool and must be written immediately
183 BOOL bFileWasChanged = pAppError->DiskFileChanged( SINCE_LAST_LOAD );
185 DBG_ASSERT( aLogFileName == LogMsg->aLogFileName, "Logging to different logfile as before" );
186 DirEntry aEntry( LogMsg->aLogFileName );
187 BOOL bNewFile = !aEntry.Exists();
188 SvFileStream aStrm( LogMsg->aLogFileName, STREAM_STD_WRITE );
189 if ( bNewFile )
191 String aSave = VERSION_STRING.Append( UniString::CreateFromInt32( 3 ) ).AppendAscii("\n"); // Version 3
192 aSave.ConvertLineEnd(LINEEND_CRLF);
193 aStrm << ByteString( aSave, RTL_TEXTENCODING_IBM_850 ).GetBuffer();
196 String aLogMsg = Impl_MakeSaveText( LogMsg->aDebugData ).AppendAscii("\n");
198 if( aStrm.IsOpen() )
200 aLogMsg.ConvertLineEnd(LINEEND_CRLF);
201 aStrm.Seek(STREAM_SEEK_TO_END);
202 aStrm << ByteString( aLogMsg, RTL_TEXTENCODING_UTF8 ).GetBuffer();
203 aStrm.Close();
205 if ( !bFileWasChanged )
206 pAppError->UpdateFileInfo( HAS_BEEN_LOADED );
209 // now write to stdout
210 if ( bPrintLogToStdout )
212 String aPrintMsg, aOriginalMsg;
214 aOriginalMsg = LogMsg->aDebugData.aMsg;
215 // converting to human readable string for adding errors to list in testobject
216 LogMsg->aDebugData.aMsg = pBasicFrame->GenRealString( LogMsg->aDebugData.aMsg );
218 aPrintMsg = Impl_MakeSaveText( LogMsg->aDebugData ).AppendAscii("\n");
220 // restore Original Msg
221 LogMsg->aDebugData.aMsg = aOriginalMsg;
223 printf( ByteString( aPrintMsg, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
227 // converting to human readable string for adding errors to list in testobject
228 LogMsg->aDebugData.aMsg = pBasicFrame->GenRealString( LogMsg->aDebugData.aMsg );
231 void MsgEdit::AddRun( String aMsg, TTDebugData aDebugData )
233 if ( !bFileLoading && bLimitLogLen )
235 USHORT nSkip = nMaxLogLen;
236 SvLBoxEntry *pRun = aEditTree.First();
237 while ( nSkip-- && pRun )
238 pRun = aEditTree.NextSibling( pRun );
239 // Remove all Entries thereafter
240 if ( pRun )
242 while ( pRun && aEditTree.NextSibling( pRun ) )
243 aEditTree.GetModel()->Remove( aEditTree.NextSibling( pRun ) );
245 aEditTree.GetModel()->Remove( pRun );
246 bModified = TRUE;
247 lModify.Call( NULL );
248 Save( aLogFileName );
249 pAppError->UpdateFileInfo( HAS_BEEN_LOADED );
253 COPY_TTDEBUGDATA( LOG_RUN );
254 if ( !bFileLoading || ( bFileLoading && nVersion >= 2 ) )
255 pCurrentRun = aEditTree.InsertEntry( aMsg, NULL, FALSE, 0, pTTDebugData );
256 else // First file format
257 pCurrentRun = aEditTree.InsertEntry( aMsg, NULL, FALSE, LIST_APPEND, pTTDebugData ); // and therefor at the end
259 aEditTree.ShowEntry( pCurrentRun );
260 pCurrentTestCase = NULL;
261 pCurrentAssertion = NULL;
262 pCurrentError = NULL;
265 void MsgEdit::AddTestCase( String aMsg, TTDebugData aDebugData )
267 if ( pCurrentRun )
269 if ( aMsg.Len() == 0 ) // End of Testcase
271 pCurrentTestCase = NULL;
273 else
275 COPY_TTDEBUGDATA( LOG_TEST_CASE );
276 pCurrentTestCase = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
277 aEditTree.ShowEntry( pCurrentTestCase );
280 pCurrentAssertion = NULL;
281 pCurrentError = NULL;
284 void MsgEdit::AddError( String aMsg, TTDebugData aDebugData )
286 if ( !pCurrentTestCase )
288 TTLogMsg aLogMsg;
289 aLogMsg.aDebugData = aDebugData;
290 aLogMsg.aDebugData.aMsg = GEN_RES_STR0( S_ERROR_OUTSIDE_TESTCASE );
291 aLogMsg.aDebugData.aLogType = LOG_TEST_CASE;
292 aLogMsg.aLogFileName = aLogFileName;
293 AddAnyMsg( &aLogMsg );
295 if ( pCurrentTestCase )
297 COPY_TTDEBUGDATA( LOG_ERROR );
298 pCurrentError = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
299 aEditTree.ShowEntry( pCurrentError );
303 void MsgEdit::AddCallStack( String aMsg, TTDebugData aDebugData )
305 DBG_ASSERT( pCurrentError, "Callstack ohne CurrentError im Journal" );
306 if ( pCurrentError )
308 COPY_TTDEBUGDATA( LOG_CALL_STACK );
309 aEditTree.InsertEntry( aMsg, pCurrentError, FALSE, LIST_APPEND, pTTDebugData );
313 void MsgEdit::AddMessage( String aMsg, TTDebugData aDebugData )
315 SvLBoxEntry *pThisEntry = NULL;
316 COPY_TTDEBUGDATA( LOG_MESSAGE );
317 if ( pCurrentTestCase )
318 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
319 else if ( pCurrentRun )
321 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
322 aEditTree.ShowEntry( pThisEntry );
324 else
326 AddRun( aMsg, aDebugData );
327 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
328 aEditTree.ShowEntry( pThisEntry );
332 void MsgEdit::AddWarning( String aMsg, TTDebugData aDebugData )
334 SvLBoxEntry *pThisEntry = NULL;
335 String aCompleteMsg;
336 aCompleteMsg = WARNING_PREFIX.Append( aMsg );
337 COPY_TTDEBUGDATA( LOG_WARNING );
339 if ( pCurrentTestCase )
340 pThisEntry = aEditTree.InsertEntry( aCompleteMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
341 else if ( pCurrentRun )
343 pThisEntry = aEditTree.InsertEntry( aCompleteMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
344 aEditTree.ShowEntry( pThisEntry );
346 else
348 AddRun( aMsg, aDebugData );
349 pThisEntry = aEditTree.InsertEntry( aCompleteMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
350 aEditTree.ShowEntry( pThisEntry );
353 while ( !aEditTree.IsEntryVisible( pThisEntry ) && ( pThisEntry = aEditTree.GetParent( pThisEntry ) ) != NULL )
354 aEditTree.InvalidateEntry( pThisEntry );
357 void MsgEdit::AddAssertion( String aMsg, TTDebugData aDebugData )
359 const String aAssertionStackPrefix( CUniString(ASSERTION_STACK_PREFIX) );
360 if ( aMsg.Match( aAssertionStackPrefix ) == aAssertionStackPrefix.Len() )
362 AddAssertionStack( aMsg, aDebugData );
363 return;
365 SvLBoxEntry *pThisEntry = NULL;
366 COPY_TTDEBUGDATA( LOG_ASSERTION );
367 if ( pCurrentTestCase )
368 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
369 else if ( pCurrentRun )
371 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
372 aEditTree.ShowEntry( pThisEntry );
374 else
376 AddRun( aMsg, aDebugData );
377 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
378 aEditTree.ShowEntry( pThisEntry );
381 pCurrentAssertion = pThisEntry;
383 while ( !aEditTree.IsEntryVisible( pThisEntry ) && ( pThisEntry = aEditTree.GetParent( pThisEntry ) ) != NULL )
384 aEditTree.InvalidateEntry( pThisEntry );
387 void MsgEdit::AddAssertionStack( String aMsg, TTDebugData aDebugData )
389 SvLBoxEntry *pThisEntry = NULL;
390 COPY_TTDEBUGDATA( LOG_ASSERTION_STACK );
391 if ( pCurrentAssertion )
392 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentAssertion, FALSE, LIST_APPEND, pTTDebugData );
393 else if ( pCurrentTestCase )
394 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
395 else if ( pCurrentRun )
397 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
398 aEditTree.ShowEntry( pThisEntry );
400 else
402 AddRun( aMsg, aDebugData );
403 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
404 aEditTree.ShowEntry( pThisEntry );
407 while ( !aEditTree.IsEntryVisible( pThisEntry ) && ( pThisEntry = aEditTree.GetParent( pThisEntry ) ) != NULL )
408 aEditTree.InvalidateEntry( pThisEntry );
411 void MsgEdit::AddQAError( String aMsg, TTDebugData aDebugData )
413 SvLBoxEntry *pThisEntry = NULL;
414 COPY_TTDEBUGDATA( LOG_QA_ERROR );
415 if ( pCurrentTestCase )
416 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentTestCase, FALSE, LIST_APPEND, pTTDebugData );
417 else if ( pCurrentRun )
419 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
420 aEditTree.ShowEntry( pThisEntry );
422 else
424 AddRun( aMsg, aDebugData );
425 pThisEntry = aEditTree.InsertEntry( aMsg, pCurrentRun, FALSE, LIST_APPEND, pTTDebugData );
426 aEditTree.ShowEntry( pThisEntry );
429 while ( !aEditTree.IsEntryVisible( pThisEntry ) && ( pThisEntry = aEditTree.GetParent( pThisEntry ) ) != NULL )
430 aEditTree.InvalidateEntry( pThisEntry );
434 SvLBoxEntry* GetEntry( SvLBoxEntry* pParent, ULONG nPos ) const { return SvLBox::GetEntry(pParent,nPos); }
435 SvLBoxEntry* GetEntry( ULONG nRootPos ) const { return SvLBox::GetEntry(nRootPos);}
439 SvLBoxEntry* FirstChild(SvLBoxEntry* pParent ) const { return (SvLBoxEntry*)(pModel->FirstChild(pParent)); }
440 SvLBoxEntry* NextSibling(SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(pModel->NextSibling( pEntry )); }
441 SvLBoxEntry* PrevSibling(SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(pModel->PrevSibling( pEntry )); }
443 SvLBoxEntry* FirstSelected() const { return (SvLBoxEntry*)SvListView::FirstSelected(); }
444 SvLBoxEntry* NextSelected( SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(SvListView::NextSelected(pEntry)); }
445 SvLBoxEntry* PrevSelected( SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(SvListView::PrevSelected(pEntry)); }
446 SvLBoxEntry* LastSelected() const { return (SvLBoxEntry*)(SvListView::LastSelected()); }
448 SvLBoxEntry* GetEntry( SvLBoxEntry* pParent, ULONG nPos ) const { return (SvLBoxEntry*)(pModel->GetEntry(pParent,nPos)); }
449 SvLBoxEntry* GetEntry( ULONG nRootPos ) const { return (SvLBoxEntry*)(pModel->GetEntry(nRootPos)); }
451 SvLBoxEntry* GetParent( SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(pModel->GetParent(pEntry)); }
452 SvLBoxEntry* GetRootLevelParent(SvLBoxEntry* pEntry ) const { return (SvLBoxEntry*)(pModel->GetRootLevelParent( pEntry ));}
454 BOOL IsInChildList( SvListEntry* pParent, SvListEntry* pChild) const;
455 SvListEntry* GetEntry( SvListEntry* pParent, ULONG nPos ) const;
456 SvListEntry* GetEntry( ULONG nRootPos ) const;
457 SvListEntry* GetEntryAtAbsPos( ULONG nAbsPos ) const;
458 SvListEntry* GetParent( SvListEntry* pEntry ) const;
459 SvListEntry* GetRootLevelParent( SvListEntry* pEntry ) const;
462 //#define CHECK( pMemo ) if ( pMemo && !aEditTree.GetViewData( pMemo ) ) pMemo = NULL
463 #define CHECK( pMemo ) if ( pMemo && !aEditTree.GetModel()->IsInChildList( NULL, pMemo ) ) pMemo = NULL
464 void MsgEdit::Delete()
466 aEditTree.RemoveSelection();
467 CHECK( pCurrentRun );
468 CHECK( pCurrentTestCase );
469 CHECK( pCurrentAssertion );
470 CHECK( pCurrentError );
471 bModified = TRUE;
472 lModify.Call( NULL );
475 void MsgEdit::Cut(){ Copy(); Delete(); bModified = TRUE; lModify.Call( NULL ); }
476 void MsgEdit::Copy(){ ::svt::OStringTransfer::CopyString( GetSelected(), &aEditTree ); }
477 /**/void MsgEdit::Paste(){ Sound::Beep(); }
478 void MsgEdit::Undo(){ Sound::Beep(); }
479 void MsgEdit::Redo(){ Sound::Beep(); }
482 String MsgEdit::Impl_MakeText( SvLBoxEntry *pEntry ) const
484 String aRet;
485 TTDebugData *aData = (TTDebugData*)pEntry->GetUserData();
486 switch ( aData->aLogType )
488 case LOG_RUN: aRet.AppendAscii("\n"); break;
489 case LOG_TEST_CASE: break;
490 case LOG_ERROR: break;
491 case LOG_CALL_STACK:aRet.AppendAscii("--> "); break;
492 case LOG_MESSAGE: break;
493 case LOG_WARNING: break;
494 case LOG_ASSERTION: break;
495 case LOG_ASSERTION_STACK:aRet.AppendAscii("--> "); break;
496 case LOG_QA_ERROR: break;
497 default:DBG_ERROR("Unknown type in ResultWindow!");
499 aRet += aEditTree.GetEntryText( pEntry );
500 return aRet;
503 String MsgEdit::Impl_MakeSaveText( TTDebugData aData ) const
505 // LogType;Filename;Line;Col1;Col2;Message
506 String aRet;
507 aRet += String::CreateFromInt32( (int)aData.aLogType );
508 aRet += ';';
509 aRet += aData.aFilename;
510 aRet += ';';
511 aRet += String::CreateFromInt32( aData.nLine );
512 aRet += ';';
513 aRet += String::CreateFromInt32( aData.nCol1 );
514 aRet += ';';
515 aRet += String::CreateFromInt32( aData.nCol2 );
516 aRet += ';';
517 aRet += '"';
518 aRet += aData.aMsg;
519 aRet += '"';
520 return aRet;
523 String MsgEdit::Impl_MakeSaveText( SvLBoxEntry *pEntry ) const
525 // LogType;Filename;Line;Col1;Col2;Message
526 String aRet;
527 TTDebugData *aData = (TTDebugData*)pEntry->GetUserData();
529 if ( aEditTree.PrevSibling( pEntry ) && LOGTYPE( aEditTree.PrevSibling( pEntry ) ) == LOG_TEST_CASE )
530 { // To properly finish cases and warnings/msgs are in correct hierarchie
531 aRet += String::CreateFromInt32( (int)LOG_TEST_CASE );
532 aRet.AppendAscii(";;0;0;0;\"\"\n");
534 aRet += Impl_MakeSaveText( *aData );
535 return aRet;
538 String MsgEdit::GetSelected()
540 String aRet;
541 SvLBoxEntry *pEntry = aEditTree.FirstSelected();
542 while ( pEntry )
544 aRet += Impl_MakeText( pEntry );
545 aRet += '\n';
546 pEntry = aEditTree.NextSelected( pEntry );
548 aRet.ConvertLineEnd();
549 return aRet;
552 TextSelection MsgEdit::GetSelection() const
554 ULONG nStart=0,nEnd=0;
556 if ( aEditTree.FirstSelected() )
558 nStart = aEditTree.GetModel()->GetAbsPos(aEditTree.FirstSelected() );
559 if ( aEditTree.LastSelected() )
560 nEnd = aEditTree.GetModel()->GetAbsPos(aEditTree.LastSelected() );
561 return TextSelection( TextPaM( nStart, 0 ), TextPaM( nEnd, STRING_MAXLEN ) );
563 else
564 return TextSelection();
567 void MsgEdit::SetSelection( const TextSelection& rSelection )
569 ULONG nStart,nEnd;
571 while ( aEditTree.GetSelectionCount() )
572 aEditTree.Select( aEditTree.FirstSelected(), FALSE );
574 if ( rSelection.HasRange() )
576 nStart = rSelection.GetStart().GetPara();
577 nEnd = rSelection.GetEnd().GetPara();
579 for ( ULONG i = nStart ; i <= nEnd ; i++ )
580 aEditTree.Select( aEditTree.GetModel()->GetEntryAtAbsPos( i ), TRUE );
584 USHORT MsgEdit::GetLineNr() const
586 if ( aEditTree.GetCurEntry() )
587 return (USHORT)aEditTree.GetModel()->GetAbsPos(aEditTree.GetCurEntry() ) + 1;
588 else
589 return 0;
592 void MsgEdit::ReplaceSelected( const String& rStr )
594 (void) rStr; /* avoid warning about unused parameter */
595 Sound::Beep();
596 DBG_ERROR("Not Implemented");
599 BOOL MsgEdit::IsModified(){ return bModified; }
600 void MsgEdit::SetModifyHdl( Link l ){ lModify = l; }
602 String MsgEdit::GetText() const
604 String aRet;
605 SvLBoxEntry *pEntry = aEditTree.First();
606 while ( pEntry )
608 aRet += Impl_MakeText( pEntry );
609 aRet += '\n';
610 pEntry = aEditTree.Next( pEntry );
612 aRet.ConvertLineEnd();
613 return aRet;
616 void MsgEdit::SetText( const String& rStr )
618 (void) rStr; /* avoid warning about unused parameter */
619 Sound::Beep();
620 DBG_ERROR("Not Implemented");
623 BOOL MsgEdit::HasText() const
625 return aEditTree.First() != NULL;
628 // Search from the beginning or mark start + 1
629 BOOL MsgEdit::Find( const String& s )
631 TextSelection r = GetSelection();
632 USHORT bgn = (USHORT) r.GetStart().GetPara() + 1;
633 if ( r.GetStart().GetPara() == 0 )
634 bgn = 0; // Search from the beginning
636 SvLBoxEntry *pEntry = aEditTree.GetModel()->GetEntryAtAbsPos( bgn );
637 while ( pEntry )
639 if( aEditTree.GetEntryText( pEntry ).Search( s, 0 ) != STRING_NOTFOUND )
641 aEditTree.SetCurEntry( pEntry );
642 return TRUE;
644 pEntry = aEditTree.Next( pEntry );
646 return FALSE;
649 /******************************************************************
651 Fileformat of *.res file:
652 Information are stored as semicolon separated strings
653 Order:
655 LogType;Filename;Line;Col1;Col2;Message
657 ******************************************************************/
659 BOOL MsgEdit::Load( const String& aName )
661 aLogFileName = aName;
662 BOOL bOk = TRUE, bFirstLine = TRUE;
663 BOOL bLoadError = FALSE;
664 SvFileStream aStrm( aName, STREAM_STD_READ );
665 if( aStrm.IsOpen() )
667 aEditTree.Clear();
668 String aLine;
669 bFileLoading = TRUE; // To avoid logging to disk
670 TTLogMsg *pLogMsg = new TTLogMsg;
671 while( !aStrm.IsEof() && bOk )
673 if ( nVersion >= 3 ) // utf8
674 aStrm.ReadByteStringLine( aLine, RTL_TEXTENCODING_UTF8 );
675 else
676 aStrm.ReadByteStringLine( aLine, RTL_TEXTENCODING_IBM_850 );
678 if( aStrm.GetError() != SVSTREAM_OK )
679 bOk = FALSE;
681 #define TOKEN( n ) aLine.GetToken( n )
683 if ( aLine.GetTokenCount() >= 6 )
685 // LogType;Filename;Line;Col1;Col2;Message
686 TTDebugData aDebugData;
687 aDebugData.aLogType = TTLogType( TOKEN(0).ToInt32() );
688 aDebugData.aFilename = TOKEN(1);
689 aDebugData.nLine = USHORT( TOKEN(2).ToInt32() );
690 aDebugData.nCol1 = USHORT( TOKEN(3).ToInt32() );
691 aDebugData.nCol2 = USHORT( TOKEN(4).ToInt32() );
692 aDebugData.aMsg = aLine.GetQuotedToken( 5, CUniString("\"\"") );
694 // Remove leading and trailing quotes
695 aDebugData.aMsg.Erase(0,1);
696 aDebugData.aMsg.Erase(aDebugData.aMsg.Len()-1,1);
698 pLogMsg->aLogFileName.Erase();
699 pLogMsg->aDebugData = aDebugData;
701 AddAnyMsg( pLogMsg );
703 else if ( bFirstLine && (aLine.Search( VERSION_STRING ) == 0) )
704 nVersion = USHORT( aLine.Copy( VERSION_STRING.Len() ).ToInt32() );
705 else if ( aLine.Len() )
706 bLoadError = TRUE;
708 bFirstLine = FALSE;
710 bFileLoading = FALSE;
711 delete pLogMsg;
712 aStrm.Close();
713 if ( nVersion < 2 && !bLoadError )
714 Save( aName ); // Necessary to avoid mess
717 else
718 bOk = FALSE;
719 return bOk;
722 BOOL MsgEdit::Save( const String& aName )
724 BOOL bOk = TRUE;
725 BOOL bIsText = DirEntry( aName ).GetExtension().CompareIgnoreCaseToAscii("TXT") == COMPARE_EQUAL;
726 if ( bIsText && !QueryBox( NULL, SttResId( IDS_LOSS_OF_INFORMATION ) ).Execute() )
727 return FALSE;
728 SvFileStream aStrm( aName, STREAM_STD_WRITE | STREAM_TRUNC );
729 if( aStrm.IsOpen() )
731 if ( bIsText )
733 String aSave = GetText();
734 aSave.ConvertLineEnd(LINEEND_CRLF);
735 aStrm << ByteString( aSave, RTL_TEXTENCODING_UTF8 ).GetBuffer();
737 else
739 // LogType;Filename;Line;Col1;Col2;Message
740 String aSave = VERSION_STRING.Append( UniString::CreateFromInt32( 3 ) ).AppendAscii("\n"); // Version 3
741 SvLBoxEntry *pRun = aEditTree.First();
742 while ( pRun && aEditTree.NextSibling( pRun ) )
743 pRun = aEditTree.NextSibling( pRun );
745 aSave.ConvertLineEnd(LINEEND_CRLF);
746 aStrm << ByteString( aSave, RTL_TEXTENCODING_IBM_850 ).GetBuffer();
748 SvLBoxEntry *pEntry;
749 while ( pRun )
751 pEntry = pRun;
752 while ( pEntry && ( pEntry == pRun || LOGTYPE( pEntry ) != LOG_RUN ) )
754 aSave = Impl_MakeSaveText( pEntry );
755 aSave += '\n';
756 aSave.ConvertLineEnd(LINEEND_CRLF);
757 aStrm << ByteString( aSave, RTL_TEXTENCODING_UTF8 ).GetBuffer();
758 pEntry = aEditTree.Next( pEntry );
760 pRun = aEditTree.PrevSibling( pRun );
764 if( aStrm.GetError() != SVSTREAM_OK )
765 bOk = FALSE;
766 else
768 bModified = FALSE;
769 lModify.Call( NULL );
773 else
774 bOk = FALSE;
775 return bOk;
779 TTTreeListBox::TTTreeListBox( AppError* pParent, BasicFrame* pBF, WinBits nWinStyle )
780 : SvTreeListBox( pParent, nWinStyle )
781 , pBasicFrame(pBF)
782 , pAppError( pParent )
783 //, nDeselectParent(0)
786 BOOL TTTreeListBox::JumpToSourcecode( SvLBoxEntry *pThisEntry )
788 if ( pThisEntry && pThisEntry->GetUserData() && ((TTDebugData*)pThisEntry->GetUserData())->aFilename.Len() > 0 )
790 TTDebugData *aData = (TTDebugData*)pThisEntry->GetUserData();
791 String aFilename = aData->aFilename;
792 if ( aData->aFilename.GetChar(0) == '~' )
794 if ( aData->aFilename.GetChar(1) == '-' )
796 aFilename.Erase( 0,2 );
798 else
800 aFilename.Erase( 0,1 );
801 DirEntry aConvert( pAppError->aBaseDir );
802 aConvert += DirEntry( aFilename, FSYS_STYLE_VFAT );
803 aFilename = aConvert.GetFull();
807 if ( pBasicFrame->FindModuleWin( aFilename ) )
809 AppWin *pWin = pBasicFrame->FindModuleWin( aFilename );
810 pWin->ToTop();
812 else if ( pBasicFrame->Basic().FindModule( CUniString( "--" ).Append( aFilename ) ) )
814 SbModule* pMod = pBasicFrame->Basic().FindModule( CUniString( "--" ).Append( aFilename ) );
815 pBasicFrame->CreateModuleWin( pMod );
817 else
818 pBasicFrame->LoadFile( aFilename );
820 if ( pBasicFrame->pWork && pBasicFrame->pWork->ISA(AppEdit) )
821 ((AppEdit*)pBasicFrame->pWork)->Highlight( aData->nLine, aData->nCol1, aData->nCol2 );
822 return FALSE;
824 return TRUE;
827 BOOL TTTreeListBox::DoubleClickHdl()
829 return JumpToSourcecode( GetHdlEntry() );
832 /*ULONG TTTreeListBox::SelectChildren( SvLBoxEntry* pParent, BOOL bSelect )
834 SvLBoxEntry *pEntry = FirstChild( pParent );
835 ULONG nRet = 0;
836 while ( pEntry )
838 nRet++;
839 Select( pEntry, bSelect );
840 pEntry = NextSibling( pEntry );
842 return nRet;
846 void TTTreeListBox::SelectHdl()
848 SvLBoxEntry* pHdlEntry = GetHdlEntry();
850 SelectChildren( pHdlEntry, TRUE );
851 Select( pHdlEntry, TRUE );
852 // InitMenu(pApp->GetAppMenu()->GetPopupMenu( RID_APPEDIT )); // So daß Delete richtig ist
855 void TTTreeListBox::DeselectHdl()
857 SvLBoxEntry* pHdlEntry = GetHdlEntry();
858 if ( GetParent( pHdlEntry ) )
860 nDeselectParent++;
861 Select( GetParent( pHdlEntry ), FALSE );
862 nDeselectParent--;
864 if ( !nDeselectParent )
866 SelectChildren( pHdlEntry, FALSE );
867 Select( pHdlEntry, FALSE );
869 Invalidate();
870 } */
873 void TTTreeListBox::KeyInput( const KeyEvent& rKEvt )
875 switch ( rKEvt.GetKeyCode().GetFunction() )
877 case KEYFUNC_CUT:
878 Control::GetParent()->Command( CommandEvent( Point(), RID_EDITCUT ) );
879 break;
880 case KEYFUNC_COPY:
881 Control::GetParent()->Command( CommandEvent( Point(), RID_EDITCOPY ) );
882 break;
883 case KEYFUNC_PASTE:
884 Control::GetParent()->Command( CommandEvent( Point(), RID_EDITPASTE ) );
885 break;
886 case KEYFUNC_DELETE:
887 Control::GetParent()->Command( CommandEvent( Point(), RID_EDITDEL ) );
888 break;
889 default:
890 if ( rKEvt.GetKeyCode().GetCode() == KEY_RETURN )
891 JumpToSourcecode( GetCurEntry() );
892 else
893 SvTreeListBox::KeyInput( rKEvt );
898 TTFeatures TTTreeListBox::GetFeatures( SvLBoxEntry* pEntry )
900 switch ( LOGTYPE( pEntry ) )
902 case LOG_MESSAGE:
903 return HasNothing;
904 case LOG_WARNING :
905 return HasWarning;
906 case LOG_ERROR:
907 case LOG_CALL_STACK:
908 return HasError;
909 case LOG_RUN:
910 case LOG_TEST_CASE:
912 SvLBoxEntry* pThisEntry = FirstChild( pEntry );
913 TTFeatures aResult = HasNothing;
914 while ( pThisEntry && !( (aResult & HasError) == HasError ) )
916 if ( !IsEntryVisible( pThisEntry ) )
917 aResult |= GetFeatures( pThisEntry );
918 pThisEntry = NextSibling( pThisEntry );
920 return aResult;
922 case LOG_ASSERTION:
923 case LOG_ASSERTION_STACK:
924 return HasAssertion;
925 case LOG_QA_ERROR:
926 return HasQAError;
927 default:
928 DBG_ERROR("Unknown type in ResultWindow");
930 return HasNothing;
934 class TTLBoxString : public SvLBoxString
936 public:
938 TTLBoxString( SvLBoxEntry* pEntry, USHORT nFlags,
939 const String& rStr ) : SvLBoxString(pEntry,nFlags,rStr) {}
941 virtual void Paint( const Point& rPos, SvLBox& rDev, USHORT nFlags,
942 SvLBoxEntry* pEntry);
946 void TTLBoxString::Paint( const Point& rPos, SvLBox& rDev, USHORT nFlags,
947 SvLBoxEntry* pEntry )
949 TTFeatures aFeatures = ((TTTreeListBox*)&rDev)->GetFeatures( pEntry );
951 Font aOldFont( rDev.GetFont());
952 Font aFont( aOldFont );
953 if ( aFeatures != HasNothing )
955 Color aCol;
956 if ( ( aFeatures & HasError ) == HasError )
957 aCol = Color( 255, 130, 130 ); // Red
958 else if ( ( aFeatures & HasWarning ) == HasWarning )
959 aCol = Color( 255, 200, 120 ); // Ocker oder so
960 else if ( ( aFeatures & HasAssertion ) == HasAssertion )
961 aCol = Color( 0xd0, 0xd0, 0xff ); // blueish
962 else
963 aCol = Color( 0xd0, 0xff, 0xd0 ); // greenish
965 if( rDev.IsSelected(pEntry) )
966 aFont.SetColor( aCol );
967 else
969 aFont.SetFillColor( aCol );
970 aFont.SetTransparent( FALSE );
971 Color aCol2( COL_BLACK );
972 aFont.SetColor( aCol2 );
975 rDev.SetFont( aFont );
976 rDev.DrawText( rPos, GetText() );
978 else
980 if( !rDev.IsSelected(pEntry) )
982 Color aCol( COL_BLACK );
983 aFont.SetColor( aCol );
985 rDev.SetFont( aFont );
986 SvLBoxString::Paint( rPos, rDev, nFlags, pEntry );
988 rDev.SetFont( aOldFont );
992 void TTTreeListBox::InitEntry(SvLBoxEntry* pEntry,
993 const String& rStr ,const Image& rImg1, const Image& rImg2,
994 SvLBoxButtonKind eButtonKind )
996 USHORT nColToHilite = 1; //0==Bitmap;1=="Column1";2=="Column2"
997 SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
998 SvLBoxString* pCol = (SvLBoxString*)pEntry->GetItem( nColToHilite );
999 TTLBoxString* pStr = new TTLBoxString( pEntry, 0, pCol->GetText() );
1000 pEntry->ReplaceItem( pStr, nColToHilite );