From 7ac08c38224b43a9f7a7e1eb89b66f2f5b36432a Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Tue, 21 Apr 2026 14:45:41 +0200 Subject: [PATCH 01/16] feat: record types window --- .../DSRecordBrowserPresenterTest.class.st | 32 +++++++++- .../DSRecordBrowserPresenter.class.st | 64 +++++++++++++++---- 2 files changed, 84 insertions(+), 12 deletions(-) diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index 9910c30..f62ec25 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -224,6 +224,24 @@ DSRecordBrowserPresenterTest >> testGetHistoryFrom [ self assert: (browser getHistoryFrom: nil) isNil ] +{ #category : 'tests' } +DSRecordBrowserPresenterTest >> testGetNumberOfEventsPerType [ + + | dict | + browser selectedHistory: (DSRecordHistory on: { + (DSMouseEnterWindowRecord new windowId: 1). + (DSBrowseRecord new windowId: 1). + (DSBrowseRecord new windowId: 1). + (DSMouseLeaveWindowRecord new windowId: 1) }). + + 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' } DSRecordBrowserPresenterTest >> testGetRecordColorAssociationsFrom [ @@ -401,6 +419,18 @@ DSRecordBrowserPresenterTest >> testUpdateLastRecord [ self assert: timerWindow lastEventMorph contents equals: record eventName ] +{ #category : 'tests' } +DSRecordBrowserPresenterTest >> testUpdateRecordTypesPresenter [ + + | presenter | + presenter := browser presenterAt: #recordTypesPresenter. + self assert: presenter roots isEmpty. + browser selectedHistory: (DSRecordHistory on: self getRecordExamples). + browser updateRecordTypesPresenter. + + self assert: presenter roots equals: browser getNumberOfEventsPerType associations +] + { #category : 'tests' } DSRecordBrowserPresenterTest >> testUpdateRecordsTable [ @@ -442,7 +472,7 @@ DSRecordBrowserPresenterTest >> testUpdateStatisticsPresenter [ 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 fifth label equals: 'Absolute time taken: 00:00:03' ] { #category : 'tests' } diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index 7306e97..aedc7ea 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -18,7 +18,8 @@ Class { 'stopRecordButtonPresenter', 'windowsPresenter', 'statisticsPresenter', - 'selectedHistory' + 'selectedHistory', + 'recordTypesPresenter' ], #classInstVars : [ 'uniqueInstance' @@ -162,7 +163,8 @@ DSRecordBrowserPresenter >> connectPresenters [ selectedHistory := self getHistoryFrom: fileListPresenter selectedItem. self updateRecordsTable. self updateWindowsPresenter. - self updateStatisticsPresenter ]. + self updateStatisticsPresenter. + self updateRecordTypesPresenter ]. recordsFilter whenChangedDo: [ self updateRecordsTable ] ] @@ -184,6 +186,7 @@ DSRecordBrowserPresenter >> defaultLayout [ add: recordsTablePresenter label: 'Records'; add: windowsPresenter label: 'Windows'; add: statisticsPresenter label: 'Statistics'; + add: recordTypesPresenter label: 'Types'; yourself); yourself); yourself) @@ -276,6 +279,18 @@ DSRecordBrowserPresenter >> getHistoryFrom: aFileReference [ ^ DSRecordHistory on: (self getRecordsFromFileReference: aFileReference) ] +{ #category : 'helpers' } +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." + + | dict | + dict := Dictionary new. + DSAbstractEventRecord getLeafSubClasses do: [ :recordClass | dict at: recordClass put: 0 ]. + selectedHistory ifNotNil: [ + selectedHistory records do: [ :record | dict at: record class update: [ :nbOfRecords | nbOfRecords + 1 ] ] ]. + ^ dict +] + { #category : 'helpers' } DSRecordBrowserPresenter >> getRecordColorAssociationsFrom: aWindowRecordCollection [ "Returns a sorted collection associating each record with its window's corresponding color, sorted by record's dateTime." @@ -319,7 +334,8 @@ DSRecordBrowserPresenter >> initializePresenters [ recordsTablePresenter := self recordsTable. recordsFilter := self recordsFilter. windowsPresenter := self windowsPresenter. - statisticsPresenter := self statisticsPresenter + statisticsPresenter := self statisticsPresenter. + recordTypesPresenter := self recordTypesPresenter ] { #category : 'testing' } @@ -345,6 +361,22 @@ DSRecordBrowserPresenter >> openAddFileDialog [ newFiles ifNotNil: [ newFiles do: [ :file | self addFile: file asFileReference ] ] ] +{ #category : 'layout' } +DSRecordBrowserPresenter >> recordTypesPresenter [ + "Instanciates a new table that displays the record types and some information about them." + + ^ self newTreeTable + addColumn: (SpStringTableColumn new + title: 'Type'; + evaluated: [ :association | association key name ]; + yourself); + addColumn: (SpStringTableColumn new + title: 'Number of records'; + evaluated: [ :association | association value ]; + yourself); + beResizable +] + { #category : 'layout' } DSRecordBrowserPresenter >> recordsFilter [ "Instanciates a new chooser that displays every record classes that could be used to filter records in table." @@ -518,6 +550,15 @@ DSRecordBrowserPresenter >> updateLastRecord: aRecord [ timerWindow lastRecord: aRecord ] +{ #category : 'operations' } +DSRecordBrowserPresenter >> updateRecordTypesPresenter [ + "Updates the record types presenter by setting its roots using the selected history." + + selectedHistory + ifNil: [ recordTypesPresenter roots: { } ] + ifNotNil: [ recordTypesPresenter roots: self getNumberOfEventsPerType associations ] +] + { #category : 'operations' } DSRecordBrowserPresenter >> updateRecordsTable [ "Updates the records' table presenter and add to each record its corresponding color." @@ -539,17 +580,18 @@ DSRecordBrowserPresenter >> updateStatisticsPresenter [ | stats | selectedHistory ifNil: [ ^ self ]. - stats := { - ('Number of events: ' , selectedHistory records size asString). - ('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) }. + stats := OrderedCollection new. + stats addAll: { + ('Number of events: ' , selectedHistory records size asString). + ('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) }. stats doWithIndex: [ :stat :index | statisticsPresenter add: stat asPresenter atPoint: 1 @ index ] ] -{ #category : 'layout' } +{ #category : 'operations' } DSRecordBrowserPresenter >> updateToolbar [ startRecordButtonPresenter enabled: DSSpy recordingSession not. @@ -558,7 +600,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 ] ] From 22f871a9c47912777701e8a41b6cc6f8ae735f7f Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Tue, 21 Apr 2026 14:59:27 +0200 Subject: [PATCH 02/16] feat: activity window --- .../DSRecordBrowserPresenterTest.class.st | 17 ++++- .../DSRecordBrowserPresenter.class.st | 71 +++++++++++++++---- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index f62ec25..4f20c6b 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -403,6 +403,21 @@ DSRecordBrowserPresenterTest >> testStopRecording [ self assert: browser timerWindow isNil ] +{ #category : 'tests' } +DSRecordBrowserPresenterTest >> testUpdateActivityPresenter [ + + | presenter history | + presenter := browser presenterAt: #activityPresenter. + + self assert: presenter roots isEmpty. + history := browser getHistoryFrom: self generateRecordsFile. + + browser selectedHistory: history. + browser updateActivityPresenter. + + self assert: presenter roots equals: history windowJumps +] + { #category : 'tests' } DSRecordBrowserPresenterTest >> testUpdateLastRecord [ @@ -425,7 +440,7 @@ DSRecordBrowserPresenterTest >> testUpdateRecordTypesPresenter [ | presenter | presenter := browser presenterAt: #recordTypesPresenter. self assert: presenter roots isEmpty. - browser selectedHistory: (DSRecordHistory on: self getRecordExamples). + browser selectedHistory: (browser getHistoryFrom: self generateRecordsFile). browser updateRecordTypesPresenter. self assert: presenter roots equals: browser getNumberOfEventsPerType associations diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index aedc7ea..3da07fc 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -19,7 +19,8 @@ Class { 'windowsPresenter', 'statisticsPresenter', 'selectedHistory', - 'recordTypesPresenter' + 'recordTypesPresenter', + 'activityPresenter' ], #classInstVars : [ 'uniqueInstance' @@ -112,6 +113,43 @@ DSRecordBrowserPresenter class >> windowType [ ^ 'Debugging Spy' ] +{ #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." + + ^ self newTreeTable + addColumn: (SpStringTableColumn new + width: 4; + beNotSortable; + evaluated: [ :item | '' ]; + yourself); + addColumn: (SpStringTableColumn new + width: 20; + beNotExpandable; + beNotSortable; + displayBackgroundColor: [ :anItem | anItem windowColor ]; + evaluated: [ :item | '' ]; + yourself); + addColumn: (SpStringTableColumn new + title: 'Window / Event'; + evaluated: [ :anItem | anItem asString ]; + yourself); + addColumn: (SpStringTableColumn new + title: 'Type'; + evaluated: [ :anItem | anItem type ]; + yourself); + addColumn: (SpStringTableColumn new + title: 'Duration'; + evaluated: [ :anItem | anItem printAsFormattedTime ]; + yourself); + beResizable; + children: [ :item | + item class = DSWindowActivityRecord + ifTrue: [ item events ] + ifFalse: [ { } ] ]; + yourself +] + { #category : 'files' } DSRecordBrowserPresenter >> addFile: aFileReference [ "Adds a file in the presenter and set is as selected, which updates the records displayed." @@ -164,7 +202,8 @@ DSRecordBrowserPresenter >> connectPresenters [ self updateRecordsTable. self updateWindowsPresenter. self updateStatisticsPresenter. - self updateRecordTypesPresenter ]. + self updateRecordTypesPresenter. + self updateActivityPresenter ]. recordsFilter whenChangedDo: [ self updateRecordsTable ] ] @@ -179,17 +218,13 @@ 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'; - add: recordTypesPresenter label: 'Types'; - yourself); - yourself); - yourself) + positionOfSlider: 57 percent); + add: (SpTabLayout new + add: activityPresenter label: 'Activity'; + add: recordsTablePresenter label: 'Records'; + add: statisticsPresenter label: 'Statistics'; + add: recordTypesPresenter label: 'Types'; + add: windowsPresenter label: 'Windows')) ] { #category : 'layout' } @@ -335,7 +370,8 @@ DSRecordBrowserPresenter >> initializePresenters [ recordsFilter := self recordsFilter. windowsPresenter := self windowsPresenter. statisticsPresenter := self statisticsPresenter. - recordTypesPresenter := self recordTypesPresenter + recordTypesPresenter := self recordTypesPresenter. + activityPresenter := self activityPresenter ] { #category : 'testing' } @@ -542,6 +578,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." From 235c1485ed6852a1888a502e4bd3094839bc4eff Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Wed, 22 Apr 2026 11:04:33 +0200 Subject: [PATCH 03/16] feat: activity tab --- .../DSRecordBrowserPresenter.class.st | 43 +++++++++++++------ .../DSWindowActivityRecord.extension.st | 7 +++ 2 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 DebuggingSpy-Browser/DSWindowActivityRecord.extension.st diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index 3da07fc..4b8d5f3 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -121,32 +121,49 @@ DSRecordBrowserPresenter >> activityPresenter [ addColumn: (SpStringTableColumn new width: 4; beNotSortable; - evaluated: [ :item | '' ]; - yourself); + evaluated: [ :item | '' ]); addColumn: (SpStringTableColumn new width: 20; beNotExpandable; beNotSortable; displayBackgroundColor: [ :anItem | anItem windowColor ]; - evaluated: [ :item | '' ]; - yourself); + evaluated: [ :item | '' ]); addColumn: (SpStringTableColumn new title: 'Window / Event'; - evaluated: [ :anItem | anItem asString ]; + evaluated: [ :anItem | + anItem class = DSWindowActivityRecord + ifTrue: [ anItem window asString ] + ifFalse: [ anItem asString ] ]; yourself); addColumn: (SpStringTableColumn new title: 'Type'; - evaluated: [ :anItem | anItem type ]; - yourself); + evaluated: [ :anItem | anItem type ]); addColumn: (SpStringTableColumn new title: 'Duration'; - evaluated: [ :anItem | anItem printAsFormattedTime ]; - yourself); + evaluated: [ :anItem | anItem class = DSWindowActivityRecord ifTrue: [ anItem duration ] ]); + addColumn: (SpStringTableColumn new + title: 'Time'; + evaluated: [ :anItem | anItem printAsFormattedTime ]); beResizable; children: [ :item | item class = DSWindowActivityRecord ifTrue: [ item events ] ifFalse: [ { } ] ]; + actions: self activityPresenterActions +] + +{ #category : 'layout' } +DSRecordBrowserPresenter >> activityPresenterActions [ + "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: [ activityPresenter selectedItem inspect ] ]; yourself ] @@ -366,7 +383,7 @@ DSRecordBrowserPresenter >> initializePresenters [ stopRecordButtonPresenter := self stopRecordButton. toolbarPresenter := self toolbar. fileListPresenter := self fileListPresenter. - recordsTablePresenter := self recordsTable. + recordsTablePresenter := self recordsTablePresenter. recordsFilter := self recordsFilter. windowsPresenter := self windowsPresenter. statisticsPresenter := self statisticsPresenter. @@ -421,7 +438,7 @@ DSRecordBrowserPresenter >> recordsFilter [ ] { #category : 'layout' } -DSRecordBrowserPresenter >> recordsTable [ +DSRecordBrowserPresenter >> recordsTablePresenter [ "Instanciates a new records table that displays data based on the selected file's records." ^ self newTreeTable @@ -444,12 +461,12 @@ DSRecordBrowserPresenter >> recordsTable [ evaluated: [ :association | association key printAsFormattedTime ]; yourself); beResizable; - actions: self recordsTableActions; + actions: self recordsTablePresenterActions; yourself ] { #category : 'layout' } -DSRecordBrowserPresenter >> recordsTableActions [ +DSRecordBrowserPresenter >> recordsTablePresenterActions [ "Return a list of actions which can be done on a record from the table. For example, inspect the selected record." ^ SpActionGroup new diff --git a/DebuggingSpy-Browser/DSWindowActivityRecord.extension.st b/DebuggingSpy-Browser/DSWindowActivityRecord.extension.st new file mode 100644 index 0000000..71a7597 --- /dev/null +++ b/DebuggingSpy-Browser/DSWindowActivityRecord.extension.st @@ -0,0 +1,7 @@ +Extension { #name : 'DSWindowActivityRecord' } + +{ #category : '*DebuggingSpy-Browser' } +DSWindowActivityRecord >> printAsFormattedTime [ + + ^ nil +] From b2c01f0b99e65ad0f896040ff6a0048eb0e0f037 Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Wed, 22 Apr 2026 14:21:21 +0200 Subject: [PATCH 04/16] feat: records presenter in activity & windows tabs --- .../DSRecordBrowserPresenterTest.class.st | 11 ++ .../DSRecordBrowserPresenter.class.st | 128 +++++++++++------- .../DSWindowRecord.extension.st | 9 +- 3 files changed, 96 insertions(+), 52 deletions(-) diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index 4f20c6b..70d1f48 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -446,6 +446,17 @@ DSRecordBrowserPresenterTest >> testUpdateRecordTypesPresenter [ self assert: presenter roots equals: browser getNumberOfEventsPerType associations ] +{ #category : 'tests' } +DSRecordBrowserPresenterTest >> testUpdateRecordsPresenterWithRecords [ + + | presenter records | + presenter := browser recordsPresenter. + records := self getRecordExamples. + browser updateRecordsPresenter: presenter withRecords: records. + + self assert: presenter roots equals: records +] + { #category : 'tests' } DSRecordBrowserPresenterTest >> testUpdateRecordsTable [ diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index 4b8d5f3..7f9e898 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -20,7 +20,9 @@ Class { 'statisticsPresenter', 'selectedHistory', 'recordTypesPresenter', - 'activityPresenter' + 'activityPresenter', + 'activityRecordsPresenter', + 'windowsRecordsPresenter' ], #classInstVars : [ 'uniqueInstance' @@ -113,6 +115,16 @@ 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." @@ -121,34 +133,18 @@ DSRecordBrowserPresenter >> activityPresenter [ addColumn: (SpStringTableColumn new width: 4; beNotSortable; - evaluated: [ :item | '' ]); - addColumn: (SpStringTableColumn new - width: 20; - beNotExpandable; - beNotSortable; - displayBackgroundColor: [ :anItem | anItem windowColor ]; - evaluated: [ :item | '' ]); + displayBackgroundColor: [ :windowJump | windowJump windowColor ]; + evaluated: [ :windowJump | '' ]); addColumn: (SpStringTableColumn new - title: 'Window / Event'; - evaluated: [ :anItem | - anItem class = DSWindowActivityRecord - ifTrue: [ anItem window asString ] - ifFalse: [ anItem asString ] ]; - yourself); - addColumn: (SpStringTableColumn new - title: 'Type'; - evaluated: [ :anItem | anItem type ]); + title: 'Window'; + evaluated: [ :windowJump | windowJump window asString ]); addColumn: (SpStringTableColumn new title: 'Duration'; - evaluated: [ :anItem | anItem class = DSWindowActivityRecord ifTrue: [ anItem duration ] ]); + evaluated: [ :windowJump | windowJump duration ]); addColumn: (SpStringTableColumn new - title: 'Time'; - evaluated: [ :anItem | anItem printAsFormattedTime ]); + title: 'Number of events'; + evaluated: [ :windowJump | windowJump events size ]); beResizable; - children: [ :item | - item class = DSWindowActivityRecord - ifTrue: [ item events ] - ifFalse: [ { } ] ]; actions: self activityPresenterActions ] @@ -222,7 +218,13 @@ DSRecordBrowserPresenter >> connectPresenters [ self updateRecordTypesPresenter. self updateActivityPresenter ]. - recordsFilter whenChangedDo: [ self updateRecordsTable ] + recordsFilter whenChangedDo: [ self updateRecordsTable ]. + + windowsPresenter whenSelectedItemChangedDo: [ :selectedItem | + selectedItem ifNotNil: [ self updateRecordsPresenter: windowsRecordsPresenter withRecords: selectedItem events ] ]. + + activityPresenter whenSelectedItemChangedDo: [ :selectedItem | + selectedItem ifNotNil: [ self updateRecordsPresenter: activityRecordsPresenter withRecords: selectedItem events ] ] ] { #category : 'layout' } @@ -237,11 +239,11 @@ DSRecordBrowserPresenter >> defaultLayout [ add: self colorReferential; positionOfSlider: 57 percent); add: (SpTabLayout new - add: activityPresenter label: 'Activity'; + add: self activityLayout label: 'Activity'; add: recordsTablePresenter label: 'Records'; add: statisticsPresenter label: 'Statistics'; add: recordTypesPresenter label: 'Types'; - add: windowsPresenter label: 'Windows')) + add: self windowsLayout label: 'Windows')) ] { #category : 'layout' } @@ -388,7 +390,9 @@ DSRecordBrowserPresenter >> initializePresenters [ windowsPresenter := self windowsPresenter. statisticsPresenter := self statisticsPresenter. recordTypesPresenter := self recordTypesPresenter. - activityPresenter := self activityPresenter + activityPresenter := self activityPresenter. + windowsRecordsPresenter := self recordsPresenter. + activityRecordsPresenter := self recordsPresenter ] { #category : 'testing' } @@ -437,6 +441,25 @@ DSRecordBrowserPresenter >> recordsFilter [ ^ 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." + + ^ self newTreeTable + 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: 'Time'; + evaluated: [ :record | record printAsFormattedTime ]); + beResizable +] + { #category : 'layout' } DSRecordBrowserPresenter >> recordsTablePresenter [ "Instanciates a new records table that displays data based on the selected file's records." @@ -619,6 +642,13 @@ DSRecordBrowserPresenter >> updateRecordTypesPresenter [ ifNotNil: [ recordTypesPresenter roots: self getNumberOfEventsPerType associations ] ] +{ #category : 'operations' } +DSRecordBrowserPresenter >> updateRecordsPresenter: aPresenter withRecords: someRecords [ + "Updates the records presenter by updating its roots." + + aPresenter roots: someRecords +] + { #category : 'operations' } DSRecordBrowserPresenter >> updateRecordsTable [ "Updates the records' table presenter and add to each record its corresponding color." @@ -677,6 +707,16 @@ DSRecordBrowserPresenter >> windowTitle [ ^ 'Debugging record 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." @@ -685,34 +725,20 @@ DSRecordBrowserPresenter >> windowsPresenter [ addColumn: (SpStringTableColumn new width: 4; beNotSortable; - evaluated: [ :item | '' ]; - yourself); - addColumn: (SpStringTableColumn new - width: 20; - beNotExpandable; - beNotSortable; - displayBackgroundColor: [ :anItem | anItem windowColor ]; - evaluated: [ :item | '' ]; - yourself); + displayBackgroundColor: [ :window | window windowColor ]; + evaluated: [ :window | '' ]); addColumn: (SpStringTableColumn new - title: 'Window / Event'; - evaluated: [ :anItem | anItem asString ]; - yourself); + title: 'Window'; + evaluated: [ :window | window asString ]); 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 ]; + title: 'Number of events'; + evaluated: [ :window | window events size ]; yourself); beResizable; - actions: self windowsPresenterActions; - children: [ :item | - item class = DSWindowRecord - ifTrue: [ item events ] - ifFalse: [ { } ] ]; - yourself + actions: self windowsPresenterActions ] { #category : 'layout' } 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' } From cb32701329bcd1fd627294e27f1368d6ac79f878 Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Wed, 22 Apr 2026 14:43:24 +0200 Subject: [PATCH 05/16] refactor: record table uses a recordsPresenter --- .../DSRecordBrowserPresenterTest.class.st | 25 -------- .../DSRecordBrowserPresenter.class.st | 63 +++---------------- 2 files changed, 9 insertions(+), 79 deletions(-) diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index 70d1f48..32a7823 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -457,31 +457,6 @@ DSRecordBrowserPresenterTest >> testUpdateRecordsPresenterWithRecords [ self assert: presenter roots equals: records ] -{ #category : 'tests' } -DSRecordBrowserPresenterTest >> testUpdateRecordsTable [ - - | fileRef | - fileRef := self generateRecordsFile. - browser selectedHistory: (browser getHistoryFrom: fileRef). - browser updateRecordsTable. - - 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 -] - -{ #category : 'tests' } -DSRecordBrowserPresenterTest >> testUpdateRecordsTableWhenAddingFile [ - - browser addFile: self generateRecordsFile. - - 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 -] - { #category : 'tests' } DSRecordBrowserPresenterTest >> testUpdateStatisticsPresenter [ diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index 7f9e898..4adb595 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -195,15 +195,12 @@ 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 : 'initialization' } @@ -212,13 +209,14 @@ DSRecordBrowserPresenter >> connectPresenters [ fileListPresenter whenSelectionChangedDo: [ selectedHistory := self getHistoryFrom: fileListPresenter selectedItem. - self updateRecordsTable. + selectedHistory ifNotNil: [ self updateRecordsPresenter: recordsTablePresenter withRecords: selectedHistory records ]. self updateWindowsPresenter. self updateStatisticsPresenter. self updateRecordTypesPresenter. self updateActivityPresenter ]. - recordsFilter whenChangedDo: [ self updateRecordsTable ]. + recordsFilter whenChangedDo: [ + selectedHistory ifNotNil: [ self updateRecordsPresenter: recordsTablePresenter withRecords: selectedHistory records ] ]. windowsPresenter whenSelectedItemChangedDo: [ :selectedItem | selectedItem ifNotNil: [ self updateRecordsPresenter: windowsRecordsPresenter withRecords: selectedItem events ] ]. @@ -385,7 +383,7 @@ DSRecordBrowserPresenter >> initializePresenters [ stopRecordButtonPresenter := self stopRecordButton. toolbarPresenter := self toolbar. fileListPresenter := self fileListPresenter. - recordsTablePresenter := self recordsTablePresenter. + recordsTablePresenter := self recordsPresenter. recordsFilter := self recordsFilter. windowsPresenter := self windowsPresenter. statisticsPresenter := self statisticsPresenter. @@ -461,35 +459,7 @@ DSRecordBrowserPresenter >> recordsPresenter [ ] { #category : 'layout' } -DSRecordBrowserPresenter >> recordsTablePresenter [ - "Instanciates a new records table that displays data based on the selected file's records." - - ^ 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); - addColumn: (SpStringTableColumn new - title: 'Time'; - evaluated: [ :association | association key printAsFormattedTime ]; - yourself); - beResizable; - actions: self recordsTablePresenterActions; - yourself -] - -{ #category : 'layout' } -DSRecordBrowserPresenter >> recordsTablePresenterActions [ +DSRecordBrowserPresenter >> recordsPresenterActions [ "Return a list of actions which can be done on a record from the table. For example, inspect the selected record." ^ SpActionGroup new @@ -646,22 +616,7 @@ DSRecordBrowserPresenter >> updateRecordTypesPresenter [ DSRecordBrowserPresenter >> updateRecordsPresenter: aPresenter withRecords: someRecords [ "Updates the records presenter by updating its roots." - aPresenter roots: someRecords -] - -{ #category : 'operations' } -DSRecordBrowserPresenter >> updateRecordsTable [ - "Updates the records' table presenter and add to each record its corresponding color." - - | recordColorAssociations | - recordColorAssociations := Array new. - - selectedHistory ifNotNil: [ - recordColorAssociations := self getRecordColorAssociationsFrom: selectedHistory windows. - recordColorAssociations := recordColorAssociations reject: [ :association | - recordsFilter chosenItems includes: association key class ] ]. - - recordsTablePresenter roots: recordColorAssociations + aPresenter roots: (someRecords reject: [ :record | recordsFilter chosenItems includes: record class ]) ] { #category : 'operations' } From f6326b7a34166ab3bd551b5bbe317ce5be4fcab4 Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Wed, 22 Apr 2026 14:53:51 +0200 Subject: [PATCH 06/16] refactor: remove deprecated method --- .../DSRecordBrowserPresenterTest.class.st | 22 ------------------- .../DSRecordBrowserPresenter.class.st | 14 ------------ 2 files changed, 36 deletions(-) diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index 32a7823..b76f961 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -242,28 +242,6 @@ DSRecordBrowserPresenterTest >> testGetNumberOfEventsPerType [ self assert: (dict at: DSWindowOpenedRecord) equals: 0 ] -{ #category : 'tests' } -DSRecordBrowserPresenterTest >> testGetRecordColorAssociationsFrom [ - - | windows colorAssociations | - windows := { (DSWindowRecord new - toolInfo: (DSToolInfo new - toolClass: StPlaygroundPresenter; - yourself); - events: { - DSWindowOpenedRecord new. - DSDoItRecord new. - DSStepThroughRecord new }) } asOrderedCollection. - - 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') ] -] - { #category : 'tests' } DSRecordBrowserPresenterTest >> testGetRecordsFromFileReference [ diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index 4adb595..a6870f3 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -343,20 +343,6 @@ DSRecordBrowserPresenter >> getNumberOfEventsPerType [ ^ dict ] -{ #category : 'helpers' } -DSRecordBrowserPresenter >> getRecordColorAssociationsFrom: aWindowRecordCollection [ - "Returns a sorted collection associating each record with its window's corresponding color, sorted by record's dateTime." - - | 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 ] -] - { #category : 'helpers' } DSRecordBrowserPresenter >> getRecordsFromFileReference: aFileReference [ "Returns recursively a list of records taken in the specified file reference. If the argument is a folder, takes all its contained records." From cd7321165d3bbdcde87338ecfc373d90f9dae2a6 Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Thu, 23 Apr 2026 10:22:56 +0200 Subject: [PATCH 07/16] feat: records presenter actions --- .../DSRecordBrowserPresenter.class.st | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index a6870f3..b06f4c6 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -207,6 +207,8 @@ DSRecordBrowserPresenter >> colorReferential [ DSRecordBrowserPresenter >> connectPresenters [ "Updates the records and the timeline whenever the selected file is changed." + "This method is awful, its gonna be refactored when History, Windows and Jumps would be using an unified method that returns their events." + fileListPresenter whenSelectionChangedDo: [ selectedHistory := self getHistoryFrom: fileListPresenter selectedItem. selectedHistory ifNotNil: [ self updateRecordsPresenter: recordsTablePresenter withRecords: selectedHistory records ]. @@ -216,7 +218,12 @@ DSRecordBrowserPresenter >> connectPresenters [ self updateActivityPresenter ]. recordsFilter whenChangedDo: [ - selectedHistory ifNotNil: [ self updateRecordsPresenter: recordsTablePresenter withRecords: selectedHistory records ] ]. + selectedHistory ifNotNil: [ + self updateRecordsPresenter: recordsTablePresenter withRecords: selectedHistory records. + windowsPresenter selectedItem ifNotNil: [ + self updateRecordsPresenter: windowsRecordsPresenter withRecords: windowsPresenter selectedItem events ]. + activityPresenter selectedItem ifNotNil: [ + self updateRecordsPresenter: activityRecordsPresenter withRecords: activityPresenter selectedItem events ] ] ]. windowsPresenter whenSelectedItemChangedDo: [ :selectedItem | selectedItem ifNotNil: [ self updateRecordsPresenter: windowsRecordsPresenter withRecords: selectedItem events ] ]. @@ -429,7 +436,10 @@ DSRecordBrowserPresenter >> recordsFilter [ DSRecordBrowserPresenter >> recordsPresenter [ "Instanciates a new records table that displays data based on the selected records in windows or activity tabs." - ^ self newTreeTable + | presenter | + presenter := self newTreeTable. + + ^ presenter addColumn: (SpStringTableColumn new displayBackgroundColor: [ :record | record windowColor ]; width: 4; @@ -441,11 +451,12 @@ DSRecordBrowserPresenter >> recordsPresenter [ addColumn: (SpStringTableColumn new title: 'Time'; evaluated: [ :record | record printAsFormattedTime ]); + actions: (self recordsPresenterActionsFor: presenter); beResizable ] { #category : 'layout' } -DSRecordBrowserPresenter >> recordsPresenterActions [ +DSRecordBrowserPresenter >> recordsPresenterActionsFor: aRecordTable [ "Return a list of actions which can be done on a record from the table. For example, inspect the selected record." ^ SpActionGroup new @@ -455,22 +466,21 @@ DSRecordBrowserPresenter >> recordsPresenterActions [ iconName: #inspect; description: 'Inspect the raw records'; shortcutKey: $i meta; - action: [ recordsTablePresenter selectedItem key inspect ] ]; + action: [ aRecordTable selectedItem 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: aRecordTable 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: aRecordTable selectedItem class ] ] ] { #category : 'files' } From 50363836086f35407df8f7d4789d6972ad08c98c Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Thu, 23 Apr 2026 10:40:48 +0200 Subject: [PATCH 08/16] refactor: actions protocol --- DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index b06f4c6..de845e5 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -148,7 +148,7 @@ DSRecordBrowserPresenter >> activityPresenter [ actions: self activityPresenterActions ] -{ #category : 'layout' } +{ #category : 'actions' } DSRecordBrowserPresenter >> activityPresenterActions [ "Return a list of actions which can be done on a record from the table. For example, inspect the selected record." @@ -269,7 +269,7 @@ DSRecordBrowserPresenter >> fileListPresenter [ hideColumnHeaders ] -{ #category : 'layout' } +{ #category : 'actions' } 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." @@ -455,7 +455,7 @@ DSRecordBrowserPresenter >> recordsPresenter [ beResizable ] -{ #category : 'layout' } +{ #category : 'actions' } DSRecordBrowserPresenter >> recordsPresenterActionsFor: aRecordTable [ "Return a list of actions which can be done on a record from the table. For example, inspect the selected record." @@ -692,7 +692,7 @@ DSRecordBrowserPresenter >> windowsPresenter [ actions: self windowsPresenterActions ] -{ #category : 'layout' } +{ #category : 'actions' } DSRecordBrowserPresenter >> windowsPresenterActions [ "Return a list of actions which can be done on a record from the table. For example, inspect the selected record." From 395720ae71ccb31b1e216a9b19e34f5f8b3b005f Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Thu, 23 Apr 2026 14:54:37 +0200 Subject: [PATCH 09/16] refactor: actions in presenters --- .../DSRecordBrowserPresenterTest.class.st | 4 +- .../DSRecordBrowserPresenter.class.st | 254 +++++++++--------- 2 files changed, 133 insertions(+), 125 deletions(-) diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index b76f961..11a83d1 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -425,12 +425,12 @@ DSRecordBrowserPresenterTest >> testUpdateRecordTypesPresenter [ ] { #category : 'tests' } -DSRecordBrowserPresenterTest >> testUpdateRecordsPresenterWithRecords [ +DSRecordBrowserPresenterTest >> testUpdateRecordsPresenterWith [ | presenter records | presenter := browser recordsPresenter. records := self getRecordExamples. - browser updateRecordsPresenter: presenter withRecords: records. + browser updateRecordsPresenter: presenter with: (DSWindowRecord new events: records). self assert: presenter roots equals: records ] diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index de845e5..a4814d0 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -115,6 +115,19 @@ DSRecordBrowserPresenter class >> windowType [ ^ 'Debugging Spy' ] +{ #category : 'actions' } +DSRecordBrowserPresenter >> activityActionsFor: aPresenter [ + "Return a list of actions which can be done on a window jump." + + ^ SpActionGroup new addActionWith: [ :anItem | + anItem + name: 'Inspect'; + iconName: #inspect; + description: 'Inspect the selected element.'; + shortcutKey: $i meta; + action: [ aPresenter selectedItem inspect ] ] +] + { #category : 'accessing' } DSRecordBrowserPresenter >> activityLayout [ "Returns the layout that displays the activity table and the selected records if applicable." @@ -129,7 +142,10 @@ DSRecordBrowserPresenter >> activityLayout [ 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." - ^ self newTreeTable + | presenter | + presenter := self newTreeTable. + + ^ presenter addColumn: (SpStringTableColumn new width: 4; beNotSortable; @@ -145,22 +161,9 @@ DSRecordBrowserPresenter >> activityPresenter [ title: 'Number of events'; evaluated: [ :windowJump | windowJump events size ]); beResizable; - actions: self activityPresenterActions -] - -{ #category : 'actions' } -DSRecordBrowserPresenter >> activityPresenterActions [ - "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: [ activityPresenter selectedItem inspect ] ]; - yourself + actions: (SpActionGroup new + add: (self activityActionsFor: presenter); + add: (self historyActionsFor: presenter)) ] { #category : 'files' } @@ -207,29 +210,25 @@ DSRecordBrowserPresenter >> colorReferential [ DSRecordBrowserPresenter >> connectPresenters [ "Updates the records and the timeline whenever the selected file is changed." - "This method is awful, its gonna be refactored when History, Windows and Jumps would be using an unified method that returns their events." - fileListPresenter whenSelectionChangedDo: [ selectedHistory := self getHistoryFrom: fileListPresenter selectedItem. - selectedHistory ifNotNil: [ self updateRecordsPresenter: recordsTablePresenter withRecords: selectedHistory records ]. + self updateRecordsPresenter: recordsTablePresenter with: selectedHistory. + self updateWindowsPresenter. self updateStatisticsPresenter. self updateRecordTypesPresenter. self updateActivityPresenter ]. recordsFilter whenChangedDo: [ - selectedHistory ifNotNil: [ - self updateRecordsPresenter: recordsTablePresenter withRecords: selectedHistory records. - windowsPresenter selectedItem ifNotNil: [ - self updateRecordsPresenter: windowsRecordsPresenter withRecords: windowsPresenter selectedItem events ]. - activityPresenter selectedItem ifNotNil: [ - self updateRecordsPresenter: activityRecordsPresenter withRecords: activityPresenter selectedItem events ] ] ]. + self updateRecordsPresenter: recordsTablePresenter with: selectedHistory. + self updateRecordsPresenter: windowsRecordsPresenter with: windowsPresenter selectedItem. + self updateRecordsPresenter: activityRecordsPresenter with: activityPresenter selectedItem ]. windowsPresenter whenSelectedItemChangedDo: [ :selectedItem | - selectedItem ifNotNil: [ self updateRecordsPresenter: windowsRecordsPresenter withRecords: selectedItem events ] ]. + self updateRecordsPresenter: windowsRecordsPresenter with: selectedItem ]. activityPresenter whenSelectedItemChangedDo: [ :selectedItem | - selectedItem ifNotNil: [ self updateRecordsPresenter: activityRecordsPresenter withRecords: selectedItem events ] ] + self updateRecordsPresenter: activityRecordsPresenter with: selectedItem ] ] { #category : 'layout' } @@ -251,27 +250,9 @@ DSRecordBrowserPresenter >> defaultLayout [ add: self windowsLayout label: 'Windows')) ] -{ #category : 'layout' } -DSRecordBrowserPresenter >> fileListPresenter [ - "Instanciates a new presenter with a list of added files." - - ^ self newTreeTable - addColumn: (SpStringTableColumn new - evaluated: [ :file | file basenameWithoutExtension ]; - beNotSortable; - yourself); - roots: self files; - children: [ :file | - file isDirectory - ifTrue: [ file children ] - ifFalse: [ { } ] ]; - actions: self fileListPresenterActions; - hideColumnHeaders -] - { #category : 'actions' } -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." +DSRecordBrowserPresenter >> fileActionsFor: aPresenter [ + "Return a list of actions which can be done on a file." ^ SpActionGroup new addActionWith: [ :anItem | @@ -280,22 +261,40 @@ DSRecordBrowserPresenter >> fileListPresenterActions [ iconName: #inspect; description: 'Inspect the raw records'; shortcutKey: $i meta; - action: [ selectedHistory records inspect ] ]; + action: [ selectedHistory events inspect ] ]; addActionWith: [ :anItem | anItem name: 'Inspect history'; iconName: #history; - description: 'Inspect the record history'; + description: 'Inspect the history'; shortcutKey: $h meta; action: [ selectedHistory inspect ] ]; addActionWith: [ :anItem | anItem name: 'Remove'; iconName: #remove; - description: 'Remove the record from list'; + description: 'Remove the file from list'; shortcutKey: $x meta; - action: [ self removeFile: fileListPresenter selectedItem ] ]; - yourself + action: [ self removeFile: aPresenter selectedItem ] ] +] + +{ #category : 'layout' } +DSRecordBrowserPresenter >> fileListPresenter [ + "Instanciates a new presenter with a list of added files." + + | presenter | + presenter := self newTreeTable. + ^ presenter + addColumn: (SpStringTableColumn new + evaluated: [ :file | file basenameWithoutExtension ]; + beNotSortable); + roots: self files; + children: [ :file | + file isDirectory + ifTrue: [ file children ] + ifFalse: [ { } ] ]; + actions: (self fileActionsFor: presenter); + hideColumnHeaders ] { #category : 'accessing' } @@ -369,6 +368,19 @@ DSRecordBrowserPresenter >> getWindowFromRecord: aRecord [ ^ (selectedHistory windows select: [ :window | window windowId = aRecord windowId ]) first ] +{ #category : 'actions' } +DSRecordBrowserPresenter >> historyActionsFor: aPresenter [ + "Return a list of actions which can be done on a history." + + ^ SpActionGroup new addActionWith: [ :anItem | + anItem + name: 'Inspect history'; + iconName: #history; + description: 'Inspect history.'; + shortcutKey: $h meta; + action: [ (DSRecordHistory on: aPresenter selectedItem events) inspect ] ] +] + { #category : 'initialization' } DSRecordBrowserPresenter >> initializePresenters [ @@ -416,15 +428,41 @@ DSRecordBrowserPresenter >> recordTypesPresenter [ ^ self newTreeTable addColumn: (SpStringTableColumn new title: 'Type'; - evaluated: [ :association | association key name ]; - yourself); + evaluated: [ :association | association key name ]); addColumn: (SpStringTableColumn new title: 'Number of records'; - evaluated: [ :association | association value ]; - yourself); + evaluated: [ :association | association value ]); beResizable ] +{ #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: [ aPresenter selectedItem inspect ] ]; + addActionWith: [ :anItem | + anItem + name: 'Inspect the window'; + iconName: #window; + description: 'Inspect the record window'; + shortcutKey: $w meta; + 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: 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." @@ -451,38 +489,10 @@ DSRecordBrowserPresenter >> recordsPresenter [ addColumn: (SpStringTableColumn new title: 'Time'; evaluated: [ :record | record printAsFormattedTime ]); - actions: (self recordsPresenterActionsFor: presenter); + actions: (self recordsActionsFor: presenter); beResizable ] -{ #category : 'actions' } -DSRecordBrowserPresenter >> recordsPresenterActionsFor: aRecordTable [ - "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 raw records'; - shortcutKey: $i meta; - action: [ aRecordTable selectedItem inspect ] ]; - addActionWith: [ :anItem | - anItem - name: 'Inspect the window'; - iconName: #window; - description: 'Inspect the record window'; - shortcutKey: $w meta; - action: [ (self getWindowFromRecord: aRecordTable 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: aRecordTable selectedItem class ] ] -] - { #category : 'files' } DSRecordBrowserPresenter >> removeFile: aFileReference [ "Removes the selected file from the list and updates the selected item depending on the list number of elements." @@ -513,8 +523,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' } @@ -533,9 +542,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' } @@ -547,8 +554,7 @@ DSRecordBrowserPresenter >> stopRecordButton [ icon: (self iconNamed: #stop); help: 'Stop recording events.'; action: [ self stopRecording ]; - enabled: DSSpy recordingSession; - yourself + enabled: DSSpy recordingSession ] { #category : 'recording' } @@ -609,10 +615,13 @@ DSRecordBrowserPresenter >> updateRecordTypesPresenter [ ] { #category : 'operations' } -DSRecordBrowserPresenter >> updateRecordsPresenter: aPresenter withRecords: someRecords [ - "Updates the records presenter by updating its roots." +DSRecordBrowserPresenter >> updateRecordsPresenter: aRecordPresenter with: anEventsContainer [ + "Update a record presenter using an object that defines a method returning its events." - aPresenter roots: (someRecords reject: [ :record | recordsFilter chosenItems includes: record class ]) + anEventsContainer + ifNil: [ aRecordPresenter roots: { } ] + ifNotNil: [ + aRecordPresenter roots: (anEventsContainer events reject: [ :event | recordsFilter chosenItems includes: event class ]) ] ] { #category : 'operations' } @@ -621,13 +630,12 @@ DSRecordBrowserPresenter >> updateStatisticsPresenter [ | stats | selectedHistory ifNil: [ ^ self ]. - stats := OrderedCollection new. - stats addAll: { - ('Number of events: ' , selectedHistory records size asString). - ('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) }. + stats := { + ('Number of events: ' , selectedHistory events size asString). + ('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) }. stats doWithIndex: [ :stat :index | statisticsPresenter add: stat asPresenter atPoint: 1 @ index ] ] @@ -655,7 +663,20 @@ DSRecordBrowserPresenter >> windowIcon [ { #category : 'accessing' } DSRecordBrowserPresenter >> windowTitle [ - ^ 'Debugging record browser' + ^ 'Debugging Spy browser' +] + +{ #category : 'actions' } +DSRecordBrowserPresenter >> windowsActionsFor: aPresenter [ + "Return a list of actions which can be done on a window." + + ^ SpActionGroup new addActionWith: [ :anItem | + anItem + name: 'Inspect'; + iconName: #inspect; + description: 'Inspect the selected element.'; + shortcutKey: $i meta; + action: [ aPresenter selectedItem inspect ] ] ] { #category : 'accessing' } @@ -672,7 +693,10 @@ DSRecordBrowserPresenter >> windowsLayout [ 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; @@ -686,23 +710,7 @@ DSRecordBrowserPresenter >> windowsPresenter [ evaluated: [ :window | window printAsFormattedTime ]); addColumn: (SpStringTableColumn new title: 'Number of events'; - evaluated: [ :window | window events size ]; - yourself); + evaluated: [ :window | window events size ]); beResizable; - actions: self windowsPresenterActions -] - -{ #category : 'actions' } -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 windowsActionsFor: presenter) ] From 72081f32d4c88346e32a085d37a648eca5cd8728 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Thu, 23 Apr 2026 10:39:44 +0200 Subject: [PATCH 10/16] refactor: change records attribute into events for DSRecordHistory --- .../DSRecordBrowserPresenterTest.class.st | 2 +- .../DSRecordHistoryTest.class.st | 78 +++++++++--------- DebuggingSpy/DSRecordHistory.class.st | 82 +++++++++---------- 3 files changed, 81 insertions(+), 81 deletions(-) diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index 11a83d1..691c388 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -194,7 +194,7 @@ DSRecordBrowserPresenterTest >> testFilteringAClassOfRecords [ history := browser getHistoryFrom: fileRef. browser addFile: fileRef. - self assert: self recordsTablePresenter roots size equals: history records size. + self assert: self recordsTablePresenter roots size equals: history events size. self recordsFilterPresenter sourceList selectItem: DSBrowseRecord. self recordsFilterPresenter addSelected. diff --git a/DebuggingSpy-Tests/DSRecordHistoryTest.class.st b/DebuggingSpy-Tests/DSRecordHistoryTest.class.st index 1e4bad8..865b8b3 100644 --- a/DebuggingSpy-Tests/DSRecordHistoryTest.class.st +++ b/DebuggingSpy-Tests/DSRecordHistoryTest.class.st @@ -43,7 +43,7 @@ DSRecordHistoryTest >> setUp [ { #category : 'tests' } DSRecordHistoryTest >> testAbsoluteTimeTaken [ - history records: self getRecordsExample. + history events: self getRecordsExample. self assert: history absoluteTimeTaken equals: 22 * 60 ] @@ -74,7 +74,7 @@ DSRecordHistoryTest >> testAddWindowRecord [ DSRecordHistoryTest >> testAllRecordsOfKind [ | record | - history records: self getRecordsExample. + history events: self getRecordsExample. self assert: (history allRecordsOfKind: DSMouseLeaveWindowRecord) size equals: 2. record := (history allRecordsOfKind: DSMouseLeaveWindowRecord) first. @@ -91,7 +91,7 @@ DSRecordHistoryTest >> testAllRecordsOfKind [ DSRecordHistoryTest >> testBuildWindowHistory [ | windowsHistory listOfRecords | - history records: { + history events: { DSDoItRecord new. (DSWindowOpenedRecord new windowId: 1; @@ -270,7 +270,7 @@ DSRecordHistoryTest >> testBuildWindows [ (DSMouseEnterWindowRecord new windowId: -1). DSClipboardCopyRecord new. DSMouseLeaveWindowRecord new } asOrderedCollection) } as: IdentityDictionary). - history records: { + history events: { DSDoItRecord new. sourceDebugger. DSClipboardCopyRecord new. @@ -299,7 +299,7 @@ DSRecordHistoryTest >> testBuildWindows [ DSRecordHistoryTest >> testCollectScrollingPeriods [ | scrollList | - history records: { + history events: { (DSMouseEnterWindowRecord new dateTime: '2026-03-25T10:01:17' asDateAndTime; windowId: 1). @@ -348,7 +348,7 @@ DSRecordHistoryTest >> testCollectScrollingPeriods [ DSRecordHistoryTest >> testCollectTimeDiscrepancies [ | deltaDict | - history records: { + history events: { (DSMouseEnterWindowRecord new dateTime: '2024-09-23T15:02:44' asDateAndTime). (DSDoItRecord new dateTime: '2024-09-23T15:02:47' asDateAndTime). (DSStepIntoRecord new dateTime: '2024-09-23T15:02:54' asDateAndTime). @@ -377,13 +377,13 @@ DSRecordHistoryTest >> testCollectTimeDiscrepancies [ { #category : 'tests' } DSRecordHistoryTest >> testComputeIdleTime [ - history records: { + history events: { (DSMouseEnterWindowRecord new dateTime: '2024-09-23T15:02:44' asDateAndTime). (DSDoItRecord new dateTime: '2024-09-23T15:02:47' asDateAndTime) }. self assert: history computeIdleTime equals: 0. - history records: { + history events: { (DSMouseEnterWindowRecord new dateTime: '2024-09-23T15:02:44' asDateAndTime). (DSDoItRecord new dateTime: '2024-09-23T15:02:47' asDateAndTime). (DSStepIntoRecord new dateTime: '2024-09-23T15:02:54' asDateAndTime). @@ -401,7 +401,7 @@ DSRecordHistoryTest >> testComputeIdleTime [ { #category : 'tests' } DSRecordHistoryTest >> testCountDebugActions [ - history records: { + history events: { DSMouseEnterWindowRecord new. DSMouseLeaveWindowRecord new. DSDoItRecord new. @@ -421,14 +421,14 @@ DSRecordHistoryTest >> testCountDebugActions [ { #category : 'tests' } DSRecordHistoryTest >> testDateTime [ - history records: self getRecordsExample. + history events: self getRecordsExample. self assert: history dateTime equals: '2000-05-07T15:02:44' asDateAndTime ] { #category : 'tests' } DSRecordHistoryTest >> testDebugPointAdds [ - history records: { + history events: { (DSBreakDebugPointEventRecord new eventName: DebugPointAdded name). DSMouseEnterWindowRecord new. (DSBreakDebugPointEventRecord new eventName: DebugPointAdded name) } asOrderedCollection. @@ -439,7 +439,7 @@ DSRecordHistoryTest >> testDebugPointAdds [ DSRecordHistoryTest >> testDebugPointEvents [ | debugPointEvents | - history records: { + history events: { (DSBreakDebugPointEventRecord new eventName: DebugPointHit name). DSMouseEnterWindowRecord new. (DSBreakDebugPointEventRecord new eventName: DebugPointAdded name) } asOrderedCollection. @@ -457,7 +457,7 @@ DSRecordHistoryTest >> testDebugPointEvents [ DSRecordHistoryTest >> testDebugPointEventsSelection [ | debugPointEvents | - history records: { + history events: { (DSBreakDebugPointEventRecord new eventName: DebugPointHit name). DSMouseEnterWindowRecord new. (DSBreakDebugPointEventRecord new eventName: DebugPointAdded name). @@ -476,7 +476,7 @@ DSRecordHistoryTest >> testDebugPointEventsSelection [ { #category : 'tests' } DSRecordHistoryTest >> testDebugPointHit [ - history records: { + history events: { (DSBreakDebugPointEventRecord new eventName: DebugPointHit name). DSMouseEnterWindowRecord new. (DSBreakDebugPointEventRecord new eventName: DebugPointAdded name) } asOrderedCollection. @@ -486,7 +486,7 @@ DSRecordHistoryTest >> testDebugPointHit [ { #category : 'tests' } DSRecordHistoryTest >> testDebugPointRemoved [ - history records: { + history events: { (DSBreakDebugPointEventRecord new eventName: DebugPointRemoved name). DSMouseEnterWindowRecord new. (DSBreakDebugPointEventRecord new eventName: DebugPointRemoved name) } asOrderedCollection. @@ -496,7 +496,7 @@ DSRecordHistoryTest >> testDebugPointRemoved [ { #category : 'tests' } DSRecordHistoryTest >> testDetectTimeDiscrepancies [ - history records: self getRecordsExample. + history events: self getRecordsExample. self assert: history detectTimeDiscrepancies equals: 1320. ] @@ -560,7 +560,7 @@ DSRecordHistoryTest >> testEstimateSourceEventOfFrom [ DSRecordHistoryTest >> testEventsAfter [ | listOfEvents | - history records: self getRecordsExample. + history events: self getRecordsExample. listOfEvents := history eventsAfter: '2000-05-07T15:06:05' asDateAndTime. self assert: listOfEvents size equals: 2. @@ -572,7 +572,7 @@ DSRecordHistoryTest >> testEventsAfter [ DSRecordHistoryTest >> testEventsBefore [ | listOfEvents | - history records: self getRecordsExample. + history events: self getRecordsExample. listOfEvents := history eventsBefore: '2000-05-07T15:13:47' asDateAndTime. self assert: listOfEvents size equals: 3. @@ -584,7 +584,7 @@ DSRecordHistoryTest >> testEventsBefore [ { #category : 'tests' } DSRecordHistoryTest >> testExecutedCode [ - history records: { + history events: { DSMouseEnterWindowRecord new. DSDoItRecord new. DSStepIntoRecord new. @@ -664,7 +664,7 @@ DSRecordHistoryTest >> testFindWindowRecordKeyForID [ { #category : 'tests' } DSRecordHistoryTest >> testFixMissingWindowIds [ - history records: { + history events: { DSDoItRecord new. (DSMouseEnterWindowRecord new windowId: 1). DSMethodAddedRecord new. @@ -680,11 +680,11 @@ DSRecordHistoryTest >> testFixMissingWindowIds [ history fixMissingWindowIds. - self assert: history records first windowId equals: -1. - self assert: history records third windowId equals: 1. - self assert: (history records at: 6) windowId equals: -1. - self assert: (history records at: 8) windowId equals: 3. - self assert: (history records at: 10) windowId equals: -1. + self assert: history events first windowId equals: -1. + self assert: history events third windowId equals: 1. + self assert: (history events at: 6) windowId equals: -1. + self assert: (history events at: 8) windowId equals: 3. + self assert: (history events at: 10) windowId equals: -1. self assert: history windowNames size equals: 1. self assert: (history windowNames at: 3) equals: 'TestWindow' @@ -715,7 +715,7 @@ DSRecordHistoryTest >> testFixWindowRecordKeysNames [ DSRecordHistoryTest >> testGetSumOfScrollingPeriods [ | scrollList | - history records: { + history events: { (DSMouseEnterWindowRecord new dateTime: '2026-03-25T10:01:17' asDateAndTime; windowId: 1). @@ -765,7 +765,7 @@ DSRecordHistoryTest >> testGetSumOfScrollingPeriods [ DSRecordHistoryTest >> testMergeContinuousEvents [ | newRecordList | - history records: { + history events: { DSMouseEnterWindowRecord new. DSMouseEnterWindowRecord new. DSMethodAddedRecord new. @@ -900,7 +900,7 @@ DSRecordHistoryTest >> testMergeFilteredWindowJumps [ { #category : 'tests' } DSRecordHistoryTest >> testMethodsAdded [ - history records: { + history events: { DSMouseEnterWindowRecord new. DSMethodAddedRecord new. DSMethodRemovedRecord new. @@ -912,7 +912,7 @@ DSRecordHistoryTest >> testMethodsAdded [ { #category : 'tests' } DSRecordHistoryTest >> testMethodsModified [ - history records: { + history events: { DSMouseEnterWindowRecord new. DSMethodAddedRecord new. DSMethodModifiedRecord new. @@ -927,7 +927,7 @@ DSRecordHistoryTest >> testMethodsModified [ DSRecordHistoryTest >> testMethodsModifiedEvents [ | methodModifiedEvents | - history records: { + history events: { DSMouseEnterWindowRecord new. DSMethodAddedRecord new. (DSMethodModifiedRecord new windowId: 23). @@ -948,7 +948,7 @@ DSRecordHistoryTest >> testMethodsModifiedEvents [ { #category : 'tests' } DSRecordHistoryTest >> testMethodsRemoved [ - history records: { + history events: { DSMouseEnterWindowRecord new. DSMethodAddedRecord new. DSMethodRemovedRecord new. @@ -970,7 +970,7 @@ DSRecordHistoryTest >> testName [ { #category : 'tests' } DSRecordHistoryTest >> testNumberOfSteps [ - history records: { + history events: { DSProceedRecord new. DSMouseEnterWindowRecord new. DSReturnValue new. @@ -1025,7 +1025,7 @@ DSRecordHistoryTest >> testProcessRecords [ history processRecords: recordList. - self assert: history records size equals: 12. + self assert: history events size equals: 12. self assert: history windows size equals: 3. self assert: history windowsHistory size equals: 3. self assert: history filteredWindows size equals: 3. @@ -1054,7 +1054,7 @@ DSRecordHistoryTest >> testProcessRecordsOneWindow [ history processRecords: recordList. - self assert: history records size equals: 4. + self assert: history events size equals: 4. self assert: history windows size equals: 1. self assert: history windowsHistory size equals: 1. self assert: history filteredWindows size equals: 1. @@ -1087,7 +1087,7 @@ DSRecordHistoryTest >> testReconstructSourcesOfDebuggerOpenings [ sourceEvent1 := DSDebugItRecord new windowId: 1. sourceEvent2 := DSPrintItRecord new windowId: 3. - history records: { + history events: { DSDoItRecord new. sourceEvent1. DSStepIntoRecord new. @@ -1118,7 +1118,7 @@ DSRecordHistoryTest >> testReconstructWindowsToolInfo [ windowIdentityHash: 1; toolIdentityHash: 42. - history records: { + history events: { (DSMouseEnterWindowRecord new toolInfo: toolInfoExample). DSDebugItRecord new. (DSMouseEnterWindowRecord new toolInfo: nil) }. @@ -1139,21 +1139,21 @@ DSRecordHistoryTest >> testReconstructWindowsToolInfo [ { #category : 'tests' } DSRecordHistoryTest >> testStartTime [ - history records: self getRecordsExample. + history events: self getRecordsExample. self assert: history startTime equals: '15:02:44' asTime ] { #category : 'tests' } DSRecordHistoryTest >> testStopTime [ - history records: self getRecordsExample. + history events: self getRecordsExample. self assert: history stopTime equals: '15:24:44' asTime ] { #category : 'tests' } DSRecordHistoryTest >> testTimeTaken [ - history records: { + history events: { (DSMouseEnterWindowRecord new dateTime: '2024-09-23T15:02:44' asDateAndTime). (DSDoItRecord new dateTime: '2024-09-23T15:02:47' asDateAndTime). (DSStepIntoRecord new dateTime: '2024-09-23T15:02:54' asDateAndTime). diff --git a/DebuggingSpy/DSRecordHistory.class.st b/DebuggingSpy/DSRecordHistory.class.st index 749d0e6..8bb14f5 100644 --- a/DebuggingSpy/DSRecordHistory.class.st +++ b/DebuggingSpy/DSRecordHistory.class.st @@ -7,7 +7,6 @@ Class { #instVars : [ 'taskName', 'user', - 'records', 'windowsHistory', 'tag', 'windowNames', @@ -15,7 +14,8 @@ Class { 'windowJumps', 'filteredWindowJumps', 'filteredWindows', - 'mergedWindowJumps' + 'mergedWindowJumps', + 'events' ], #category : 'DebuggingSpy-Records-Extensions', #package : 'DebuggingSpy', @@ -57,7 +57,7 @@ DSRecordHistory class >> windowLeaveEventTypes [ DSRecordHistory >> absoluteTimeTaken [ "The absolute time taken to perform the recording of user events, including unmonitoring activities (interruptions or activities outside the IDE)." - ^ records last dateTime asSeconds - records first dateTime asSeconds + ^ events last dateTime asSeconds - events first dateTime asSeconds ] { #category : 'API-history' } @@ -71,7 +71,7 @@ DSRecordHistory >> addWindowRecord: aDSRecord [ { #category : 'private - history' } DSRecordHistory >> allRecordsOfKind: aClass [ - ^ records select: [ :record | record isKindOf: aClass ] + ^ events select: [ :record | record isKindOf: aClass ] ] { #category : 'API-history' } @@ -79,7 +79,7 @@ DSRecordHistory >> buildWindowHistory [ self windowsHistory removeAll. self fixMissingWindowIds. - records do: [ :r | self addWindowRecord: r ]. + events do: [ :r | self addWindowRecord: r ]. self fixWindowRecordKeysNames ] @@ -125,18 +125,18 @@ DSRecordHistory >> collectScrollingPeriods [ i := 1. scrollingPeriods := OrderedCollection new. - [ i <= records size ] whileTrue: [ - (records at: i) class = DSScrollingRecord ifTrue: [ + [ i <= events size ] whileTrue: [ + (events at: i) class = DSScrollingRecord ifTrue: [ | start stop | - start := (records at: i) dateTime. - stop := (records at: i) dateTime. + start := (events at: i) dateTime. + stop := (events at: i) dateTime. i := i + 1. - [ i <= records size and: [ (records at: i) class = DSScrollingRecord ] ] whileTrue: [ - stop := (records at: i) dateTime. + [ i <= events size and: [ (events at: i) class = DSScrollingRecord ] ] whileTrue: [ + stop := (events at: i) dateTime. i := i + 1 ]. scrollingPeriods add: { start. - stop } -> (records at: i - 1) windowId ]. + stop } -> (events at: i - 1) windowId ]. i := i + 1 ]. ^ scrollingPeriods @@ -147,7 +147,7 @@ DSRecordHistory >> collectTimeDiscrepancies [ "Returns a dictionary which contains all delta between two records above than 5s" | time previousRecord copyOfRecords deltas | - copyOfRecords := records deepCopy. + copyOfRecords := events deepCopy. time := 0. deltas := OrderedCollection new. previousRecord := copyOfRecords first. @@ -184,7 +184,7 @@ DSRecordHistory >> countDebugActions [ { #category : 'accessing' } DSRecordHistory >> dateTime [ - ^records first dateTime + ^events first dateTime ] { #category : 'API-history' } @@ -209,7 +209,7 @@ DSRecordHistory >> debugPointAnalysisMap [ { #category : 'private - history' } DSRecordHistory >> debugPointEvents [ - ^ self records select: [ :r | (r isKindOf: DSAbstractDebugPointEventRecord)] + ^ self events select: [ :r | (r isKindOf: DSAbstractDebugPointEventRecord)] ] { #category : 'private - history' } @@ -237,8 +237,8 @@ DSRecordHistory >> detectTimeDiscrepancies [ | currentRecord totalDelta | totalDelta := 0. - currentRecord := records first. - records do: [ :r | + currentRecord := events first. + events do: [ :r | | delta | ((r isKindOf: DSWindowOpenedRecord) and: [ 'Finish task *' match: r windowName asString ]) ifTrue: [ ^ totalDelta ]. delta := r dateTime asSeconds - currentRecord dateTime asSeconds. @@ -268,14 +268,26 @@ DSRecordHistory >> estimateSourceEventOf: aDSDebuggerOpeningRecord from: aRecord ^ aRecordList at: eventIndex - 1 ] +{ #category : 'accessing' } +DSRecordHistory >> events [ + + ^ events +] + +{ #category : 'accessing' } +DSRecordHistory >> events: anObject [ + + events := anObject +] + { #category : 'API-history' } DSRecordHistory >> eventsAfter: aDateAndTime [ - ^records select:[:e| e dateTime > aDateAndTime] + ^events select:[:e| e dateTime > aDateAndTime] ] { #category : 'API-history' } DSRecordHistory >> eventsBefore: aDateAndTime [ - ^records select:[:e| e dateTime < aDateAndTime] + ^events select:[:e| e dateTime < aDateAndTime] ] { #category : 'API-history' } @@ -341,7 +353,7 @@ DSRecordHistory >> fixMissingWindowIds [ openedWindowStack := Stack new. windowNames := Dictionary new. - records do: [ :r | + events do: [ :r | r windowId ifNotNil: [ ({ DSWindowClosedRecord. @@ -406,9 +418,9 @@ DSRecordHistory >> mergeContinuousEvents [ | newRecords merge record | newRecords := OrderedCollection new. merge := OrderedCollection new. - record := records first. + record := events first. merge add: record. - (records copy asOrderedCollection + (events copy asOrderedCollection removeFirst; yourself) do: [ :next | record class = next class ifFalse: [ @@ -493,13 +505,13 @@ DSRecordHistory >> processRecords: anArrayOfRecords [ "Build the history from an array of records" "events with window id equals to 0 are automatic events triggered while opening a spec presenter while the window is not already open -> noise " - records := (anArrayOfRecords reject: [ :e | #( 0 ) includes: e windowId ]). + events := (anArrayOfRecords reject: [ :e | #( 0 ) includes: e windowId ]). "Transform raw events to model events" (self allRecordsOfKind: DSAbstractDebugPointEventRecord) do: #asDebugPointRecord. "Detect if we're in a specific task" - (records first isKindOf: DSStartTaskRecord) ifTrue: [ taskName := records first taskName ]. + (events first isKindOf: DSStartTaskRecord) ifTrue: [ taskName := events first taskName ]. "Windows" self buildWindowHistory. @@ -520,7 +532,7 @@ DSRecordHistory >> reconstructSourcesOfDebuggerOpenings [ sortedDebuggerWindows := (windows select: [ :w | w isDebugger ]) sort: [ :d1 :d2 | d1 events first dateTime < d2 events first dateTime ]. - recordsCopy := records copy asOrderedCollection. + recordsCopy := events copy asOrderedCollection. sortedDebuggerWindows do: [ :w | | sourceEvent | @@ -535,7 +547,7 @@ DSRecordHistory >> reconstructWindowsToolInfo [ | toolInfos validWindows | toolInfos := Dictionary new. - records do: [ :record | + events do: [ :record | (record class = DSMouseEnterWindowRecord and: [ record toolInfo isNotNil ]) ifTrue: [ toolInfos at: record toolInfo windowIdentityHash ifAbsentPut: record toolInfo ] ]. @@ -551,21 +563,9 @@ DSRecordHistory >> reconstructWindowsToolInfo [ window toolInfo: (toolInfos at: id ifAbsent: [ nil ]) ] ]. ] -{ #category : 'accessing' } -DSRecordHistory >> records [ - - ^ records -] - -{ #category : 'accessing' } -DSRecordHistory >> records: anObject [ - - records := anObject -] - { #category : 'initialization' } DSRecordHistory >> reprocessRecords [ - self processRecords: records asOrderedCollection + self processRecords: events asOrderedCollection ] { #category : 'private - history' } @@ -579,12 +579,12 @@ DSRecordHistory >> secondarySourcesOfDebuggerOpenings [ { #category : 'accessing' } DSRecordHistory >> startTime [ - ^ records first dateTime asTime + ^ events first dateTime asTime ] { #category : 'accessing' } DSRecordHistory >> stopTime [ - ^records last dateTime asTime + ^events last dateTime asTime ] { #category : 'accessing' } From 658997e4b68da4c7465097be9602a6abec214114 Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Thu, 23 Apr 2026 15:02:45 +0200 Subject: [PATCH 11/16] fix: merge actions --- DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index a4814d0..18c1ff8 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -186,8 +186,7 @@ DSRecordBrowserPresenter >> addRecordButton [ label: 'Add'; icon: (self iconNamed: #smallAdd); help: 'Add a new record.'; - action: [ self openAddFileDialog ]; - yourself + action: [ self openAddFileDialog ] ] { #category : 'layout' } @@ -325,8 +324,7 @@ DSRecordBrowserPresenter >> filterRecordsButton [ label: 'Filter'; icon: (self iconNamed: #diff); help: 'Filter records.'; - action: [ recordsFilter open ]; - yourself + action: [ recordsFilter open ] ] { #category : 'helpers' } @@ -345,7 +343,7 @@ DSRecordBrowserPresenter >> getNumberOfEventsPerType [ dict := Dictionary new. DSAbstractEventRecord getLeafSubClasses do: [ :recordClass | dict at: recordClass put: 0 ]. selectedHistory ifNotNil: [ - selectedHistory records do: [ :record | dict at: record class update: [ :nbOfRecords | nbOfRecords + 1 ] ] ]. + selectedHistory events do: [ :record | dict at: record class update: [ :nbOfRecords | nbOfRecords + 1 ] ] ]. ^ dict ] From b5b979b8a8574e568ac19993bdae29a0ea6ab920 Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Thu, 23 Apr 2026 15:50:10 +0200 Subject: [PATCH 12/16] refactor: remove unused method --- DebuggingSpy-Browser/DSWindowActivityRecord.extension.st | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 DebuggingSpy-Browser/DSWindowActivityRecord.extension.st diff --git a/DebuggingSpy-Browser/DSWindowActivityRecord.extension.st b/DebuggingSpy-Browser/DSWindowActivityRecord.extension.st deleted file mode 100644 index 71a7597..0000000 --- a/DebuggingSpy-Browser/DSWindowActivityRecord.extension.st +++ /dev/null @@ -1,7 +0,0 @@ -Extension { #name : 'DSWindowActivityRecord' } - -{ #category : '*DebuggingSpy-Browser' } -DSWindowActivityRecord >> printAsFormattedTime [ - - ^ nil -] From 9ec806133cf09e08d1d6546c3f319b830225b3aa Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Mon, 27 Apr 2026 10:01:57 +0200 Subject: [PATCH 13/16] feat: new stats in browser --- .../DSRecordBrowserPresenter.class.st | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index 18c1ff8..009bfd6 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -154,6 +154,12 @@ DSRecordBrowserPresenter >> activityPresenter [ 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 ]); @@ -484,6 +490,9 @@ DSRecordBrowserPresenter >> recordsPresenter [ 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 ]); @@ -633,7 +642,16 @@ 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) }. stats doWithIndex: [ :stat :index | statisticsPresenter add: stat asPresenter atPoint: 1 @ index ] ] From 90abe05c35daf4a2b164d1e05f573c6041143acc Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Mon, 27 Apr 2026 10:59:50 +0200 Subject: [PATCH 14/16] fix: spelling mistake --- DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index 009bfd6..7b49fc2 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -648,10 +648,11 @@ DSRecordBrowserPresenter >> updateStatisticsPresenter [ ('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) }. + ('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 ] ] From 0e31a2dd13e43bc82d94f3e895d7d3d5a715001e Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Mon, 27 Apr 2026 14:50:47 +0200 Subject: [PATCH 15/16] fix: PR changes --- .../DSRecordBrowserPresenterTest.class.st | 58 ++++++++++++++++--- .../DSRecordBrowserPresenter.class.st | 4 +- DebuggingSpy/DSRecordHistory.class.st | 4 +- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st index 691c388..9f75365 100644 --- a/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st +++ b/DebuggingSpy-Browser-Tests/DSRecordBrowserPresenterTest.class.st @@ -384,16 +384,48 @@ DSRecordBrowserPresenterTest >> testStopRecording [ { #category : 'tests' } DSRecordBrowserPresenterTest >> testUpdateActivityPresenter [ - | presenter history | + | 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 := browser getHistoryFrom: self generateRecordsFile. + history := DSRecordHistory on: records. + history windowJumps: jumps. browser selectedHistory: history. browser updateActivityPresenter. - self assert: presenter roots equals: history windowJumps + self assert: presenter roots equals: jumps ] { #category : 'tests' } @@ -445,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 fifth 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 7b49fc2..22d0f89 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -644,7 +644,7 @@ DSRecordBrowserPresenter >> updateStatisticsPresenter [ ('Idle time: ' , (Time fromSeconds: selectedHistory computeIdleTime) print24). ('Absolute time taken: ' , (Time fromSeconds: selectedHistory absoluteTimeTaken) print24). ('Number of debug actions: ' , selectedHistory countDebugActions asString). - ('Date : ' , selectedHistory dateTime asString). + ('Date: ' , selectedHistory dateTime asString). ('Debug points added: ' , selectedHistory debugPointAdds asString). ('Debug points hit: ' , selectedHistory debugPointHit asString). ('Debug points removed: ' , selectedHistory debugPointRemoved asString). @@ -652,7 +652,7 @@ DSRecordBrowserPresenter >> updateStatisticsPresenter [ ('Methods modified: ' , selectedHistory methodsModified asString). ('Methods removed: ' , selectedHistory methodsRemoved asString). ('Number of steps: ' , selectedHistory numberOfSteps asString). - ('Executed code: ' , selectedHistory executedCode asString) }. + ('Executed code: ' , selectedHistory executedCode asString) }. stats doWithIndex: [ :stat :index | statisticsPresenter add: stat asPresenter atPoint: 1 @ index ] ] 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' } From adba4807cfd78c1e2472d675aeaeb9b470dde9fc Mon Sep 17 00:00:00 2001 From: Nicolas Potel Date: Mon, 27 Apr 2026 15:55:59 +0200 Subject: [PATCH 16/16] refactor: presenters actions --- .../DSRecordBrowserPresenter.class.st | 110 ++++++------------ 1 file changed, 37 insertions(+), 73 deletions(-) diff --git a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st index 22d0f89..28a6b7b 100644 --- a/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st +++ b/DebuggingSpy-Browser/DSRecordBrowserPresenter.class.st @@ -115,19 +115,6 @@ DSRecordBrowserPresenter class >> windowType [ ^ 'Debugging Spy' ] -{ #category : 'actions' } -DSRecordBrowserPresenter >> activityActionsFor: aPresenter [ - "Return a list of actions which can be done on a window jump." - - ^ SpActionGroup new addActionWith: [ :anItem | - anItem - name: 'Inspect'; - iconName: #inspect; - description: 'Inspect the selected element.'; - shortcutKey: $i meta; - action: [ aPresenter selectedItem inspect ] ] -] - { #category : 'accessing' } DSRecordBrowserPresenter >> activityLayout [ "Returns the layout that displays the activity table and the selected records if applicable." @@ -168,8 +155,8 @@ DSRecordBrowserPresenter >> activityPresenter [ evaluated: [ :windowJump | windowJump events size ]); beResizable; actions: (SpActionGroup new - add: (self activityActionsFor: presenter); - add: (self historyActionsFor: presenter)) + add: (self commonActionsFor: presenter); + yourself) ] { #category : 'files' } @@ -211,6 +198,27 @@ DSRecordBrowserPresenter >> colorReferential [ 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' } DSRecordBrowserPresenter >> connectPresenters [ "Updates the records and the timeline whenever the selected file is changed." @@ -259,28 +267,13 @@ DSRecordBrowserPresenter >> defaultLayout [ DSRecordBrowserPresenter >> fileActionsFor: aPresenter [ "Return a list of actions which can be done on a file." - ^ 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 history'; - shortcutKey: $h meta; - action: [ selectedHistory inspect ] ]; - addActionWith: [ :anItem | - anItem - name: 'Remove'; - iconName: #remove; - description: 'Remove the file from list'; - shortcutKey: $x meta; - action: [ self removeFile: aPresenter selectedItem ] ] + ^ 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' } @@ -298,7 +291,9 @@ DSRecordBrowserPresenter >> fileListPresenter [ file isDirectory ifTrue: [ file children ] ifFalse: [ { } ] ]; - actions: (self fileActionsFor: presenter); + actions: (SpActionGroup new + add: (self commonActionsFor: presenter); + add: (self fileActionsFor: presenter)); hideColumnHeaders ] @@ -372,19 +367,6 @@ DSRecordBrowserPresenter >> getWindowFromRecord: aRecord [ ^ (selectedHistory windows select: [ :window | window windowId = aRecord windowId ]) first ] -{ #category : 'actions' } -DSRecordBrowserPresenter >> historyActionsFor: aPresenter [ - "Return a list of actions which can be done on a history." - - ^ SpActionGroup new addActionWith: [ :anItem | - anItem - name: 'Inspect history'; - iconName: #history; - description: 'Inspect history.'; - shortcutKey: $h meta; - action: [ (DSRecordHistory on: aPresenter selectedItem events) inspect ] ] -] - { #category : 'initialization' } DSRecordBrowserPresenter >> initializePresenters [ @@ -444,13 +426,6 @@ 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: [ aPresenter selectedItem inspect ] ]; addActionWith: [ :anItem | anItem name: 'Inspect the window'; @@ -496,7 +471,9 @@ DSRecordBrowserPresenter >> recordsPresenter [ addColumn: (SpStringTableColumn new title: 'Time'; evaluated: [ :record | record printAsFormattedTime ]); - actions: (self recordsActionsFor: presenter); + actions: (SpActionGroup new + add: (self commonActionsFor: presenter); + add: (self recordsActionsFor: presenter)); beResizable ] @@ -683,19 +660,6 @@ DSRecordBrowserPresenter >> windowTitle [ ^ 'Debugging Spy browser' ] -{ #category : 'actions' } -DSRecordBrowserPresenter >> windowsActionsFor: aPresenter [ - "Return a list of actions which can be done on a window." - - ^ SpActionGroup new addActionWith: [ :anItem | - anItem - name: 'Inspect'; - iconName: #inspect; - description: 'Inspect the selected element.'; - shortcutKey: $i meta; - action: [ aPresenter selectedItem inspect ] ] -] - { #category : 'accessing' } DSRecordBrowserPresenter >> windowsLayout [ "Returns the layout that displays the windows table and the selected records if applicable." @@ -729,5 +693,5 @@ DSRecordBrowserPresenter >> windowsPresenter [ title: 'Number of events'; evaluated: [ :window | window events size ]); beResizable; - actions: (self windowsActionsFor: presenter) + actions: (self commonActionsFor: presenter) ]