1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dbg_lay.cxx,v $
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_sw.hxx"
34 /* -----------------08.01.99 14:55-------------------
35 * Und hier die Beschreibung:
37 * Durch die PROTOCOL-Makros wird es ermoeglicht, Ereignisse im Frame-Methoden zu protokollieren.
38 * In protokollwuerdigen Stellen in Frame-Methoden muss entweder ein PROTOCOL(...) oder bei Methoden,
39 * bei denen auch das Verlassen der Methode mitprotokolliert werden soll, ein PROTOCOL_ENTER(...)-Makro
41 * Die Parameter der PROTOCOL-Makros sind
42 * 1. Ein Pointer auf einen SwFrm, also meist "this" oder "rThis"
43 * 2. Die Funktionsgruppe z.B. PROT_MAKEALL, hierueber wird (inline) entschieden, ob dies
44 * zur Zeit protokolliert werden soll oder nicht.
45 * 3. Die Aktion, im Normalfall 0, aber z.B. ein ACT_START bewirkt eine Einrueckung in der
46 * Ausgabedatei, ein ACT_END nimmt dies wieder zurueck. Auf diese Art wird z.B. durch
47 * PROTOCOL_ENTER am Anfang einer Methode eingerueckt und beim Verlassen wieder zurueck.
48 * 4. Der vierte Parameter ist ein void-Pointer, damit man irgendetwas uebergeben kann,
49 * was in das Protokoll einfliessen kann, typesches Beispiel bei PROT_GROW muss man
50 * einen Pointer auf den Wert, um den gegrowt werden soll, uebergeben.
53 * Das Protokoll ist die Datei "dbg_lay.out" im aktuellen (BIN-)Verzeichnis.
54 * Es enthaelt Zeilen mit FrmId, Funktionsgruppe sowie weiteren Infos.
56 * Was genau protokolliert wird, kann auf folgende Arten eingestellt werden:
57 * 1. Die statische Variable SwProtokoll::nRecord enthaelt die Funktionsgruppen,
58 * die aufgezeichnet werden sollen.
59 * Ein Wert von z.B. PROT_GROW bewirkt, das Aufrufe von SwFrm::Grow dokumentiert werden,
60 * PROT_MAKEALL protokolliert Aufrufe von xxx::MakeAll.
61 * Die PROT_XY-Werte koennen oderiert werden.
62 * Default ist Null, es wird keine Methode aufgezeichnet.
63 * 2. In der SwImplProtocol-Klasse gibt es einen Filter fuer Frame-Typen,
64 * nur die Methodenaufrufe von Frame-Typen, die dort gesetzt sind, werden protokolliert.
65 * Der Member nTypes kann auf Werte wie FRM_PAGE, FRM_SECTION gesetzt und oderiert werden.
66 * Default ist 0xFFFF, d.h. alle Frame-Typen.
67 * 3. In der SwImplProtocol-Klasse gibt es einen ArrayPointer auf FrmIds, die zu ueberwachen sind.
68 * Ist der Pointer Null, so werden alle Frames protokolliert, ansonsten nur Frames,
69 * die in dem Array vermerkt sind.
71 * Eine Aufzeichnung in Gang zu setzen, erfordert entweder Codemanipulation, z.B. in
72 * SwProtocol::Init() einen anderen Default fuer nRecord setzen oder Debuggermanipulation.
73 * Im Debugger gibt verschiedene, sich anbietende Stellen:
74 * 1. In SwProtocol::Init() einen Breakpoint setzen und dort nRecord manipulieren, ggf.
75 * FrmIds eintragen, dann beginnt die Aufzeichnung bereits beim Programmstart.
76 * 2. Waehrend des Programmlaufs einen Breakpoint vor irgendein PROTOCOL oder PROTOCOL_ENTER-
77 * Makro setzen, dann am SwProtocol::nRecord das unterste Bit setzen (PROT_INIT). Dies
78 * bewirkt, dass die Funktionsgruppe des folgenden Makros aktiviert und in Zukunft
80 * 3. Spezialfall von 2.: Wenn man 2. in der Methode SwRootFrm::Paint(..) anwendet, werden
81 * die Aufzeichnungseinstellung aus der Datei "dbg_lay.ini" ausgelesen!
82 * In dieser INI-Datei kann es Kommentarzeilen geben, diese beginnen mit '#', dann
83 * sind die Sektionen "[frmid]", "[frmtype]" und "[record]" relevant.
84 * Nach [frmid] koennen die FrameIds der zu protokollierenden Frames folgen. Gibt es
85 * dort keine Eintraege, werden alle Frames aufgezeichnet.
86 * Nach [frmtype] koennen FrameTypen folgen, die aufgezeichnet werden sollen, da der
87 * Default hier allerdings USHRT_MAX ist, werden sowieso alle aufgezeichnet. Man kann
88 * allerdings auch Typen entfernen, in dem man ein '!' vor den Wert setzt, z.B.
89 * !0xC000 nimmt die SwCntntFrms aus der Aufzeichnung heraus.
90 * Nach [record] folgen die Funktionsgruppen, die aufgezeichnet werden sollen, Default
91 * ist hier 0, also keine. Auch hier kann man mit einem vorgestellten '!' Funktionen
93 * Hier mal ein Beispiel fuer eine INI-Datei:
94 * ------------------------------------------
95 * #Funktionen: Alle, ausser PRTAREA
96 * [record] 0xFFFFFFE !0x200
100 * #keine Layoutframes ausser ColumnFrms
101 * [frmtype] !0x3FFF 0x4
102 * ------------------------------------------
104 * Wenn die Aufzeichnung erstmal laeuft, kann man in SwImplProtocol::_Record(...) mittels
105 * Debugger vielfaeltige Manipulationen vornehmen, z.B. bezueglich FrameTypen oder FrmIds.
107 * --------------------------------------------------*/
110 #error Wer fummelt denn an den makefiles rum?
115 #include "dbg_lay.hxx"
116 #include <tools/stream.hxx>
118 #ifndef _SVSTDARR_HXX
119 #define _SVSTDARR_USHORTS
120 #define _SVSTDARR_USHORTSSORT
121 #define _SVSTDARR_LONGS
122 #include <svtools/svstdarr.hxx>
128 #include "layfrm.hxx"
129 #include "flyfrm.hxx"
130 #include "txtfrm.hxx"
132 #include "dflyobj.hxx"
133 #include <fntcache.hxx>
134 // OD 2004-05-24 #i28701#
135 #include <sortedobjs.hxx>
137 ULONG
SwProtocol::nRecord
= 0;
138 SwImplProtocol
* SwProtocol::pImpl
= NULL
;
140 ULONG
lcl_GetFrameId( const SwFrm
* pFrm
)
143 static BOOL bFrameId
= FALSE
;
145 return pFrm
->GetFrmId();
147 if( pFrm
&& pFrm
->IsTxtFrm() )
148 return ((SwTxtFrm
*)pFrm
)->GetTxtNode()->GetIndex();
154 SvFileStream
*pStream
; // Ausgabestream
155 SvUShortsSort
*pFrmIds
; // welche FrmIds sollen aufgezeichnet werden ( NULL == alle )
156 SvLongs
*pVar
; // Variables
157 ByteString aLayer
; // Einrueckung der Ausgabe (" " pro Start/End)
158 USHORT nTypes
; // welche Typen sollen aufgezeichnet werden
159 USHORT nLineCount
; // Ausgegebene Zeilen
160 USHORT nMaxLines
; // Maximal auszugebende Zeilen
161 BYTE nInitFile
; // Bereich (FrmId,FrmType,Record) beim Einlesen der INI-Datei
162 BYTE nTestMode
; // Special fuer Testformatierung, es wird ggf. nur
163 // innerhalb einer Testformatierung aufgezeichnet.
164 void _Record( const SwFrm
* pFrm
, ULONG nFunction
, ULONG nAct
, void* pParam
);
166 void CheckLine( ByteString
& rLine
);
167 void SectFunc( ByteString
&rOut
, const SwFrm
* pFrm
, ULONG nAct
, void* pParam
);
172 void Record( const SwFrm
* pFrm
, ULONG nFunction
, ULONG nAct
, void* pParam
)
173 { if( pStream
) _Record( pFrm
, nFunction
, nAct
, pParam
); }
174 BOOL
InsertFrm( USHORT nFrmId
); // FrmId aufnehmen zum Aufzeichnen
175 BOOL
DeleteFrm( USHORT nFrmId
); // FrmId entfernen, diesen nicht mehr Aufzeichnen
176 void FileInit(); // Auslesen der INI-Datei
177 void ChkStream() { if( !pStream
) NewStream(); }
178 void SnapShot( const SwFrm
* pFrm
, ULONG nFlags
);
179 void GetVar( const USHORT nNo
, long& rVar
)
180 { if( pVar
&& nNo
< pVar
->Count() ) rVar
= (*pVar
)[ nNo
]; }
183 /* -----------------11.01.99 10:43-------------------
184 * Durch das PROTOCOL_ENTER-Makro wird ein SwEnterLeave-Objekt erzeugt,
185 * wenn die aktuelle Funktion aufgezeichnet werden soll, wird ein
186 * SwImplEnterLeave-Objekt angelegt. Der Witz dabei ist, das der Ctor
187 * des Impl-Objekt am Anfang der Funktion und automatisch der Dtor beim
188 * Verlassen der Funktion gerufen wird. In der Basis-Implementierung ruft
189 * der Ctor lediglich ein PROTOCOL(..) mit ACT_START und im Dtor ein
190 * PROTOCOL(..) mit ACT_END.
191 * Es lassen sich Ableitungen der Klasse bilden, um z.B. beim Verlassen
192 * einer Funktion Groessenaenderungen des Frames zu dokumentieren u.v.a.m.
193 * Dazu braucht dann nur noch in SwEnterLeave::Ctor(...) die gewuenschte
194 * SwImplEnterLeave-Klasse angelegt zu werden.
196 * --------------------------------------------------*/
198 class SwImplEnterLeave
201 const SwFrm
* pFrm
; // Der Frame,
202 ULONG nFunction
, nAction
; // die Funktion, ggf. die Aktion
203 void* pParam
; // und weitere Parameter
205 SwImplEnterLeave( const SwFrm
* pF
, ULONG nFunct
, ULONG nAct
, void* pPar
)
206 : pFrm( pF
), nFunction( nFunct
), nAction( nAct
), pParam( pPar
) {}
207 virtual void Enter(); // Ausgabe beim Eintritt
208 virtual void Leave(); // Ausgabe beim Verlassen
211 class SwSizeEnterLeave
: public SwImplEnterLeave
215 SwSizeEnterLeave( const SwFrm
* pF
, ULONG nFunct
, ULONG nAct
, void* pPar
)
216 : SwImplEnterLeave( pF
, nFunct
, nAct
, pPar
), nFrmHeight( pF
->Frm().Height() ) {}
217 virtual void Leave(); // Ausgabe der Groessenaenderung
220 class SwUpperEnterLeave
: public SwImplEnterLeave
224 SwUpperEnterLeave( const SwFrm
* pF
, ULONG nFunct
, ULONG nAct
, void* pPar
)
225 : SwImplEnterLeave( pF
, nFunct
, nAct
, pPar
), nFrmId( 0 ) {}
226 virtual void Enter(); // Ausgabe
227 virtual void Leave(); // Ausgabe der FrmId des Uppers
230 class SwFrmChangesLeave
: public SwImplEnterLeave
234 SwFrmChangesLeave( const SwFrm
* pF
, ULONG nFunct
, ULONG nAct
, void* pPar
)
235 : SwImplEnterLeave( pF
, nFunct
, nAct
, pPar
), aFrm( pF
->Frm() ) {}
236 virtual void Enter(); // keine Ausgabe
237 virtual void Leave(); // Ausgabe bei Aenderung der Frm-Area
240 void SwProtocol::Record( const SwFrm
* pFrm
, ULONG nFunction
, ULONG nAct
, void* pParam
)
243 { // Hier landen wir, wenn im Debugger SwProtocol::nRecord mit PROT_INIT(0x1) oderiert wurde
244 BOOL bFinit
= FALSE
; // Dies bietet im Debugger die Moeglichkeit,
245 if( bFinit
) // die Aufzeichnung dieser Action zu beenden
247 nRecord
&= ~nFunction
; // Diese Funktion nicht mehr aufzeichnen
248 nRecord
&= ~PROT_INIT
; // PROT_INIT stets zuruecksetzen
251 nRecord
|= nFunction
; // Aufzeichnung dieser Funktion freischalten
252 nRecord
&= ~PROT_INIT
; // PROT_INIT stets zuruecksetzen
256 if( !pImpl
) // Impl-Object anlegen, wenn noetig
257 pImpl
= new SwImplProtocol();
258 pImpl
->Record( pFrm
, nFunction
, nAct
, pParam
); // ...und Aufzeichnen
261 // Die folgende Funktion wird beim Anziehen der Writer-DLL durch TxtInit(..) aufgerufen
262 // und ermoeglicht dem Debuggenden Funktionen und/oder FrmIds freizuschalten
264 void SwProtocol::Init()
267 XubString
aName( "dbg_lay.go", RTL_TEXTENCODING_MS_1252
);
268 SvFileStream
aStream( aName
, STREAM_READ
);
269 if( aStream
.IsOpen() )
271 pImpl
= new SwImplProtocol();
277 // Ende der Aufzeichnung
279 void SwProtocol::Stop()
291 // Creates a more or less detailed snapshot of the layout structur
293 void SwProtocol::SnapShot( const SwFrm
* pFrm
, ULONG nFlags
)
296 pImpl
->SnapShot( pFrm
, nFlags
);
299 void SwProtocol::GetVar( const USHORT nNo
, long& rVar
)
302 pImpl
->GetVar( nNo
, rVar
);
305 SwImplProtocol::SwImplProtocol()
306 : pStream( NULL
), pFrmIds( NULL
), pVar( NULL
), nTypes( 0xffff ),
307 nLineCount( 0 ), nMaxLines( USHRT_MAX
), nTestMode( 0 )
312 BOOL
SwImplProtocol::NewStream()
314 XubString
aName( "dbg_lay.out", RTL_TEXTENCODING_MS_1252
);
316 pStream
= new SvFileStream( aName
, STREAM_WRITE
| STREAM_TRUNC
);
317 if( pStream
->GetError() )
325 SwImplProtocol::~SwImplProtocol()
336 /* -----------------11.01.99 11:03-------------------
337 * SwImplProtocol::CheckLine analysiert eine Zeile der INI-Datei
338 * --------------------------------------------------*/
340 void SwImplProtocol::CheckLine( ByteString
& rLine
)
342 rLine
= rLine
.ToLowerAscii(); // Gross/Kleinschreibung ist einerlei
343 while( STRING_LEN
> rLine
.SearchAndReplace( '\t', ' ' ) )
344 ; //nothing // Tabs werden durch Blanks ersetzt
345 if( '#' == rLine
.GetChar(0) ) // Kommentarzeilen beginnen mit '#'
347 if( '[' == rLine
.GetChar(0) ) // Bereiche: FrmIds, Typen oder Funktionen
349 ByteString aTmp
= rLine
.GetToken( 0, ']' );
350 if( "[frmid" == aTmp
) // Bereich FrmIds
354 pFrmIds
= NULL
; // Default: Alle Frames aufzeichnen
356 else if( "[frmtype" == aTmp
)// Bereich Typen
359 nTypes
= USHRT_MAX
; // Default: Alle FrmaeTypen aufzeichnen
361 else if( "[record" == aTmp
)// Bereich Funktionen
364 SwProtocol::SetRecord( 0 );// Default: Keine Funktion wird aufgezeichnet
366 else if( "[test" == aTmp
)// Bereich Funktionen
368 nInitFile
= 4; // Default:
369 nTestMode
= 0; // Ausserhalb der Testformatierung wird aufgezeichnet
371 else if( "[max" == aTmp
)// maximale Zeilenzahl
373 nInitFile
= 5; // Default:
374 nMaxLines
= USHRT_MAX
;
376 else if( "[var" == aTmp
)// variables
380 pVar
= new SvLongs( 5, 5 );
383 nInitFile
= 0; // Nanu: Unbekannter Bereich?
384 rLine
.Erase( 0, aTmp
.Len() + 1 );
386 USHORT nToks
= rLine
.GetTokenCount( ' ' ); // Blanks (oder Tabs) sind die Trenner
387 for( USHORT i
=0; i
< nToks
; ++i
)
389 ByteString aTok
= rLine
.GetToken( i
, ' ' );
391 if( '!' == aTok
.GetChar(0) )
393 bNo
= TRUE
; // Diese(n) Funktion/Typ entfernen
399 sscanf( aTok
.GetBuffer(), "%li", &nVal
);
402 case 1: InsertFrm( USHORT( nVal
) ); // FrmId aufnehmen
405 USHORT nNew
= (USHORT
)nVal
;
407 nTypes
&= ~nNew
; // Typ entfernen
409 nTypes
|= nNew
; // Typ aufnehmen
413 ULONG nOld
= SwProtocol::Record();
415 nOld
&= ~nVal
; // Funktion entfernen
417 nOld
|= nVal
; // Funktion aufnehmen
418 SwProtocol::SetRecord( nOld
);
422 BYTE nNew
= (BYTE
)nVal
;
424 nTestMode
&= ~nNew
; // TestMode zuruecksetzen
426 nTestMode
|= nNew
; // TestMode setzen
429 case 5: nMaxLines
= (USHORT
)nVal
;
431 case 6: pVar
->Insert( (long)nVal
, pVar
->Count() );
438 /* -----------------11.01.99 11:17-------------------
439 * SwImplProtocol::FileInit() liest die Datei "dbg_lay.ini"
440 * im aktuellen Verzeichnis und wertet sie aus.
441 * --------------------------------------------------*/
442 void SwImplProtocol::FileInit()
444 XubString
aName( "dbg_lay.ini", RTL_TEXTENCODING_MS_1252
);
445 SvFileStream
aStream( aName
, STREAM_READ
);
446 if( aStream
.IsOpen() )
450 while( !aStream
.IsEof() )
454 if( '\n' == c
|| '\r' == c
) // Zeilenende
456 aLine
.EraseLeadingChars();
457 aLine
.EraseTrailingChars();
459 CheckLine( aLine
); // Zeile auswerten
466 CheckLine( aLine
); // letzte Zeile auswerten
471 /* -----------------11.01.99 11:20-------------------
472 * lcl_Start sorgt fuer Einrueckung um zwei Blanks bei ACT_START
473 * und nimmt diese bei ACT_END wieder zurueck.
474 * --------------------------------------------------*/
475 void lcl_Start( ByteString
& rOut
, ByteString
& rLay
, ULONG nAction
)
477 if( nAction
== ACT_START
)
482 else if( nAction
== ACT_END
)
486 rLay
.Erase( rLay
.Len() - 2 );
493 /* -----------------11.01.99 11:21-------------------
494 * lcl_Flags gibt das ValidSize-, ValidPos- und ValidPrtArea-Flag ("Sz","Ps","PA")
495 * des Frames aus, "+" fuer valid, "-" fuer invalid.
496 * --------------------------------------------------*/
498 void lcl_Flags( ByteString
& rOut
, const SwFrm
* pFrm
)
501 rOut
+= pFrm
->GetValidSizeFlag() ? '+' : '-';
503 rOut
+= pFrm
->GetValidPosFlag() ? '+' : '-';
505 rOut
+= pFrm
->GetValidPrtAreaFlag() ? '+' : '-';
508 /* -----------------11.01.99 11:23-------------------
509 * lcl_FrameType gibt den Typ des Frames in Klartext aus.
510 * --------------------------------------------------*/
512 void lcl_FrameType( ByteString
& rOut
, const SwFrm
* pFrm
)
514 if( pFrm
->IsTxtFrm() )
516 else if( pFrm
->IsLayoutFrm() )
518 if( pFrm
->IsPageFrm() )
520 else if( pFrm
->IsColumnFrm() )
522 else if( pFrm
->IsBodyFrm() )
524 if( pFrm
->GetUpper() && pFrm
->IsColBodyFrm() )
528 else if( pFrm
->IsRootFrm() )
530 else if( pFrm
->IsCellFrm() )
532 else if( pFrm
->IsTabFrm() )
534 else if( pFrm
->IsRowFrm() )
536 else if( pFrm
->IsSctFrm() )
538 else if( pFrm
->IsHeaderFrm() )
540 else if( pFrm
->IsFooterFrm() )
542 else if( pFrm
->IsFtnFrm() )
544 else if( pFrm
->IsFtnContFrm() )
546 else if( pFrm
->IsFlyFrm() )
551 else if( pFrm
->IsNoTxtFrm() )
554 rOut
+= "Not impl. ";
557 /* -----------------11.01.99 11:25-------------------
558 * SwImplProtocol::Record(..) wird nur gerufen, wenn das PROTOCOL-Makro
559 * feststellt, dass die Funktion aufgezeichnet werden soll ( SwProtocol::nRecord ).
560 * In dieser Methode werden noch die beiden weiteren Einschraenkungen ueberprueft,
561 * ob die FrmId und der FrameType zu den aufzuzeichnenden gehoeren.
562 * --------------------------------------------------*/
564 void SwImplProtocol::_Record( const SwFrm
* pFrm
, ULONG nFunction
, ULONG nAct
, void* pParam
)
567 if( nSpecial
) // Debugger-Manipulationsmoeglichkeit
569 USHORT nId
= USHORT(lcl_GetFrameId( pFrm
));
572 case 1: InsertFrm( nId
); break;
573 case 2: DeleteFrm( nId
); break;
574 case 3: delete pFrmIds
; pFrmIds
= NULL
; break;
575 case 4: delete pStream
; pStream
= NULL
; break;
579 if( !pStream
&& !NewStream() )
580 return; // Immer noch kein Stream
582 if( pFrmIds
&& !pFrmIds
->Seek_Entry( USHORT(lcl_GetFrameId( pFrm
)) ) )
583 return; // gehoert nicht zu den gewuenschten FrmIds
585 if( !(pFrm
->GetType() & nTypes
) )
586 return; // Der Typ ist unerwuenscht
588 if( 1 == nTestMode
&& nFunction
!= PROT_TESTFORMAT
)
589 return; // Wir sollen nur innerhalb einer Testformatierung aufzeichnen
591 ByteString aOut
= aLayer
;
592 aOut
+= ByteString::CreateFromInt64( lcl_GetFrameId( pFrm
) );
594 lcl_FrameType( aOut
, pFrm
); // dann den FrameType
595 switch ( nFunction
) // und die Funktion
597 case PROT_SNAPSHOT
: lcl_Flags( aOut
, pFrm
);
599 case PROT_MAKEALL
: aOut
+= "MakeAll";
600 lcl_Start( aOut
, aLayer
, nAct
);
601 if( nAct
== ACT_START
)
602 lcl_Flags( aOut
, pFrm
);
604 case PROT_MOVE_FWD
: bTmp
= TRUE
; // NoBreak
605 case PROT_MOVE_BWD
: aOut
+= ( nFunction
== bTmp
) ? "Fwd" : "Bwd";
606 lcl_Start( aOut
, aLayer
, nAct
);
610 aOut
+= ByteString::CreateFromInt32( *((USHORT
*)pParam
) );
613 case PROT_GROW_TST
: if( ACT_START
!= nAct
)
617 case PROT_SHRINK_TST
: if( ACT_START
!= nAct
)
619 aOut
+= "TestShrink";
622 case PROT_SHRINK
: bTmp
= TRUE
; // NoBreak
623 case PROT_GROW
: aOut
+= !bTmp
? "Grow" :
624 ( nFunction
== PROT_SHRINK
? "Shrink" : "AdjustNgbhd" );
625 lcl_Start( aOut
, aLayer
, nAct
);
629 aOut
+= ByteString::CreateFromInt64( *((long*)pParam
) );
632 case PROT_POS
: break;
633 case PROT_PRTAREA
: aOut
+= "PrtArea";
634 lcl_Start( aOut
, aLayer
, nAct
);
636 case PROT_SIZE
: aOut
+= "Size";
637 lcl_Start( aOut
, aLayer
, nAct
);
639 aOut
+= ByteString::CreateFromInt64( pFrm
->Frm().Height() );
641 case PROT_LEAF
: aOut
+= "Prev/NextLeaf";
642 lcl_Start( aOut
, aLayer
, nAct
);
647 aOut
+= ByteString::CreateFromInt64( lcl_GetFrameId( (SwFrm
*)pParam
) );
650 case PROT_FILE_INIT
: FileInit();
653 case PROT_SECTION
: SectFunc( aOut
, pFrm
, nAct
, pParam
);
655 case PROT_CUT
: bTmp
= TRUE
; // NoBreak
656 case PROT_PASTE
: aOut
+= bTmp
? "Cut from " : "Paste to ";
657 aOut
+= ByteString::CreateFromInt64( lcl_GetFrameId( (SwFrm
*)pParam
) );
659 case PROT_TESTFORMAT
: aOut
+= "Test";
660 lcl_Start( aOut
, aLayer
, nAct
);
661 if( ACT_START
== nAct
)
666 case PROT_FRMCHANGES
:
668 SwRect
& rFrm
= *((SwRect
*)pParam
);
669 if( pFrm
->Frm().Pos() != rFrm
.Pos() )
672 aOut
+= ByteString::CreateFromInt64(rFrm
.Left());
674 aOut
+= ByteString::CreateFromInt64(rFrm
.Top());
676 aOut
+= ByteString::CreateFromInt64(pFrm
->Frm().Left());
678 aOut
+= ByteString::CreateFromInt64(pFrm
->Frm().Top());
681 if( pFrm
->Frm().Height() != rFrm
.Height() )
684 aOut
+= ByteString::CreateFromInt64(rFrm
.Height());
686 aOut
+= ByteString::CreateFromInt64(pFrm
->Frm().Height());
689 if( pFrm
->Frm().Width() != rFrm
.Width() )
692 aOut
+= ByteString::CreateFromInt64(rFrm
.Width());
694 aOut
+= ByteString::CreateFromInt64(pFrm
->Frm().Width());
700 *pStream
<< aOut
.GetBuffer() << endl
; // Ausgabe
701 pStream
->Flush(); // Gleich auf die Platte, damit man mitlesen kann
702 if( ++nLineCount
>= nMaxLines
) // Maximale Ausgabe erreicht?
703 SwProtocol::SetRecord( 0 ); // => Ende der Aufzeichnung
706 /* -----------------13.01.99 11:39-------------------
707 * SwImplProtocol::SectFunc(...) wird von SwImplProtocol::_Record(..) gerufen,
708 * hier werden die Ausgaben rund um SectionFrms abgehandelt.
709 * --------------------------------------------------*/
711 void SwImplProtocol::SectFunc( ByteString
&rOut
, const SwFrm
* , ULONG nAct
, void* pParam
)
716 case ACT_MERGE
: rOut
+= "Merge Section ";
717 rOut
+= ByteString::CreateFromInt64( lcl_GetFrameId( (SwFrm
*)pParam
) );
719 case ACT_CREATE_MASTER
: bTmp
= TRUE
; // NoBreak
720 case ACT_CREATE_FOLLOW
: rOut
+= "Create Section ";
721 rOut
+= bTmp
? "Master to " : "Follow from ";
722 rOut
+= ByteString::CreateFromInt64( lcl_GetFrameId( (SwFrm
*)pParam
) );
724 case ACT_DEL_MASTER
: bTmp
= TRUE
; // NoBreak
725 case ACT_DEL_FOLLOW
: rOut
+= "Delete Section ";
726 rOut
+= bTmp
? "Master to " : "Follow from ";
727 rOut
+= ByteString::CreateFromInt64( lcl_GetFrameId( (SwFrm
*)pParam
) );
732 /* -----------------11.01.99 11:31-------------------
733 * SwImplProtocol::InsertFrm(..) nimmt eine neue FrmId zum Aufzeichnen auf,
734 * wenn pFrmIds==NULL, werden alle aufgezeichnet, sobald durch InsertFrm(..)
735 * pFrmIds angelegt wird, werden nur noch die enthaltenen FrmIds aufgezeichnet.
736 * --------------------------------------------------*/
738 BOOL
SwImplProtocol::InsertFrm( USHORT nId
)
741 pFrmIds
= new SvUShortsSort(5,5);
742 if( pFrmIds
->Seek_Entry( nId
) )
744 pFrmIds
->Insert( nId
);
748 /* -----------------11.01.99 11:52-------------------
749 * SwImplProtocol::DeleteFrm(..) entfernt eine FrmId aus dem pFrmIds-Array,
750 * so dass diese Frame nicht mehr aufgezeichnet wird.
751 * --------------------------------------------------*/
752 BOOL
SwImplProtocol::DeleteFrm( USHORT nId
)
755 if( !pFrmIds
|| !pFrmIds
->Seek_Entry( nId
, &nPos
) )
757 pFrmIds
->Remove( nPos
);
761 /*-----------------20.9.2001 10:29------------------
762 * SwProtocol::SnapShot(..)
763 * creates a snapshot of the given frame and its content.
764 * --------------------------------------------------*/
765 void SwImplProtocol::SnapShot( const SwFrm
* pFrm
, ULONG nFlags
)
769 _Record( pFrm
, PROT_SNAPSHOT
, 0, 0);
770 if( pFrm
->GetDrawObjs() && nFlags
& SNAP_FLYFRAMES
)
773 const SwSortedObjs
&rObjs
= *pFrm
->GetDrawObjs();
774 for ( USHORT i
= 0; i
< rObjs
.Count(); ++i
)
776 SwAnchoredObject
* pObj
= rObjs
[i
];
777 if ( pObj
->ISA(SwFlyFrm
) )
778 SnapShot( static_cast<SwFlyFrm
*>(pObj
), nFlags
);
780 if( aLayer
.Len() > 1 )
781 aLayer
.Erase( aLayer
.Len() - 2 );
783 if( pFrm
->IsLayoutFrm() && nFlags
& SNAP_LOWER
&&
784 ( !pFrm
->IsTabFrm() || nFlags
& SNAP_TABLECONT
) )
787 SnapShot( ((SwLayoutFrm
*)pFrm
)->Lower(), nFlags
);
788 if( aLayer
.Len() > 1 )
789 aLayer
.Erase( aLayer
.Len() - 2 );
791 pFrm
= pFrm
->GetNext();
795 /* -----------------11.01.99 11:53-------------------
796 * SwEnterLeave::Ctor(..) wird vom eigentlichen (inline-)Kontruktor gerufen,
797 * wenn die Funktion aufgezeichnet werden soll.
798 * Die Aufgabe ist es abhaengig von der Funktion das richtige SwImplEnterLeave-Objekt
799 * zu erzeugen, alles weitere geschieht dann in dessen Ctor/Dtor.
800 * --------------------------------------------------*/
801 void SwEnterLeave::Ctor( const SwFrm
* pFrm
, ULONG nFunc
, ULONG nAct
, void* pPar
)
807 case PROT_SHRINK
: pImpl
= new SwSizeEnterLeave( pFrm
, nFunc
, nAct
, pPar
); break;
809 case PROT_MOVE_BWD
: pImpl
= new SwUpperEnterLeave( pFrm
, nFunc
, nAct
, pPar
); break;
810 case PROT_FRMCHANGES
: pImpl
= new SwFrmChangesLeave( pFrm
, nFunc
, nAct
, pPar
); break;
811 default: pImpl
= new SwImplEnterLeave( pFrm
, nFunc
, nAct
, pPar
); break;
816 /* -----------------11.01.99 11:56-------------------
817 * SwEnterLeave::Dtor() ruft lediglich den Destruktor des SwImplEnterLeave-Objekts,
818 * ist nur deshalb nicht inline, damit die SwImplEnterLeave-Definition nicht
819 * im dbg_lay.hxx zu stehen braucht.
820 * --------------------------------------------------*/
822 void SwEnterLeave::Dtor()
831 void SwImplEnterLeave::Enter()
833 SwProtocol::Record( pFrm
, nFunction
, ACT_START
, pParam
);
836 void SwImplEnterLeave::Leave()
838 SwProtocol::Record( pFrm
, nFunction
, ACT_END
, pParam
);
841 void SwSizeEnterLeave::Leave()
843 nFrmHeight
= pFrm
->Frm().Height() - nFrmHeight
;
844 SwProtocol::Record( pFrm
, nFunction
, ACT_END
, &nFrmHeight
);
847 void SwUpperEnterLeave::Enter()
849 nFrmId
= pFrm
->GetUpper() ? USHORT(lcl_GetFrameId( pFrm
->GetUpper() )) : 0;
850 SwProtocol::Record( pFrm
, nFunction
, ACT_START
, &nFrmId
);
853 void SwUpperEnterLeave::Leave()
855 nFrmId
= pFrm
->GetUpper() ? USHORT(lcl_GetFrameId( pFrm
->GetUpper() )) : 0;
856 SwProtocol::Record( pFrm
, nFunction
, ACT_END
, &nFrmId
);
859 void SwFrmChangesLeave::Enter()
863 void SwFrmChangesLeave::Leave()
865 if( pFrm
->Frm() != aFrm
)
866 SwProtocol::Record( pFrm
, PROT_FRMCHANGES
, 0, &aFrm
);