diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index 1e2d001..9f75365 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -225,25 +225,21 @@ DSRecordBrowserPresenterTest >> testGetHistoryFrom [ ] { #category : 'tests' } -DSRecordBrowserPresenterTest >> testGetRecordColorAssociationsFrom [ +DSRecordBrowserPresenterTest >> testGetNumberOfEventsPerType [ - | windows colorAssociations | - windows := { (DSWindowRecord new - toolInfo: (DSToolInfo new - toolClass: StPlaygroundPresenter; - yourself); - events: { - DSWindowOpenedRecord new. - DSDoItRecord new. - DSStepThroughRecord new }) } asOrderedCollection. + | dict | + browser selectedHistory: (DSRecordHistory on: { + (DSMouseEnterWindowRecord new windowId: 1). + (DSBrowseRecord new windowId: 1). + (DSBrowseRecord new windowId: 1). + (DSMouseLeaveWindowRecord new windowId: 1) }). - colorAssociations := browser getRecordColorAssociationsFrom: windows. - - self assert: colorAssociations first key class equals: DSWindowOpenedRecord. - self assert: (colorAssociations at: 2) key class equals: DSDoItRecord. - self assert: colorAssociations last key class equals: DSStepThroughRecord. - - colorAssociations do: [ :association | self assert: association value equals: (Color fromHexString: '#70B77E') ] + dict := browser getNumberOfEventsPerType. + self assert: dict keys size equals: DSAbstractEventRecord getLeafSubClasses size. + self assert: (dict at: DSMouseEnterWindowRecord) equals: 1. + self assert: (dict at: DSBrowseRecord) equals: 2. + self assert: (dict at: DSMouseLeaveWindowRecord) equals: 1. + self assert: (dict at: DSWindowOpenedRecord) equals: 0 ] { #category : 'tests' } @@ -385,6 +381,53 @@ DSRecordBrowserPresenterTest >> testStopRecording [ self assert: browser timerWindow isNil ] +{ #category : 'tests' } +DSRecordBrowserPresenterTest >> testUpdateActivityPresenter [ + + | presenter records jumps history | + presenter := browser presenterAt: #activityPresenter. + records := OrderedCollection new + add: (DSMouseEnterWindowRecord new + windowId: 1; + dateTime: (DateAndTime fromSeconds: 1)); + add: (DSBrowseRecord new + windowId: 1; + dateTime: (DateAndTime fromSeconds: 6)); + add: (DSMouseLeaveWindowRecord new + windowId: 1; + dateTime: (DateAndTime fromSeconds: 8)); + add: (DSMouseEnterWindowRecord new + windowId: 2; + dateTime: (DateAndTime fromSeconds: 9)); + add: (DSInspectItRecord new + windowId: 2; + dateTime: (DateAndTime fromSeconds: 10)); + add: (DSMouseLeaveWindowRecord new + windowId: 2; + dateTime: (DateAndTime fromSeconds: 15)); + yourself. + + jumps := OrderedCollection new + add: (DSWindowActivityRecord start: records first stop: records third events: { + records first. + records second. + records third }); + add: (DSWindowActivityRecord start: records fourth stop: records sixth events: { + records fourth. + records fifth. + records sixth }); + yourself. + + self assert: presenter roots isEmpty. + history := DSRecordHistory on: records. + history windowJumps: jumps. + + browser selectedHistory: history. + browser updateActivityPresenter. + + self assert: presenter roots equals: jumps +] + { #category : 'tests' } DSRecordBrowserPresenterTest >> testUpdateLastRecord [ @@ -402,28 +445,26 @@ DSRecordBrowserPresenterTest >> testUpdateLastRecord [ ] { #category : 'tests' } -DSRecordBrowserPresenterTest >> testUpdateRecordsTable [ +DSRecordBrowserPresenterTest >> testUpdateRecordTypesPresenter [ - | fileRef | - fileRef := self generateRecordsFile. - browser selectedHistory: (browser getHistoryFrom: fileRef). - browser updateRecordsTable. + | presenter | + presenter := browser presenterAt: #recordTypesPresenter. + self assert: presenter roots isEmpty. + browser selectedHistory: (browser getHistoryFrom: self generateRecordsFile). + browser updateRecordTypesPresenter. - self assert: self recordsTablePresenter roots first key class equals: DSBrowseRecord. - self assert: (self recordsTablePresenter roots at: 2) key class equals: DSMouseEnterWindowRecord. - self assert: (self recordsTablePresenter roots at: 3) key class equals: DSMouseLeaveWindowRecord. - self assert: self recordsTablePresenter roots last key class equals: DSInspectItRecord + self assert: presenter roots equals: browser getNumberOfEventsPerType associations ] { #category : 'tests' } -DSRecordBrowserPresenterTest >> testUpdateRecordsTableWhenAddingFile [ +DSRecordBrowserPresenterTest >> testUpdateRecordsPresenterWith [ - browser addFile: self generateRecordsFile. + | presenter records | + presenter := browser recordsPresenter. + records := self getRecordExamples. + browser updateRecordsPresenter: presenter with: (DSWindowRecord new events: records). - self assert: self recordsTablePresenter roots first key class equals: DSBrowseRecord. - self assert: (self recordsTablePresenter roots at: 2) key class equals: DSMouseEnterWindowRecord. - self assert: (self recordsTablePresenter roots at: 3) key class equals: DSMouseLeaveWindowRecord. - self assert: self recordsTablePresenter roots last key class equals: DSInspectItRecord + self assert: presenter roots equals: records ] { #category : 'tests' } @@ -436,13 +477,23 @@ DSRecordBrowserPresenterTest >> testUpdateStatisticsPresenter [ browser updateStatisticsPresenter. children := self statisticsPresenter children. - self assert: children size equals: 5. + self assert: children size equals: 15. self assert: children keys first label equals: 'Number of events: 4'. - self assert: children keys second label equals: 'Number of windows: 4'. - self assert: children keys third label equals: 'Time taken: 00:00:03'. - self assert: children keys fourth label equals: 'Idle time: 00:00:00'. - self assert: children keys last label equals: 'Absolute time taken: 00:00:03' + self assert: (children keys at: 2) label equals: 'Number of windows: 4'. + self assert: (children keys at: 3) label equals: 'Time taken: 00:00:03'. + self assert: (children keys at: 4) label equals: 'Idle time: 00:00:00'. + self assert: (children keys at: 5) label equals: 'Absolute time taken: 00:00:03'. + self assert: (children keys at: 6) label equals: 'Number of debug actions: 1'. + self assert: (children keys at: 7) label equals: 'Date: ' , (DateAndTime fromSeconds: 1) asString. + self assert: (children keys at: 8) label equals: 'Debug points added: 0'. + self assert: (children keys at: 9) label equals: 'Debug points hit: 0'. + self assert: (children keys at: 10) label equals: 'Debug points removed: 0'. + self assert: (children keys at: 11) label equals: 'Methods added: 0'. + self assert: (children keys at: 12) label equals: 'Methods modified: 0'. + self assert: (children keys at: 13) label equals: 'Methods removed: 0'. + self assert: (children keys at: 14) label equals: 'Number of steps: 0'. + self assert: (children keys at: 15) label equals: 'Executed code: 1' ] { #category : 'tests' } diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index abe1e32..28a6b7b 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -18,7 +18,11 @@ Class { 'stopRecordButtonPresenter', 'windowsPresenter', 'statisticsPresenter', - 'selectedHistory' + 'selectedHistory', + 'recordTypesPresenter', + 'activityPresenter', + 'activityRecordsPresenter', + 'windowsRecordsPresenter' ], #classInstVars : [ 'uniqueInstance' @@ -111,6 +115,50 @@ DSRecordBrowserPresenter class >> windowType [ ^ 'Debugging Spy' ] +{ #category : 'accessing' } +DSRecordBrowserPresenter >> activityLayout [ + "Returns the layout that displays the activity table and the selected records if applicable." + + ^ SpPanedLayout newTopToBottom + add: activityPresenter; + add: activityRecordsPresenter; + positionOfSlider: 70 percent +] + +{ #category : 'layout' } +DSRecordBrowserPresenter >> activityPresenter [ + "Instanciates a new table that displays the windows and their events as children. For each column, the manipulated object could be either a DSWindowRecord or a record that inherits from DSAbstractEventRecord." + + | presenter | + presenter := self newTreeTable. + + ^ presenter + addColumn: (SpStringTableColumn new + width: 4; + beNotSortable; + displayBackgroundColor: [ :windowJump | windowJump windowColor ]; + evaluated: [ :windowJump | '' ]); + addColumn: (SpStringTableColumn new + title: 'Window'; + evaluated: [ :windowJump | windowJump window asString ]); + addColumn: (SpStringTableColumn new + title: 'Start'; + evaluated: [ :windowJump | windowJump start printAsFormattedTime ]); + addColumn: (SpStringTableColumn new + title: 'Stop'; + evaluated: [ :windowJump | windowJump stop printAsFormattedTime ]); + addColumn: (SpStringTableColumn new + title: 'Duration'; + evaluated: [ :windowJump | windowJump duration ]); + addColumn: (SpStringTableColumn new + title: 'Number of events'; + evaluated: [ :windowJump | windowJump events size ]); + beResizable; + actions: (SpActionGroup new + add: (self commonActionsFor: presenter); + yourself) +] + { #category : 'files' } DSRecordBrowserPresenter >> addFile: aFileReference [ "Adds a file in the presenter and set is as selected, which updates the records displayed." @@ -131,8 +179,7 @@ DSRecordBrowserPresenter >> addRecordButton [ label: 'Add'; icon: (self iconNamed: #smallAdd); help: 'Add a new record.'; - action: [ self openAddFileDialog ]; - yourself + action: [ self openAddFileDialog ] ] { #category : 'layout' } @@ -143,15 +190,33 @@ DSRecordBrowserPresenter >> colorReferential [ addColumn: (SpStringTableColumn new title: 'Color'; evaluated: [ :association | '' ]; - displayBackgroundColor: [ :association | association key ]; - yourself); + displayBackgroundColor: [ :association | association key ]); addColumn: (SpStringTableColumn new title: 'Window type'; - evaluated: [ :association | association value ]; - yourself); + evaluated: [ :association | association value ]); roots: (self class colorAssociations sort: [ :a :b | a key hue <= b key hue ]); - beResizable; - yourself + beResizable +] + +{ #category : 'actions' } +DSRecordBrowserPresenter >> commonActionsFor: aPresenter [ + "Return a list of actions which can be done on every presenter." + + ^ SpActionGroup new + addActionWith: [ :anItem | + anItem + name: 'Inspect'; + iconName: #inspect; + description: 'Inspect the selected item'; + shortcutKey: $i meta; + action: [ aPresenter selectedItem inspect ] ]; + addActionWith: [ :anItem | + anItem + name: 'Inspect history'; + iconName: #history; + description: 'Inspect the history'; + shortcutKey: $h meta; + action: [ selectedHistory inspect ] ] ] { #category : 'initialization' } @@ -160,11 +225,23 @@ DSRecordBrowserPresenter >> connectPresenters [ fileListPresenter whenSelectionChangedDo: [ selectedHistory := self getHistoryFrom: fileListPresenter selectedItem. - self updateRecordsTable. + self updateRecordsPresenter: recordsTablePresenter with: selectedHistory. + self updateWindowsPresenter. - self updateStatisticsPresenter ]. + self updateStatisticsPresenter. + self updateRecordTypesPresenter. + self updateActivityPresenter ]. + + recordsFilter whenChangedDo: [ + self updateRecordsPresenter: recordsTablePresenter with: selectedHistory. + self updateRecordsPresenter: windowsRecordsPresenter with: windowsPresenter selectedItem. + self updateRecordsPresenter: activityRecordsPresenter with: activityPresenter selectedItem ]. + + windowsPresenter whenSelectedItemChangedDo: [ :selectedItem | + self updateRecordsPresenter: windowsRecordsPresenter with: selectedItem ]. - recordsFilter whenChangedDo: [ self updateRecordsTable ] + activityPresenter whenSelectedItemChangedDo: [ :selectedItem | + self updateRecordsPresenter: activityRecordsPresenter with: selectedItem ] ] { #category : 'layout' } @@ -177,65 +254,49 @@ DSRecordBrowserPresenter >> defaultLayout [ add: (SpPanedLayout newTopToBottom add: fileListPresenter; add: self colorReferential; - positionOfSlider: 57 percent; - yourself); - add: (SpBoxLayout newTopToBottom - add: (SpTabLayout new - add: recordsTablePresenter label: 'Records'; - add: windowsPresenter label: 'Windows'; - add: statisticsPresenter label: 'Statistics'; - yourself); - yourself); - yourself) + positionOfSlider: 57 percent); + add: (SpTabLayout new + add: self activityLayout label: 'Activity'; + add: recordsTablePresenter label: 'Records'; + add: statisticsPresenter label: 'Statistics'; + add: recordTypesPresenter label: 'Types'; + add: self windowsLayout label: 'Windows')) +] + +{ #category : 'actions' } +DSRecordBrowserPresenter >> fileActionsFor: aPresenter [ + "Return a list of actions which can be done on a file." + + ^ SpActionGroup new addActionWith: [ :anItem | + anItem + name: 'Remove'; + iconName: #remove; + description: 'Remove the file from list'; + shortcutKey: $x meta; + action: [ self removeFile: aPresenter selectedItem ] ] ] { #category : 'layout' } DSRecordBrowserPresenter >> fileListPresenter [ "Instanciates a new presenter with a list of added files." - ^ self newTreeTable + | presenter | + presenter := self newTreeTable. + ^ presenter addColumn: (SpStringTableColumn new evaluated: [ :file | file basenameWithoutExtension ]; - beNotSortable; - yourself); + beNotSortable); roots: self files; children: [ :file | file isDirectory ifTrue: [ file children ] ifFalse: [ { } ] ]; - actions: self fileListPresenterActions; + actions: (SpActionGroup new + add: (self commonActionsFor: presenter); + add: (self fileActionsFor: presenter)); hideColumnHeaders ] -{ #category : 'layout' } -DSRecordBrowserPresenter >> fileListPresenterActions [ - "Returns a list of actions for the list of added files. Action are: inspecting raw records, inspecting history, or removing the selected file from the list." - - ^ SpActionGroup new - addActionWith: [ :anItem | - anItem - name: 'Inspect'; - iconName: #inspect; - description: 'Inspect the raw records'; - shortcutKey: $i meta; - action: [ selectedHistory events inspect ] ]; - addActionWith: [ :anItem | - anItem - name: 'Inspect history'; - iconName: #history; - description: 'Inspect the record history'; - shortcutKey: $h meta; - action: [ selectedHistory inspect ] ]; - addActionWith: [ :anItem | - anItem - name: 'Remove'; - iconName: #remove; - description: 'Remove the record from list'; - shortcutKey: $x meta; - action: [ self removeFile: fileListPresenter selectedItem ] ]; - yourself -] - { #category : 'accessing' } DSRecordBrowserPresenter >> files [ @@ -264,8 +325,7 @@ DSRecordBrowserPresenter >> filterRecordsButton [ label: 'Filter'; icon: (self iconNamed: #diff); help: 'Filter records.'; - action: [ recordsFilter open ]; - yourself + action: [ recordsFilter open ] ] { #category : 'helpers' } @@ -277,17 +337,15 @@ DSRecordBrowserPresenter >> getHistoryFrom: aFileReference [ ] { #category : 'helpers' } -DSRecordBrowserPresenter >> getRecordColorAssociationsFrom: aWindowRecordCollection [ - "Returns a sorted collection associating each record with its window's corresponding color, sorted by record's dateTime." +DSRecordBrowserPresenter >> getNumberOfEventsPerType [ + "Returns a list of dictionary that associates each type of records to the number of records of this type in the selected history." - | recordColorsAssociations | - recordColorsAssociations := OrderedCollection new. - - aWindowRecordCollection do: [ :windowRecord | - recordColorsAssociations addAll: - (windowRecord events collect: [ :record | record -> windowRecord windowColor ]) ]. - - ^ recordColorsAssociations sorted: [ :recordA :recordB | recordA key dateTime < recordB key dateTime ] + | dict | + dict := Dictionary new. + DSAbstractEventRecord getLeafSubClasses do: [ :recordClass | dict at: recordClass put: 0 ]. + selectedHistory ifNotNil: [ + selectedHistory events do: [ :record | dict at: record class update: [ :nbOfRecords | nbOfRecords + 1 ] ] ]. + ^ dict ] { #category : 'helpers' } @@ -316,10 +374,14 @@ DSRecordBrowserPresenter >> initializePresenters [ stopRecordButtonPresenter := self stopRecordButton. toolbarPresenter := self toolbar. fileListPresenter := self fileListPresenter. - recordsTablePresenter := self recordsTable. + recordsTablePresenter := self recordsPresenter. recordsFilter := self recordsFilter. windowsPresenter := self windowsPresenter. - statisticsPresenter := self statisticsPresenter + statisticsPresenter := self statisticsPresenter. + recordTypesPresenter := self recordTypesPresenter. + activityPresenter := self activityPresenter. + windowsRecordsPresenter := self recordsPresenter. + activityRecordsPresenter := self recordsPresenter ] { #category : 'testing' } @@ -346,67 +408,73 @@ DSRecordBrowserPresenter >> openAddFileDialog [ ] { #category : 'layout' } -DSRecordBrowserPresenter >> recordsFilter [ - "Instanciates a new chooser that displays every record classes that could be used to filter records in table." - - ^ SpChooserPresenter new sourceItems: DSAbstractEventRecord getLeafSubClasses -] - -{ #category : 'layout' } -DSRecordBrowserPresenter >> recordsTable [ - "Instanciates a new records table that displays data based on the selected file's records." +DSRecordBrowserPresenter >> recordTypesPresenter [ + "Instanciates a new table that displays the record types and some information about them." ^ self newTreeTable - addColumn: (SpStringTableColumn new - displayBackgroundColor: [ :association | association key windowColor ]; - width: 4; - beNotSortable; - evaluated: [ :association | '' ]; - yourself); - addColumn: (SpStringTableColumn new - title: 'Event'; - evaluated: [ :association | association key eventName asString ]; - yourself); addColumn: (SpStringTableColumn new title: 'Type'; - evaluated: [ :association | association key class asString ]; - yourself); + evaluated: [ :association | association key name ]); addColumn: (SpStringTableColumn new - title: 'Time'; - evaluated: [ :association | association key printAsFormattedTime ]; - yourself); - beResizable; - actions: self recordsTableActions; - yourself + title: 'Number of records'; + evaluated: [ :association | association value ]); + beResizable ] -{ #category : 'layout' } -DSRecordBrowserPresenter >> recordsTableActions [ - "Return a list of actions which can be done on a record from the table. For example, inspect the selected record." +{ #category : 'actions' } +DSRecordBrowserPresenter >> recordsActionsFor: aPresenter [ + "Return a list of actions which can be done on a record." ^ SpActionGroup new - addActionWith: [ :anItem | - anItem - name: 'Inspect'; - iconName: #inspect; - description: 'Inspect the raw records'; - shortcutKey: $i meta; - action: [ recordsTablePresenter selectedItem key inspect ] ]; addActionWith: [ :anItem | anItem name: 'Inspect the window'; iconName: #window; description: 'Inspect the record window'; shortcutKey: $w meta; - action: [ (self getWindowFromRecord: recordsTablePresenter selectedItem key) inspect ] ]; + action: [ (self getWindowFromRecord: aPresenter selectedItem) inspect ] ]; addActionWith: [ :anItem | anItem name: 'Filter this type of records'; iconName: #packageAdd; description: 'Filter this type of records'; shortcutKey: $f meta; - action: [ self filterRecordClass: recordsTablePresenter selectedItem key class ] ]; - yourself + action: [ self filterRecordClass: aPresenter selectedItem class ] ] +] + +{ #category : 'layout' } +DSRecordBrowserPresenter >> recordsFilter [ + "Instanciates a new chooser that displays every record classes that could be used to filter records in table." + + ^ SpChooserPresenter new sourceItems: DSAbstractEventRecord getLeafSubClasses +] + +{ #category : 'layout' } +DSRecordBrowserPresenter >> recordsPresenter [ + "Instanciates a new records table that displays data based on the selected records in windows or activity tabs." + + | presenter | + presenter := self newTreeTable. + + ^ presenter + addColumn: (SpStringTableColumn new + displayBackgroundColor: [ :record | record windowColor ]; + width: 4; + beNotSortable; + evaluated: [ :record | '' ]); + addColumn: (SpStringTableColumn new + title: 'Event'; + evaluated: [ :record | record asString ]); + addColumn: (SpStringTableColumn new + title: 'Type'; + evaluated: [ :record | record class name ]); + addColumn: (SpStringTableColumn new + title: 'Time'; + evaluated: [ :record | record printAsFormattedTime ]); + actions: (SpActionGroup new + add: (self commonActionsFor: presenter); + add: (self recordsActionsFor: presenter)); + beResizable ] { #category : 'files' } @@ -439,8 +507,7 @@ DSRecordBrowserPresenter >> startRecordButton [ icon: (self iconNamed: #glamorousGo); help: 'Start recording events.'; action: [ self startRecording ]; - enabled: DSSpy recordingSession not; - yourself + enabled: DSSpy recordingSession not ] { #category : 'recording' } @@ -459,9 +526,7 @@ DSRecordBrowserPresenter >> startRecording [ DSRecordBrowserPresenter >> statisticsPresenter [ "Instanciates a new records table that displays data based on the selected file's records." - ^ SpGridLayout new - beColumnNotHomogeneous; - yourself + ^ SpGridLayout new beColumnNotHomogeneous ] { #category : 'layout' } @@ -473,8 +538,7 @@ DSRecordBrowserPresenter >> stopRecordButton [ icon: (self iconNamed: #stop); help: 'Stop recording events.'; action: [ self stopRecording ]; - enabled: DSSpy recordingSession; - yourself + enabled: DSSpy recordingSession ] { #category : 'recording' } @@ -510,6 +574,13 @@ DSRecordBrowserPresenter >> toolbar [ addItem: self filterRecordsButton ] +{ #category : 'operations' } +DSRecordBrowserPresenter >> updateActivityPresenter [ + "Updates the activity presenter by setting its roots using the selected history." + + selectedHistory ifNil: [ activityPresenter roots: { } ] ifNotNil: [ activityPresenter roots: selectedHistory windowJumps ] +] + { #category : 'operations' } DSRecordBrowserPresenter >> updateLastRecord: aRecord [ "Updates the last record for the recording window." @@ -519,18 +590,22 @@ DSRecordBrowserPresenter >> updateLastRecord: aRecord [ ] { #category : 'operations' } -DSRecordBrowserPresenter >> updateRecordsTable [ - "Updates the records' table presenter and add to each record its corresponding color." +DSRecordBrowserPresenter >> updateRecordTypesPresenter [ + "Updates the record types presenter by setting its roots using the selected history." - | recordColorAssociations | - recordColorAssociations := Array new. + selectedHistory + ifNil: [ recordTypesPresenter roots: { } ] + ifNotNil: [ recordTypesPresenter roots: self getNumberOfEventsPerType associations ] +] - selectedHistory ifNotNil: [ - recordColorAssociations := self getRecordColorAssociationsFrom: selectedHistory windows. - recordColorAssociations := recordColorAssociations reject: [ :association | - recordsFilter chosenItems includes: association key class ] ]. +{ #category : 'operations' } +DSRecordBrowserPresenter >> updateRecordsPresenter: aRecordPresenter with: anEventsContainer [ + "Update a record presenter using an object that defines a method returning its events." - recordsTablePresenter roots: recordColorAssociations + anEventsContainer + ifNil: [ aRecordPresenter roots: { } ] + ifNotNil: [ + aRecordPresenter roots: (anEventsContainer events reject: [ :event | recordsFilter chosenItems includes: event class ]) ] ] { #category : 'operations' } @@ -544,12 +619,22 @@ DSRecordBrowserPresenter >> updateStatisticsPresenter [ ('Number of windows: ' , selectedHistory windows size asString). ('Time taken: ' , (Time fromSeconds: selectedHistory timeTaken) print24). ('Idle time: ' , (Time fromSeconds: selectedHistory computeIdleTime) print24). - ('Absolute time taken: ' , (Time fromSeconds: selectedHistory absoluteTimeTaken) print24) }. + ('Absolute time taken: ' , (Time fromSeconds: selectedHistory absoluteTimeTaken) print24). + ('Number of debug actions: ' , selectedHistory countDebugActions asString). + ('Date: ' , selectedHistory dateTime asString). + ('Debug points added: ' , selectedHistory debugPointAdds asString). + ('Debug points hit: ' , selectedHistory debugPointHit asString). + ('Debug points removed: ' , selectedHistory debugPointRemoved asString). + ('Methods added: ' , selectedHistory methodsAdded asString). + ('Methods modified: ' , selectedHistory methodsModified asString). + ('Methods removed: ' , selectedHistory methodsRemoved asString). + ('Number of steps: ' , selectedHistory numberOfSteps asString). + ('Executed code: ' , selectedHistory executedCode asString) }. stats doWithIndex: [ :stat :index | statisticsPresenter add: stat asPresenter atPoint: 1 @ index ] ] -{ #category : 'layout' } +{ #category : 'operations' } DSRecordBrowserPresenter >> updateToolbar [ startRecordButtonPresenter enabled: DSSpy recordingSession not. @@ -558,7 +643,7 @@ DSRecordBrowserPresenter >> updateToolbar [ { #category : 'operations' } DSRecordBrowserPresenter >> updateWindowsPresenter [ - "Updates the windows presenter by setting its roots using the selected item from files presenter." + "Updates the windows presenter by setting its roots using the selected history." selectedHistory ifNil: [ windowsPresenter roots: { } ] ifNotNil: [ windowsPresenter roots: selectedHistory windows ] ] @@ -572,58 +657,41 @@ DSRecordBrowserPresenter >> windowIcon [ { #category : 'accessing' } DSRecordBrowserPresenter >> windowTitle [ - ^ 'Debugging record browser' + ^ 'Debugging Spy browser' +] + +{ #category : 'accessing' } +DSRecordBrowserPresenter >> windowsLayout [ + "Returns the layout that displays the windows table and the selected records if applicable." + + ^ SpPanedLayout newTopToBottom + add: windowsPresenter; + add: windowsRecordsPresenter; + positionOfSlider: 70 percent ] { #category : 'layout' } DSRecordBrowserPresenter >> windowsPresenter [ "Instanciates a new table that displays the windows and their events as children. For each column, the manipulated object could be either a DSWindowRecord or a record that inherits from DSAbstractEventRecord." - ^ self newTreeTable + | presenter | + presenter := self newTreeTable. + + ^ presenter addColumn: (SpStringTableColumn new width: 4; beNotSortable; - evaluated: [ :item | '' ]; - yourself); + displayBackgroundColor: [ :window | window windowColor ]; + evaluated: [ :window | '' ]); addColumn: (SpStringTableColumn new - width: 20; - beNotExpandable; - beNotSortable; - displayBackgroundColor: [ :anItem | anItem windowColor ]; - evaluated: [ :item | '' ]; - yourself); + title: 'Window'; + evaluated: [ :window | window asString ]); addColumn: (SpStringTableColumn new - title: 'Window / Event'; - evaluated: [ :anItem | anItem asString ]; - yourself); - addColumn: (SpStringTableColumn new - title: 'Type'; - evaluated: [ :anItem | anItem type ]; - yourself); + title: 'Duration'; + evaluated: [ :window | window printAsFormattedTime ]); addColumn: (SpStringTableColumn new - title: 'Time'; - evaluated: [ :anItem | anItem printAsFormattedTime ]; - yourself); + title: 'Number of events'; + evaluated: [ :window | window events size ]); beResizable; - actions: self windowsPresenterActions; - children: [ :item | - item class = DSWindowRecord - ifTrue: [ item events ] - ifFalse: [ { } ] ]; - yourself -] - -{ #category : 'layout' } -DSRecordBrowserPresenter >> windowsPresenterActions [ - "Return a list of actions which can be done on a record from the table. For example, inspect the selected record." - - ^ SpActionGroup new - addActionWith: [ :anItem | - anItem - name: 'Inspect'; - iconName: #inspect; - description: 'Inspect the selected element.'; - shortcutKey: $i meta; - action: [ windowsPresenter selectedItem inspect ] ]; - yourself + actions: (self commonActionsFor: presenter) ] diff --git a/DebuggingSpy-Browser/DSWindowRecord.extension.st b/DebuggingSpy-Browser/DSWindowRecord.extension.st index dcb587f..0198a1b 100644 --- a/DebuggingSpy-Browser/DSWindowRecord.extension.st +++ b/DebuggingSpy-Browser/DSWindowRecord.extension.st @@ -4,7 +4,14 @@ Extension { #name : 'DSWindowRecord' } DSWindowRecord >> printAsFormattedTime [ "Returns the formatted time to be displayed in the windows presenter." - ^ nil + | duration | + duration := self totalTime. + + ^ (String + new: 18 + streamContents: [ :aStream | + (Time seconds: duration seconds nanoSeconds: duration nanoSeconds) print24: true showSeconds: true on: aStream ]) asText + allBold ] { #category : '*DebuggingSpy-Browser' } diff --git a/DebuggingSpy/DSRecordHistory.class.st b/DebuggingSpy/DSRecordHistory.class.st index 8bb14f5..128f326 100644 --- a/DebuggingSpy/DSRecordHistory.class.st +++ b/DebuggingSpy/DSRecordHistory.class.st @@ -275,9 +275,9 @@ DSRecordHistory >> events [ ] { #category : 'accessing' } -DSRecordHistory >> events: anObject [ +DSRecordHistory >> events: aCollectionOfRecords [ - events := anObject + events := aCollectionOfRecords ] { #category : 'API-history' }