From VisualWorks®, 7.6 of February 8, 2008 on March 3, 2008 at 9:41:48 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <class> <name>LogEnvironment</name> <environment>Tools</environment> <super>UI.Model</super> <private>false</private> none debugStream debugCategories debugClasses trace logFileName <imports></imports> <category>Tools-Logging Tool</category> <attributes> <package>LoggingTool</package> </attributes> </class> <comment> Tools.LogEnvironment
Now the LogEnvironment class is used mostly for tracing and debugging purposes. Instance Variables: debugStream <Stream> The debugged class put the information to the stream to display it using Logging Tool debugCategories <Collection> The list of debug categories from the debugged classes debugClasses <Collection> The list of registered classes to debug trace <Boolean> Turns on and off the debug logFileName <String> The name of external file to file out the debug information Class Variables: Environment <LogEnvironment> To be register for debugging the class should implement the following protocol: 1. Specify the list of the class categories to debug aClass class >>debugLabelsAndValues ^List new add: ('IMAP Client Messages'->#IMAPClient); add: ('IMAP Server Messages'->#IMAPServer); yourself 2. Menu item name for the class in Logging Tool aClass class >>menuItemName ^'IMAPClient Messages' 3. Register with the LogEnvironment registerToDebug Tools.LogEnvironment default addToDebug: self To print the debugging information into Logging Tool can be used LogEnvironment default log: aString level: aLevel
</comment> <class> <name>LoggingTool</name> <environment>Tools</environment> <super>UI.ApplicationModel</super> <private>false</private> none model <imports></imports> <category>Tools-Logging Tool</category> <attributes> <package>LoggingTool</package> </attributes> </class> <comment> Tools.LoggingTool
Logging Tool is a user interface to display debugging information. Instance Variables: Class Variables: LastBounds <Rectangle> The interface size MyCollector <LogTextCollector> Collects debugging information
</comment> <class> <name>LogTextCollector</name> <environment>Tools</environment> <super>UI.TextCollector</super> <private>false</private> none <imports></imports> <category>Tools-Logging Tool</category> <attributes> <package>LoggingTool</package> </attributes> </class> <comment> Tools.LogTextCollector
Class LogTextCollector represents a ValueHolder for LoggingTool class Instance Variables:
</comment> <name>LastBounds</name> <environment>Tools.LoggingTool</environment> <private>false</private> <constant>false</constant> <category>unknown</category> <attributes> <package>LoggingTool</package> </attributes> <name>MyCollector</name> <environment>Tools.LoggingTool</environment> <private>false</private> <constant>false</constant> <category>constants</category> <attributes> <package>LoggingTool</package> </attributes> <name>CharacterLimit</name> <environment>Tools.LogTextCollector</environment> <private>false</private> <constant>false</constant> <category>constants</category> <initializer>50000</initializer> <attributes> <package>LoggingTool</package> </attributes> <name>Environment</name> <environment>Tools.LogEnvironment</environment> <private>false</private> <constant>false</constant> <category>default</category> <initializer></initializer> <attributes> <package>LoggingTool</package> </attributes> <methods> Tools.LogEnvironment <category>private</category>
addDebugCategory: symbol self debugCategories add: symbol
removeDebugCategory: symbol self debugCategories remove: symbol
reset self resetDebugClasses. self resetDebugCategories.
resetDebugCategories debugCategories := nil
resetDebugClasses debugClasses := nil
</methods> <methods> Tools.LogEnvironment <category>registration</category>
addToDebug: aClass self debugClasses add: aClass.
</methods> <methods> Tools.LogEnvironment <category>debugging</category>
debug: aBlock level: aLevel ( self trace and: [ self debugCategories includes: aLevel ] ) ifTrue: [ aBlock value]
log: aStringOrBlock self log: aStringOrBlock level: #general
log: aStringOrBlock level: aLevel | stream i briefMsg aMsg | self debug: [(stream := self debugStream) == nil ifTrue: [^self]. aMsg := ((aStringOrBlock isKindOf: BlockClosure) ifTrue: [ aStringOrBlock value ] ifFalse: [ aStringOrBlock ]) asString. i := aMsg size. [i > 0 and: [(aMsg at: i) isSeparator]] whileTrue: [i := i - 1]. briefMsg := aMsg copyFrom: 1 to: i. stream cr; nextPutAll: briefMsg; cr; flush] level: aLevel
printTrace: aString | stream | (stream := self debugStream) == nil ifTrue: [^self]. stream cr; cr; nextPutAll: ' **** ' asString. Date today printOn: stream. stream nextPutAll: ' '. Time now printOn: stream. stream nextPutAll: ' ', aString asString, ' ****'; flush.
traceOff self printTrace: (#StopTrace << #dialogs >> 'Stop Trace'). self trace: false.
traceOn self trace: true. self printTrace: (#StartTrace << #dialogs >> 'Start Trace').
</methods> <methods> Tools.LogEnvironment <category>accessing</category>
debugCategories debugCategories isNil ifTrue: [ debugCategories := Set new. debugCategories add: #general ]. ^debugCategories
debugClasses ^debugClasses isNil ifTrue: [ debugClasses := Set new.] ifFalse: [ debugClasses ].
debugStream ^debugStream
debugStream: aStream debugStream := aStream
logFileName logFileName isNil ifTrue: [ logFileName := 'LogOutput.txt']. ^ logFileName
logFileName: aString logFileName := aString
trace trace isNil ifTrue: [ trace := false]. ^ trace
trace: aBoolean trace := aBoolean
</methods> <methods> Tools.LogEnvironment <category>actions</category>
getFileName "Prompt the user for a filename and open the file." | fileName | fileName := self logFileName. fileName := Dialog requestFileName: (#PleaseEnterFileName << #dialogs >> 'Please, enter file name ') default: fileName. ^fileName isEmpty ifTrue: [nil] ifFalse: [ fileName]
saveOutput "Prompt the user for a filename and save the log in to this file." | fileName logFile | (fileName := self getFileName) isNil ifTrue: [ ^nil]. logFile := (Filename named: fileName) writeStream. [logFile nextPutAll: self debugStream value string. logFile flush. ] ensure: [ logFile close ].
</methods> <methods> Tools.LogEnvironment class <category>accessing</category>
default ^ Environment isNil ifTrue: [ Environment := self new ] ifFalse: [ Environment ].
</methods> <methods> Tools.LoggingTool <category>private</category>
buildLoggingMenu | logMenu | logMenu := Menu new. self debugClasses do: [ :debugClass | | item submenu | item := MenuItem labeled: debugClass menuItemName. submenu := Menu new. debugClass debugLabelsAndValues do: [ :association | | menuitem | menuitem := MenuItem labeled: association key. menuitem indication: [ self debugCategories includes: association value ]. menuitem value: [( self debugCategories includes: association value) ifTrue: [ self environment removeDebugCategory: association value] ifFalse: [ self environment addDebugCategory: association value]]. submenu addItem: menuitem. ]. item submenu: submenu. logMenu addItem: item. ]. ^logMenu
buildTracingMenu | menu menuitem | menu := Menu new. menuitem := MenuItem labeled: (#TraceON << #dialogs >> 'Trace ON'). menuitem value: [ self environment traceOn ]. menuitem indication: [ self environment trace ]. menu addItem: menuitem. menuitem := MenuItem labeled: (#TraceOFF << #dialogs >> 'Trace OFF'). menuitem value: [ self environment traceOff ]. menuitem indication: [ self environment trace not ]. menu addItem: menuitem. ^menu.
debugCategories ^self environment debugCategories
debugClasses ^self environment debugClasses
</methods> <methods> Tools.LoggingTool <category>menu messages</category>
clear "Clears output." self textCollector clear.
saveOutput ^self environment saveOutput
</methods> <methods> Tools.LoggingTool <category>views</category>
collector | textCollectorView | textCollectorView := TextCollectorView model: self textCollector. textCollectorView editText: self textCollector value. textCollectorView controller: ParagraphEditor new. ^textCollectorView
</methods> <methods> Tools.LoggingTool <category>accessing</category>
environment ^self model
model model isNil ifTrue: [model := LogEnvironment default. model addDependent: self]. ^model
model: aLogEnvironment model := aLogEnvironment. model addDependent: self.
textCollector ^self class myCollector
</methods> <methods> Tools.LoggingTool <category>update</category>
noticeOfWindowClose: aWindow "The ApplicationWindow aWindow is in the process of closing." model removeDependent: self. super noticeOfWindowClose: aWindow
</methods> <methods> Tools.LoggingTool <category>interface opening</category>
postBuildWith: aBuilder super postBuildWith: aBuilder. ((builder menuAt: #windowMenu) atNameKey: #logging) submenu: self buildLoggingMenu. ((builder menuAt: #windowMenu) atNameKey: #trace) submenu: self buildTracingMenu. self environment debugStream: self textCollector.
postOpenWith: aBuilder | view | super postOpenWith: aBuilder. view := (aBuilder componentAt: #collector) widget. view selectionIndex: view text size + 1. view selectAndScroll. view deselect.
</methods> <methods> Tools.LoggingTool class <category>accessing</category>
clear self myCollector clear
initCollector MyCollector := nil
lastBounds "Clients should check for nil." ^LastBounds
lastBounds: rectangle LastBounds := rectangle
myCollector MyCollector isNil ifTrue: [ MyCollector := LogTextCollector new ]. ^ MyCollector
</methods> <methods> Tools.LoggingTool class <category>class-initialization</category>
obsolete MyCollector := nil. super obsolete
</methods> <methods> Tools.LoggingTool class <category>interface opening</category>
open "Open an Interface. If an interface is already open raise it." self raiseSingleInstance isNil ifTrue: [^super open]
openWith: aLogEnvironment "Open an interface. If an interface is already open raise it." | obj | (obj := self new) model: aLogEnvironment. obj open.
</methods> <methods> Tools.LogTextCollector <category>entry control</category>
beginEntry "use a text stream" entryStream := TextStream on: (String new: CharacterLimit)
</methods> <methods> Tools.LogTextCollector <category>private</category>
characterLimit ^characterLimit isNil ifTrue: [characterLimit := CharacterLimit] ifFalse: [characterLimit]
</methods> <methods> Tools.LogTextCollector <category>accessing</category>
nextPutAll: aCollection "Append all the characters in aCollection to the text." ^entryStream nextPutAllText: aCollection
</methods> <methods> Tools.LoggingTool class <category>resources</category>
windowMenu "MenuEditor new openOnClass: self andSelector: #windowMenu" <resource: #menu> ^#(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_File #defaultString: '&File' #catalogID: #menus) #nameKey: #file #submenu: #(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #SaveOutput #defaultString: 'Save Output...' #catalogID: #menus) #value: #saveOutput ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #ClearLog #defaultString: 'Clear log' #catalogID: #menus) #value: #clear ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #E_xit #defaultString: 'E&xit' #catalogID: #menus) #value: #closeRequest #shortcutKeyCharacter: $x ) ) #(2 1 ) nil ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Logging #defaultString: '&Logging' #catalogID: #menus) #nameKey: #logging ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Utils #defaultString: '&Utils' #catalogID: #menus) #nameKey: #utils #submenu: #(#{UI.Menu} #( #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #InspectDots #defaultString: 'Inspect...' #catalogID: #menus) #value: #inspect ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #BrowseDot #defaultString: 'Browse...' #catalogID: #menus) #value: #browse ) ) #(2 ) nil ) ) #(#{UI.MenuItem} #rawLabel: #(#{Kernel.UserMessage} #key: #_Trace #defaultString: '&Trace' #catalogID: #menus) #nameKey: #trace ) ) #(4 ) nil ) decodeAsLiteralArray
</methods> <methods> Tools.LoggingTool class <category>interface specs</category>
windowSpec "UIPainter new openOnClass: self andSelector: #windowSpec" <resource: #canvas> ^#(#{UI.FullSpec} #window: #(#{UI.WindowSpec} #label: #(#{Kernel.UserMessage} #key: #LogWindow #defaultString: 'Log Window' #catalogID: #labels) #bounds: #(#{Graphics.Rectangle} 293 265 732 503 ) #flags: 4 #menu: #windowMenu #isEventDriven: true ) #component: #(#{UI.SpecCollection} #collection: #( #(#{UI.ArbitraryComponentSpec} #layout: #(#{Graphics.LayoutFrame} 0 0.00683371 0 0.0178571 0 0.995444 0 0.986607 ) #name: #collector #flags: 9 #component: #collector ) ) ) )
</methods> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>Model</name> <environment>UI</environment> <super>Core.Object</super> <private>false</private> none dependents <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>ApplicationModel</name> <environment>UI</environment> <super>UI.Model</super> <private>false</private> none builder uiSession eventHandlers savedWindowInformation <imports></imports> <category>UIBuilder-Framework</category> <attributes> <package>UIBuilder-Framework</package> </attributes> </class> <class> <name>TextCollector</name> <environment>UI</environment> <super>UI.ValueHolder</super> <private>false</private> none entryStream characterLimit writeSequencer nextEntry autoFlush <imports></imports> <category>Interface-Support</category> <attributes> <package>Interface-Support</package> </attributes> </class>