#FEATURE by exept
class: ShowMeHowItWorks
added:
#clear
#fastMoveRelativeX:y:
#freezePin:ofStep:with:
#key:
#selectPin:ofStep:
changed:
#click:inComponent:clickTime:
#findComponent:in:
#movePointerToScreenPosition:speed:
#screenBoundsOfComponent:
#select:
#withViewAndPositionFor:do:
class: ShowMeHowItWorks::ItemInView
added:
#isItemInView
#isVisible
"
COPYRIGHT (c) 2019 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
"{ Package: 'stx:libtool2' }"
"{ NameSpace: Smalltalk }"
ApplicationModel subclass:#FileVersionDiffBrowser
instanceVariableNames:'diffTextView diffTextLabelA diffTextLabelB versionAHolder
versionBHolder infoHolder isMultipleVersionBrowser
versionInfoList versionList versionEntriesList
selectedVersionHolder symbolicVersionList symbolicVersionNameList
selectedSymbolicVersionHolder selectedSymbolicVersionIndexHolder
symbolicToVersionMapping selectedVersionIndexHolder
isMultipleFilesVersionBrowser fileListHolder
selectedFileIndexHolder fileHolder diffTextHolder
versionAIfSingleFileDiff versionBIfSingleFileDiff
fileIfSingleFileDiff'
classVariableNames:''
poolDictionaries:''
category:'Interface-Tools-File'
!
!FileVersionDiffBrowser class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 2019 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
documentation
"
A quickly hacked up browser to show differences between file versions,
allowing easy comparison; will also eventually add capabilities
to checkIn / load files into / from the repository.
[usages:]
FileVersionDiffBrowser openOnAllVersionsOfFile:'Make.proto'.
FileVersionDiffBrowser openOnAllFilesChangedSince:(Date today - 7 days) in:('../../libbasic' asFilename).
[see also:]
[instance variables:]
[class variables:]
"
! !
!FileVersionDiffBrowser class methodsFor:'interface specs'!
windowSpec
"This resource specification was automatically generated
by the UIPainter of ST/X."
"Do not manually edit this!! If it is corrupted,
the UIPainter may not be able to read the specification."
"
UIPainter new openOnClass:FileVersionDiffBrowser andSelector:#windowSpec
FileVersionDiffBrowser new openInterface:#windowSpec
FileVersionDiffBrowser open
"
<resource: #canvas>
^
#(FullSpec
name: windowSpec
uuid: '34d3baee-a108-11e9-a652-b8f6b1108e05'
window:
(WindowSpec
label: 'Version DiffBrowser'
name: 'Version DiffBrowser'
uuid: '90e45e00-7175-11e9-a23a-b8f6b1108e05'
min: (Point 10 10)
bounds: (Rectangle 0 0 865 504)
menu: mainMenu
)
component:
(SpecCollection
collection: (
(VariableVerticalPanelSpec
name: 'VariableVerticalPanel1'
layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 -25 1.0)
uuid: '90e460c6-7175-11e9-a23a-b8f6b1108e05'
component:
(SpecCollection
collection: (
(ViewSpec
name: 'DiffOrSingleMethodCodeBox'
uuid: '90e471a6-7175-11e9-a23a-b8f6b1108e05'
component:
(SpecCollection
collection: (
(ViewSpec
name: 'diffTextViewBox'
layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
uuid: '90e47264-7175-11e9-a23a-b8f6b1108e05'
component:
(SpecCollection
collection: (
(LabelSpec
label: 'A'
name: 'DiffTextLabelA'
layout: (LayoutFrame 0 0 0 0 0 0.5 20 0)
uuid: '90e47318-7175-11e9-a23a-b8f6b1108e05'
translateLabel: true
labelChannel: diffTextLabelA
)
(LabelSpec
label: 'B'
name: 'DiffTextLabelB'
layout: (LayoutFrame 0 0.5 0 0 0 1 20 0)
uuid: '90e47412-7175-11e9-a23a-b8f6b1108e05'
translateLabel: true
labelChannel: diffTextLabelB
)
(ArbitraryComponentSpec
name: 'diffTextView'
layout: (LayoutFrame 0 0.0 20 0.0 0 1.0 0 1.0)
uuid: '90e47502-7175-11e9-a23a-b8f6b1108e05'
hasBorder: false
component: diffTextView
)
)
)
)
)
)
)
)
)
handles: (Any 1.0)
)
(LabelSpec
name: 'InfoLabel'
layout: (LayoutFrame 0 0 -25 1 0 1 0 1)
uuid: '90e47868-7175-11e9-a23a-b8f6b1108e05'
level: -1
translateLabel: true
labelChannel: infoHolder
adjust: left
)
)
)
)
!
windowSpecForMultipleFiles
"This resource specification was automatically generated
by the UIPainter of ST/X."
"Do not manually edit this!! If it is corrupted,
the UIPainter may not be able to read the specification."
"
UIPainter new openOnClass:FileVersionDiffBrowser andSelector:#windowSpecForMultipleFiles
FileVersionDiffBrowser new openInterface:#windowSpecForMultipleFiles
"
<resource: #canvas>
^
#(FullSpec
name: windowSpecForMultipleFiles
uuid: '3c5c60f4-a108-11e9-a652-b8f6b1108e05'
window:
(WindowSpec
label: 'Version DiffBrowser'
name: 'Version DiffBrowser'
uuid: '2b3f2546-d4fd-11e7-af82-c42c033b4871'
min: (Point 10 10)
bounds: (Rectangle 0 0 865 504)
menu: mainMenu
)
component:
(SpecCollection
collection: (
(VariableVerticalPanelSpec
name: 'VariableVerticalPanel1'
layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 -25 1.0)
uuid: '2b3f297e-d4fd-11e7-af82-c42c033b4871'
component:
(SpecCollection
collection: (
(VariableHorizontalPanelSpec
name: 'FileAndVersionAndTagPanel'
uuid: '17c6805c-7184-11e9-a23a-b8f6b1108e05'
component:
(SpecCollection
collection: (
(SequenceViewSpec
name: 'List2'
uuid: '2b3f2d20-d4fd-11e7-af82-c42c033b4871'
model: selectedFileIndexHolder
menu: fileListMenu
hasHorizontalScrollBar: true
hasVerticalScrollBar: true
useIndex: true
sequenceList: fileNameListHolder
)
(VariableHorizontalPanelSpec
name: 'VersionAndTagPanel'
uuid: '2b3f2c08-d4fd-11e7-af82-c42c033b4871'
component:
(SpecCollection
collection: (
(SequenceViewSpec
name: 'VersionList'
uuid: '2b3f2d20-d4fd-11e7-af82-c42c033b4871'
model: selectedVersionIndexHolder
menu: versionsMenu
hasHorizontalScrollBar: true
hasVerticalScrollBar: true
useIndex: true
sequenceList: versionEntriesList
)
(SequenceViewSpec
name: 'List1'
uuid: '2b3f3086-d4fd-11e7-af82-c42c033b4871'
model: selectedSymbolicVersionIndexHolder
menu: symbolicVersionsMenu
hasHorizontalScrollBar: true
hasVerticalScrollBar: true
useIndex: true
sequenceList: symbolicVersionNameList
)
)
)
handles: (Any 0.5 1.0)
)
)
)
handles: (Any 0.5 1.0)
)
(ViewSpec
name: 'DiffBox'
uuid: '2b3f408a-d4fd-11e7-af82-c42c033b4871'
component:
(SpecCollection
collection: (
(ViewSpec
name: 'diffTextViewBox'
layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
uuid: '2b3f415c-d4fd-11e7-af82-c42c033b4871'
component:
(SpecCollection
collection: (
(LabelSpec
label: 'A'
name: 'DiffTextLabelA'
layout: (LayoutFrame 0 0 0 0 0 0.5 20 0)
uuid: '2b3f426a-d4fd-11e7-af82-c42c033b4871'
translateLabel: true
labelChannel: diffTextLabelA
)
(LabelSpec
label: 'B'
name: 'DiffTextLabelB'
layout: (LayoutFrame 0 0.5 0 0 0 1 20 0)
uuid: '2b3f43d2-d4fd-11e7-af82-c42c033b4871'
translateLabel: true
labelChannel: diffTextLabelB
)
(ArbitraryComponentSpec
name: 'diffTextView'
layout: (LayoutFrame 0 0.0 20 0.0 0 1.0 0 1.0)
uuid: '2b3f4508-d4fd-11e7-af82-c42c033b4871'
hasBorder: false
component: diffTextView
)
)
)
)
)
)
)
)
)
handles: (Any 0.5 1.0)
)
(LabelSpec
name: 'InfoLabel'
layout: (LayoutFrame 0 0 -25 1 0 1 0 1)
uuid: '2b3f4a44-d4fd-11e7-af82-c42c033b4871'
level: -1
translateLabel: true
labelChannel: infoHolder
adjust: left
)
)
)
)
!
windowSpecForMultipleVersions
"This resource specification was automatically generated
by the UIPainter of ST/X."
"Do not manually edit this!! If it is corrupted,
the UIPainter may not be able to read the specification."
"
UIPainter new openOnClass:FileVersionDiffBrowser andSelector:#windowSpecForMultipleVersions
FileVersionDiffBrowser new openInterface:#windowSpecForMultipleVersions
"
<resource: #canvas>
^
#(FullSpec
name: windowSpecForMultipleVersions
uuid: '441c0448-a108-11e9-a652-b8f6b1108e05'
window:
(WindowSpec
label: 'Version DiffBrowser'
name: 'Version DiffBrowser'
uuid: '2b3f2546-d4fd-11e7-af82-c42c033b4871'
min: (Point 10 10)
bounds: (Rectangle 0 0 865 504)
menu: mainMenu
)
component:
(SpecCollection
collection: (
(VariableVerticalPanelSpec
name: 'VariableVerticalPanel1'
layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 -25 1.0)
uuid: '2b3f297e-d4fd-11e7-af82-c42c033b4871'
component:
(SpecCollection
collection: (
(VariableHorizontalPanelSpec
name: 'VersionAndTagBox'
uuid: '2b3f2c08-d4fd-11e7-af82-c42c033b4871'
component:
(SpecCollection
collection: (
(SequenceViewSpec
name: 'VersionList'
uuid: '2b3f2d20-d4fd-11e7-af82-c42c033b4871'
model: selectedVersionIndexHolder
menu: versionsMenu
hasHorizontalScrollBar: true
hasVerticalScrollBar: true
useIndex: true
sequenceList: versionEntriesList
)
(SequenceViewSpec
name: 'List1'
uuid: '2b3f3086-d4fd-11e7-af82-c42c033b4871'
model: selectedSymbolicVersionIndexHolder
menu: symbolicVersionsMenu
hasHorizontalScrollBar: true
hasVerticalScrollBar: true
useIndex: true
sequenceList: symbolicVersionNameList
)
)
)
handles: (Any 0.5 1.0)
)
(ViewSpec
name: 'DiffBox'
uuid: '2b3f408a-d4fd-11e7-af82-c42c033b4871'
component:
(SpecCollection
collection: (
(ViewSpec
name: 'diffTextViewBox'
layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
uuid: '2b3f415c-d4fd-11e7-af82-c42c033b4871'
component:
(SpecCollection
collection: (
(LabelSpec
label: 'A'
name: 'DiffTextLabelA'
layout: (LayoutFrame 0 0 0 0 0 0.5 20 0)
uuid: '2b3f426a-d4fd-11e7-af82-c42c033b4871'
translateLabel: true
labelChannel: diffTextLabelA
)
(LabelSpec
label: 'B'
name: 'DiffTextLabelB'
layout: (LayoutFrame 0 0.5 0 0 0 1 20 0)
uuid: '2b3f43d2-d4fd-11e7-af82-c42c033b4871'
translateLabel: true
labelChannel: diffTextLabelB
)
(ArbitraryComponentSpec
name: 'diffTextView'
layout: (LayoutFrame 0 0.0 20 0.0 0 1.0 0 1.0)
uuid: '2b3f4508-d4fd-11e7-af82-c42c033b4871'
hasBorder: false
component: diffTextView
)
)
)
)
)
)
)
)
)
handles: (Any 0.5 1.0)
)
(LabelSpec
name: 'InfoLabel'
layout: (LayoutFrame 0 0 -25 1 0 1 0 1)
uuid: '2b3f4a44-d4fd-11e7-af82-c42c033b4871'
level: -1
translateLabel: true
labelChannel: infoHolder
adjust: left
)
)
)
)
! !
!FileVersionDiffBrowser class methodsFor:'menu specs'!
mainMenu
"This resource specification was automatically generated
by the MenuEditor of ST/X."
"Do not manually edit this!! If it is corrupted,
the MenuEditor may not be able to read the specification."
"
MenuEditor new openOnClass:FileVersionDiffBrowser andSelector:#mainMenu
(Menu new fromLiteralArrayEncoding:(FileVersionDiffBrowser mainMenu)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
label: 'File'
submenu:
(Menu
(
(MenuItem
label: 'Create PatchFile...'
itemValue: createPatchFile
)
(MenuItem
label: '-'
)
(MenuItem
label: 'Exit'
itemValue: closeRequest
)
)
nil
nil
)
)
(MenuItem
label: 'View'
submenuChannel: viewMenu
)
(MenuItem
label: 'MENU_Help'
startGroup: conditionalRight
submenu:
(Menu
(
(MenuItem
label: 'Documentation'
itemValue: openDocumentation
)
(MenuItem
label: '-'
)
(MenuItem
label: 'About this Application...'
itemValue: openAboutThisApplication
)
)
nil
nil
)
)
)
nil
nil
)
!
versionsMenu
"This resource specification was automatically generated
by the MenuEditor of ST/X."
"Do not manually edit this!! If it is corrupted,
the MenuEditor may not be able to read the specification."
"
MenuEditor new openOnClass:VersionDiffBrowser andSelector:#mainMenu
(Menu new fromLiteralArrayEncoding:(VersionDiffBrowser mainMenu)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
label: 'Compare against Previous (Older) Version'
nameKey: CompareAgainstPreviousVersion
itemValue: versionMenuCompareAgainstPreviousVersion
enabled: hasPreviousVersionInVersionList
)
(MenuItem
label: 'Compare against Next (Younger) Version'
nameKey: CompareAgainstNextVersion
itemValue: versionMenuCompareAgainstNextVersion
enabled: hasNextVersionInVersionList
)
)
nil
nil
)
"Created: / 05-02-2017 / 11:11:30 / cg"
"Modified: / 06-02-2017 / 09:27:22 / cg"
!
viewMenu
"This resource specification was automatically generated
by the MenuEditor of ST/X."
"Do not manually edit this!! If it is corrupted,
the MenuEditor may not be able to read the specification."
"
MenuEditor new openOnClass:FileVersionDiffBrowser andSelector:#viewMenu
(Menu new fromLiteralArrayEncoding:(FileVersionDiffBrowser viewMenu)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
label: 'Show Log Messages'
itemValue: showLogMessages
)
)
nil
nil
)
! !
!FileVersionDiffBrowser class methodsFor:'startup'!
openOnAllFilesChangedSince:aDateOrTimestamp in:aSetOfFilesOrADirectoryFilename
"create a FileVersionDiffBrowser instance and set the list of files.
When a file is selected, the version list is extracted,
and the diff list is generated from the file's current version against
the selected version in the top selection list"
|setOfFiles theBrowser filesChangedSince sinceTimestamp|
sinceTimestamp := aDateOrTimestamp asTimestamp.
setOfFiles := aSetOfFilesOrADirectoryFilename.
setOfFiles isFilename ifTrue:[
setOfFiles := setOfFiles directoryContentsAsFilenames.
].
filesChangedSince := setOfFiles
select:[:fn | fn modificationTime > sinceTimestamp].
filesChangedSince sort:[:a :b | a name < b name].
theBrowser := self new.
theBrowser allButOpenInterface:#windowSpecForMultipleFiles.
theBrowser beMultipleFilesVersionBrowser.
theBrowser fileList:filesChangedSince.
"/ theBrowser classHolder:(ValueHolder with:aClass).
"/ theBrowser setupForClass:aClass againstVersion:nil.
theBrowser window label:(self resources string:'Versions of %1 files' with:setOfFiles size).
theBrowser openWindow.
^ theBrowser.
"
FileVersionDiffBrowser
openOnAllFilesChangedSince:(Date today - 7 days)
in:('../../libbasic' asFilename files).
"
"Created: / 07-07-2019 / 18:58:01 / Claus Gittinger"
"Modified: / 08-07-2019 / 01:36:01 / Claus Gittinger"
!
openOnAllVersionsOfFile:aFilename
"create a VersionDiffBrowser instance and set the file.
The diff is generated from aFilename's current version against
the selected version in the top selection list"
|theBrowser|
theBrowser := self new.
theBrowser allButOpenInterface:#windowSpecForMultipleVersions.
theBrowser beMultipleVersionBrowser.
theBrowser fileHolder value:aFilename.
theBrowser setupForAllVersionsOfFile:aFilename.
theBrowser window label:(self resources string:'Versions of %1' with:aFilename baseName).
theBrowser openWindow.
^ theBrowser.
"
self openOnAllVersionsOfFile:'Make.proto' asFilename
self openOnAllVersionsOfFile:'../../libbasic/Array.st' asFilename
"
"Created: / 07-07-2019 / 19:26:28 / Claus Gittinger"
"Modified: / 07-07-2019 / 22:40:38 / Claus Gittinger"
"Modified (comment): / 08-07-2019 / 01:27:03 / Claus Gittinger"
!
openOnAllVersionsOfFiles:aSetOfFilenames
"create a VersionDiffBrowser instance and set the list of files.
When a file is selected, the version list is extracted,
and the diff set is generated from the file's current version against
the selected version in the top selection list"
|theBrowser|
theBrowser := self new.
theBrowser allButOpenInterface:#windowSpecForMultipleFiles.
theBrowser beMultipleFilesVersionBrowser.
theBrowser beMultipleVersionBrowser.
theBrowser fileList:(aSetOfFilenames collect:#asFilename).
theBrowser window label:(self resources string:'Versions of %1 files' with:aSetOfFilenames size).
theBrowser openWindow.
^ theBrowser.
"
self openOnAllVersionsOfFiles:#('Make.proto' 'Make.spec')
"
"Created: / 07-07-2019 / 19:29:38 / Claus Gittinger"
"Modified: / 08-07-2019 / 00:30:31 / Claus Gittinger"
!
openOnFile:aFilename againstVersion:aVersionA
"create a VersionDiffBrowser instance and set the diffs of the
browser. The diffs are generated from aFilename's current against some version
via the source code manager."
|theBrowser fn|
fn := aFilename asFilename.
theBrowser := self new.
theBrowser allButOpen.
theBrowser setupForFile:fn againstVersion:aVersionA.
theBrowser window label:(self resources string:'Diffs of %1 %2 against current' with:fn baseName with:aVersionA).
theBrowser openWindow.
^ theBrowser.
"
self openOnFile:'Make.proto' againstVersion:'1.2'
self openOnFile:'Make.proto' againstVersion:#newest - against the newest repository version
"
"Created: / 07-07-2019 / 19:31:13 / Claus Gittinger"
"Modified: / 08-07-2019 / 00:42:22 / Claus Gittinger"
!
openOnFile:file1 andFile:file2
|fn1 fn2|
fn1 := file1 asFilename.
fn2 := file2 asFilename.
^ self
openOnFile:fn1 labelA:fn1 baseName andFile:fn2 labelB:fn2 baseName
title:(self resources string:'%1 vs. %2'
with:fn1 baseName with:fn2 baseName)
ifSame:nil
"
FileVersionDiffBrowser
openOnFile:'../../libbasic/FloatArray.st'
andFile:'../../libbasic/DoubleArray.st'
"
"Created: / 08-07-2019 / 00:52:18 / Claus Gittinger"
!
openOnFile:fileA labelA:aLabelA andFile:fileB labelB:aLabelB title:title
"create a VersionDiffBrowser instance and set the difflist of the
browser. The diffs are generated from two files."
^ self
openOnFile:fileA labelA:aLabelA
andFile:fileB labelB:aLabelB
title:title ifSame:nil
"
self
openOnFile:'../../libbasic/FloatArray.st' labelA:'FloatArray'
andFile:'../../libbasic/DoubleArray.st' labelB:'DoubleArray'
title:'FloatArray vs. DoubleArray'
"
"Created: / 07-07-2019 / 19:32:07 / Claus Gittinger"
"Modified (comment): / 08-07-2019 / 00:37:50 / Claus Gittinger"
!
openOnFile:fileA labelA:aLabelA andFile:fileB labelB:aLabelB title:title ifSame:sameAction
"create a VersionDiffBrowser instance and set the class change set of the
browser. The class diff set is generated from two classes."
|theBrowser fn1 fn2|
fn1 := fileA asFilename.
fn2 := fileB asFilename.
theBrowser := self new.
theBrowser allButOpen.
theBrowser setupForFile:fn1 labelA:aLabelA andFile:fn2 labelB:aLabelB.
theBrowser window label:title.
theBrowser openWindow.
^ theBrowser.
"
FileVersionDiffBrowser
openOnFile:'../../libbasic/FloatArray.st' labelA:'FloatArray'
andFile:'../../libbasic/DoubleArray.st' labelB:'DoubleArray'
title:'Some diffs' ifSame:nil
"
"Created: / 07-07-2019 / 20:05:16 / Claus Gittinger"
"Modified (comment): / 08-07-2019 / 00:51:29 / Claus Gittinger"
!
openOnFile:aFilename versionA:versionA versionB:versionB
"create a VersionDiffBrowser instance and set the class change set of the
browser. The class diff set is generated from two versions of aClass via
the source code manager."
|theBrowser|
theBrowser := self new.
theBrowser allButOpen.
theBrowser setupForFile:aFilename versionA:versionA versionB:versionB.
theBrowser window label:(self resources
string:'%1 Versions %2 vs. %3'
with:aFilename baseName with:versionA with:versionB).
theBrowser openWindow.
^ theBrowser.
"
self openOnFile:'Make.proto' versionA:'1.1' versionB:'1.2'
"
"Created: / 07-07-2019 / 20:06:15 / Claus Gittinger"
! !
!FileVersionDiffBrowser methodsFor:'accessing'!
beMultipleFilesVersionBrowser
isMultipleFilesVersionBrowser := true
"Created: / 07-07-2019 / 18:58:49 / Claus Gittinger"
!
beMultipleVersionBrowser
isMultipleVersionBrowser := true
!
isMultipleFilesVersionBrowser
^ isMultipleFilesVersionBrowser
"Created: / 07-07-2019 / 19:53:15 / Claus Gittinger"
!
isMultipleVersionBrowser
^ isMultipleVersionBrowser
"Modified: / 08-05-2019 / 10:59:40 / Claus Gittinger"
! !
!FileVersionDiffBrowser methodsFor:'aspects'!
diffTextHolder
diffTextHolder isNil ifTrue:[
diffTextHolder := '' asValue
].
^ diffTextHolder
"Created: / 07-07-2019 / 20:04:23 / Claus Gittinger"
!
diffTextLabelA
"aspect for the label for version A"
^ diffTextLabelA.
"Modified: / 08-05-2019 / 11:03:23 / Claus Gittinger"
!
diffTextLabelB
"aspect for the label for version B"
^ diffTextLabelB.
"Modified: / 08-05-2019 / 11:03:32 / Claus Gittinger"
!
diffTextView
"
return the component for the diff text view.
<return: HVScrollableView>
"
|v|
diffTextView isNil ifTrue:[
v := DiffCodeView new.
v textViewClass:CodeView.
v initialize.
diffTextView := HVScrollableView
forView:v
miniScrollerH:true miniScrollerV:false.
diffTextView addNextPreviousButtons.
].
^ diffTextView
"Modified: / 06-10-2006 / 14:30:42 / cg"
!
fileHolder
fileHolder isNil ifTrue:[
fileHolder := nil asValue
].
^ fileHolder
"Created: / 07-07-2019 / 20:10:47 / Claus Gittinger"
!
fileList:aList
self fileListHolder contents:aList
"Created: / 08-07-2019 / 00:28:32 / Claus Gittinger"
!
fileListHolder
"aspect for the 'list of files' list.
<return: List>"
fileListHolder isNil ifTrue:[
fileListHolder := List new
].
^ fileListHolder
"Created: / 07-07-2019 / 19:46:44 / Claus Gittinger"
!
fileNameListHolder
"aspect for the 'list of file' list.
<return: List>"
^ BlockValue
with:[:l | l collect:#baseName]
argument:(self fileListHolder)
"Created: / 07-07-2019 / 19:47:13 / Claus Gittinger"
!
infoHolder
^ infoHolder.
"Modified: / 08-05-2019 / 11:05:10 / Claus Gittinger"
!
selectedFileIndexHolder
selectedFileIndexHolder isNil ifTrue:[
selectedFileIndexHolder := nil asValue.
selectedFileIndexHolder onChangeSend:#selectedFileIndexHolderChanged to:self.
].
^ selectedFileIndexHolder
"Created: / 07-07-2019 / 19:00:13 / Claus Gittinger"
!
selectedSymbolicVersionHolder
^ selectedSymbolicVersionHolder
"Modified: / 08-05-2019 / 11:08:42 / Claus Gittinger"
!
selectedSymbolicVersionIndexHolder
^ selectedSymbolicVersionIndexHolder
"Created: / 28-05-2019 / 15:32:03 / Claus Gittinger"
!
selectedVersionHolder
^ selectedVersionHolder
"Modified: / 08-05-2019 / 11:09:18 / Claus Gittinger"
!
selectedVersionIndex
^ selectedVersionIndexHolder value ? 0
"Created: / 23-05-2018 / 11:35:50 / Claus Gittinger"
"Modified: / 08-05-2019 / 11:09:50 / Claus Gittinger"
!
selectedVersionIndexHolder
^ selectedVersionIndexHolder
"Created: / 29-11-2017 / 13:02:49 / cg"
"Modified: / 08-05-2019 / 11:09:46 / Claus Gittinger"
!
symbolicVersionList
^ symbolicVersionList
"Modified: / 08-05-2019 / 11:10:23 / Claus Gittinger"
!
symbolicVersionNameList
^ symbolicVersionNameList
"Created: / 28-05-2019 / 15:42:12 / Claus Gittinger"
!
versionEntriesList
^ versionEntriesList
"Created: / 29-11-2017 / 13:06:14 / cg"
"Modified: / 08-05-2019 / 11:10:38 / Claus Gittinger"
!
versionList
^ versionList
"Modified: / 08-05-2019 / 11:10:53 / Claus Gittinger"
! !
!FileVersionDiffBrowser methodsFor:'aspects-menu'!
hasNextVersionInVersionList
"versions are sorted youngest first.
If the current selected one is the first, there is no next version"
^ (self selectedVersionIndex) > 1.
"Modified: / 23-05-2018 / 11:36:33 / Claus Gittinger"
!
hasPreviousVersionInVersionList
"versions are sorted youngest first.
If the current selected one is the last, there is no previous version"
^ (self selectedVersionIndex) < versionList value size.
"Modified: / 23-05-2018 / 11:36:38 / Claus Gittinger"
!
versionsMenu
^ [
|m item nextVersion prevVersion|
m := self class versionsMenu.
m := m decodeAsLiteralArray.
m findGuiResourcesIn:self.
self hasNextVersionInVersionList ifTrue:[
nextVersion := self versionList at:(self selectedVersionIndex - 1).
item := m atNameKey:#CompareAgainstNextVersion.
item label:(resources string:(item label,' (%1)') with:nextVersion).
].
self hasPreviousVersionInVersionList ifTrue:[
prevVersion := self versionList at:(self selectedVersionIndex + 1).
item := m atNameKey:#CompareAgainstPreviousVersion.
item label:(resources string:(item label,'(%1)') with:prevVersion).
].
m
]
"Modified: / 23-05-2018 / 11:36:18 / Claus Gittinger"
! !
!FileVersionDiffBrowser methodsFor:'change & update'!
selectVersion:version
|idx numShownBefore numShownAfter|
idx := versionList indexOf:version.
"/ if not found, get more version infos
[idx == 0] whileTrue:[
numShownBefore := versionList size.
self updateVersionList.
numShownAfter := versionList size.
idx := versionList indexOf:version.
idx == 0 ifTrue:[
numShownBefore == numShownAfter ifTrue:[
^ self
].
].
].
self selectedVersionIndexHolder value:idx.
"Created: / 28-05-2019 / 14:58:37 / Claus Gittinger"
!
selectedFileIndexHolderChanged
|fn|
fn := self fileListHolder value at:(self selectedFileIndexHolder value).
self fileHolder value:fn.
(self isMultipleVersionBrowser or:[self isMultipleFilesVersionBrowser]) ifTrue:[
self withWaitCursorDo:[
self updateVersionList.
]
]
"Created: / 07-07-2019 / 19:51:17 / Claus Gittinger"
"Modified: / 08-07-2019 / 00:30:51 / Claus Gittinger"
!
selectedSymbolicVersionHolderChanged
|symbolicTag version|
symbolicTag := self selectedSymbolicVersionHolder value.
version := symbolicToVersionMapping at:symbolicTag ifAbsent:nil.
version isNil ifTrue:[
symbolicTag = '-' ifFalse:[
Dialog warn:'No version has this tag ("%1")' with:symbolicTag.
].
^ self.
].
self selectVersion:version
"Modified: / 28-05-2019 / 14:57:56 / Claus Gittinger"
!
selectedSymbolicVersionIndexHolderChanged
self selectedSymbolicVersionHolder value:(symbolicVersionList at:self selectedSymbolicVersionIndexHolder value)
"Created: / 28-05-2019 / 15:32:47 / Claus Gittinger"
!
selectedVersionHolderChanged
self withWaitCursorDo:[
|idx|
"/ possibly expand a contracted list
selectedVersionHolder value = '...' ifTrue:[
idx := self versionList size.
self updateVersionList.
selectedVersionHolder setValue:(self versionList at:idx).
].
"/ update the view
self
setupForFile:fileHolder value
againstVersion:(selectedVersionHolder value).
"/ self showVersionInfoIfNothingSelected
]
"Modified: / 06-02-2017 / 02:32:24 / cg"
"Modified: / 08-07-2019 / 00:05:30 / Claus Gittinger"
!
selectedVersionIndexHolderChanged
self selectedVersionHolder value:(versionList at:self selectedVersionIndexHolder value)
"Created: / 29-11-2017 / 13:04:12 / cg"
!
showActivity:someMessage
"some activityNotification shalt be communicated to the user."
infoHolder value:someMessage.
"Created: / 28-05-2019 / 15:26:34 / Claus Gittinger"
!
update:something with:parameter from:changedObject
(changedObject == fileHolder
or:[changedObject == versionAHolder
or:[changedObject == versionBHolder]]) ifTrue:[
self setupForFile:(fileHolder value) versionA:(versionAHolder value) versionB:(versionBHolder value).
^ self
].
super update:something with:parameter from:changedObject
"Modified: / 17-07-2012 / 17:48:58 / cg"
"Modified: / 08-07-2019 / 00:09:19 / Claus Gittinger"
!
updateLists
"walk over the changeSet(s) and setup the 3 lists:
onlyInA, changed, onlyInB,
Optionally filter extensions, categoryChanges and versionMethods,
changes with same semantic (variable renames)
and changes which have been explicitly filtered by the user."
|listOnlyInA listOnlyInB listChanged
printStringGenerator "sortBlockForChangeLists" filteredList
numIgnoredExtensions numIgnoredVersionMethods
info needFilter entryIsForCommentOrFormatOnly
isIgnoredChange|
"/ listOnlyInA := filteredList := self methodsOnlyInA.
"/ listOnlyInA removeAll.
"/ classChangeSet notNil ifTrue:[
"/ "/ classChangeSet methodsOnlyInA sort:sortBlockForChangeLists.
"/ filteredList := classChangeSet methodsOnlyInA reject:isIgnoredChange.
"/ listOnlyInA addAll: (filteredList collect:printStringGenerator).
"/ ].
"/ methodsOnlyInAFiltered := filteredList.
"/
"/ listOnlyInB := filteredList := self methodsOnlyInB.
"/ listOnlyInB removeAll.
"/ classChangeSet notNil ifTrue:[
"/ "/ classChangeSet methodsOnlyInB sort:sortBlockForChangeLists.
"/ filteredList := classChangeSet methodsOnlyInB reject:isIgnoredChange.
"/ listOnlyInB addAll: (filteredList collect:printStringGenerator).
"/ ].
"/ methodsOnlyInBFiltered := filteredList.
"/ entryIsForCommentOrFormatOnly :=
"/ [:entry |
"/ |commentOnly changeA changeB mthdA mthdB|
"/
"/ commentOnly := false.
"/
"/ changeA := entry first.
"/ changeB := entry second.
"/ changeA isMethodChange ifTrue:[
"/ changeA isMethodCodeChange ifTrue:[
"/ RBCodeDuplicationRule notNil ifTrue:[
"/ mthdA := RBMethod forMethodChange:changeA.
"/ mthdB := RBMethod forMethodChange:changeB.
"/ commentOnly := RBCodeDuplicationRule hasMethod:mthdA sameSemanticAs:mthdB.
"/ ].
"/ ] ifFalse:[
"/ changeA isMethodCategoryChange ifTrue:[
"/ commentOnly := true
"/ ] ifFalse:[
"/ self breakPoint:#cg
"/ ].
"/ ].
"/ ] ifFalse:[
"/ changeA isClassDefinitionChange ifTrue:[
"/ changeA source = changeB source ifTrue:[
"/ commentOnly := true
"/ ] ifFalse:[
"/ self breakPoint:#cg
"/ ].
"/ ] ifFalse:[
"/ self breakPoint:#cg
"/ ].
"/ ].
"/ commentOnly
"/ ].
"/ listChanged := filteredList := self methodsChanged.
"/ listChanged removeAll.
"/ classChangeSet notNil ifTrue:[
"/ "/ classChangeSet methodsChanged sort:[:a :b | sortBlockForChangeLists value:a first value:b first].
"/ filteredList := classChangeSet methodsChanged reject:[:entry | isIgnoredChange value:entry first].
"/
"/ (self hideDiffsWithCommentOrFormattingChangeOnly) ifTrue:[
"/ filteredList := filteredList reject:entryIsForCommentOrFormatOnly.
"/ listChanged addAll: (filteredList collect:[:entry| printStringGenerator value:(entry first)]).
"/ ] ifFalse:[
"/ filteredList do:[:entry|
"/ |string|
"/
"/ string := printStringGenerator value:(entry first).
"/ (entryIsForCommentOrFormatOnly value:entry) ifTrue:[
"/ string := string withColor:Color grey.
"/ ].
"/ listChanged add:string
"/ ].
"/ ].
"/ ].
"/ methodsChangedFiltered := filteredList.
"/ self boxAVisible value:(listOnlyInA notEmpty).
"/ self boxBVisible value:(listOnlyInB notEmpty).
"/ self boxMVisible value:(listChanged isEmpty
"/ and: [(listOnlyInA notEmpty
"/ or:[listOnlyInB notEmpty])]) not.
self information:info
"Modified (comment): / 06-02-2017 / 10:09:11 / cg"
"Modified (format): / 16-02-2017 / 11:11:49 / stefan"
"Modified: / 07-07-2019 / 19:08:03 / Claus Gittinger"
!
updateVersionList
"asks the classes source code manager for a list of revisions;
construct versionInfoList (containing the full info), versionList (containing version numbers only)
and tagList (containing symbolic names only).
This is only used when comparing multiple versions."
|fn sourceCodeManager numShown newNumShown numOverallRevisions
partialLog newestRev revisions revisionEntries symbolicNames
stableRevision releasedRevision tagList logMessages|
fn := fileHolder value.
fn isNil ifTrue:[
symbolicVersionList contents:#().
symbolicVersionNameList contents:#().
self versionList contents:#().
self versionEntriesList contents:#().
^ self
].
sourceCodeManager := CVSSourceCodeManager.
numShown := versionList size - 1.
newNumShown := (numShown + 50) max:30.
infoHolder value:'Getting version log...'.
partialLog := sourceCodeManager revisionLogOfFile:fn numberOfRevisions:newNumShown.
partialLog isNil ifTrue:[
self warn:'Could not find/access the container for ',fn name,' in the repository.
This could be due to:
- invalid/wrong CVS-Root setting
- missing CVS access rights
(no access / not logged in)
- changed CVSRoot after compilation
(i.e. wrong CVS-path in classes version method)
'.
^ nil
].
numOverallRevisions := partialLog at:#numberOfRevisions.
newestRev := partialLog at:#newestRevision.
revisions := partialLog at:#revisions.
"/ fetch the symbolic (tag) version list
symbolicNames := partialLog at:#symbolicNames ifAbsent:[].
symbolicNames notNil ifTrue:[
stableRevision := symbolicNames at:'stable' ifAbsent:[].
releasedRevision := symbolicNames at:'released' ifAbsent:[].
tagList := ((symbolicNames associations
sort:[:a :b | sourceCodeManager versionString:(a value) isLessThan:(b value)])
collect:[:assoc | assoc key]) reverse.
"/ tagList := ((symbolicNames associations
"/ sort:[:a :b | a key < b key])
"/ collect:[:assoc | assoc key]) reverse.
tagList remove:'stable' ifAbsent:[].
stableRevision notNil ifTrue:[
tagList notEmpty ifTrue:[tagList addFirst:'-'].
tagList addFirst:'stable'.
].
].
logMessages := Dictionary new.
versionInfoList := revisions.
"/ items := versionInfoList collect:[:each | |rev date who flag|
"/ rev := each at:#revision.
"/ logMessages at:rev put:(each at:#logMessage).
"/ date := (each at:#date ifAbsent:nil) ? '?'.
"/ who := (each at:#author ifAbsent:nil) ? '?'.
"/ rev = stableRevision ifTrue:[
"/ flag := ' Stable' allBold.
"/ ] ifFalse:[rev = releasedRevision ifTrue:[
"/ flag := ' Released' allBold.
"/ ] ifFalse:[
"/ flag := ' '
"/ ]].
"/ rev allBold , flag, ' [' , date , ' by ' , who , ']'
"/ ].
"/
"/ revisions := revisions collect:[:eachItem | eachItem at:#revision].
revisions := OrderedCollection new.
revisionEntries := OrderedCollection new.
versionInfoList do:[:eachVersionInfo |
revisions add:eachVersionInfo revision.
revisionEntries add:(
(eachVersionInfo revision)
, ((' (by %2 at %3)'
bindWith:(eachVersionInfo revision)
with:(eachVersionInfo user)
with:(eachVersionInfo date)) allGray)).
].
revisions size < numOverallRevisions ifTrue:[
revisions add:'...'.
revisionEntries add:'...'.
].
symbolicToVersionMapping := symbolicNames.
symbolicVersionList contents:tagList.
symbolicVersionNameList
contents:(
tagList
collect:[:eachSymbolic |
|versionsString|
eachSymbolic = '-' ifTrue:[
eachSymbolic.
] ifFalse:[
versionsString := symbolicToVersionMapping at:eachSymbolic ifAbsent:'<<none>>'.
eachSymbolic,((' (',versionsString,')') allGray)
]
]).
self versionList contents:revisions.
self versionEntriesList contents:revisionEntries.
infoHolder value:'Done.'.
"Modified: / 29-11-2017 / 13:06:21 / cg"
"Modified: / 07-07-2019 / 23:44:42 / Claus Gittinger"
! !
!FileVersionDiffBrowser methodsFor:'initialization & release'!
initialize
super initialize.
isMultipleVersionBrowser := false.
isMultipleFilesVersionBrowser := false.
diffTextLabelA := ValueHolder new.
diffTextLabelB := ValueHolder new.
infoHolder := ValueHolder new.
selectedSymbolicVersionIndexHolder := nil asValue.
selectedSymbolicVersionIndexHolder onChangeSend:#selectedSymbolicVersionIndexHolderChanged to:self.
selectedSymbolicVersionHolder := nil asValue.
selectedSymbolicVersionHolder onChangeSend:#selectedSymbolicVersionHolderChanged to:self.
selectedVersionIndexHolder := nil asValue.
selectedVersionIndexHolder onChangeSend:#selectedVersionIndexHolderChanged to:self.
selectedVersionHolder := nil asValue.
selectedVersionHolder onChangeSend:#selectedVersionHolderChanged to:self.
symbolicVersionList := List new.
symbolicVersionNameList := List new.
versionEntriesList := List new.
versionList := List new.
"Created: / 08-05-2019 / 10:59:30 / Claus Gittinger"
"Modified: / 08-07-2019 / 00:06:27 / Claus Gittinger"
!
postOpenWith:aBuilder
super postOpenWith:aBuilder.
self isMultipleVersionBrowser ifTrue:[
self withWaitCursorDo:[
self updateVersionList.
]
]
! !
!FileVersionDiffBrowser methodsFor:'menu action'!
mainMenu
"if this application runs as an subapplication,
the menu bar should not be used."
self masterApplication isNil ifTrue:[
^ self class mainMenu
].
^ nil
"Modified: / 25-07-2006 / 11:13:44 / cg"
!
menuAHolder
^ [ self class menuA ]
"Created: / 05-02-2017 / 10:07:15 / cg"
!
menuBHolder
^ [ self class menuB ]
"Created: / 05-02-2017 / 10:07:22 / cg"
!
menuMHolder
^ [ self class menuM ]
"Created: / 05-02-2017 / 10:07:36 / cg"
!
openDocumentation
HTMLDocumentView openFullOnDocumentationFile:'tools/misc/TOP.html#VERSIONDIFF'
!
versionMenuCompareAgainstNextVersion
|fn selectedVersion nextVersion|
selectedVersion := self selectedVersionHolder value.
nextVersion := self versionList at:(self selectedVersionIndex - 1).
fn := fileHolder value.
self class
openOnFile:fn versionA:selectedVersion versionB:nextVersion
"Modified: / 08-07-2019 / 00:09:54 / Claus Gittinger"
!
versionMenuCompareAgainstPreviousVersion
|fn selectedVersion prevVersion|
selectedVersion := self selectedVersionHolder value.
selectedVersion isNil ifTrue:[
self selectedVersionIndexHolder value:1
].
prevVersion := self versionList at:(self selectedVersionIndex + 1).
fn := fileHolder value.
self class
openOnFile:fn versionA:prevVersion versionB:selectedVersion
"Modified: / 08-07-2019 / 00:10:12 / Claus Gittinger"
! !
!FileVersionDiffBrowser methodsFor:'private'!
acceptInRightView
|text|
text := self diffTextView text2.
self halt.
"Created: / 08-07-2019 / 02:32:30 / Claus Gittinger"
!
addAcceptToTextViewMenus
"add to the standard diff text view an accept entry.
The acceptAction will store the selected version into the file"
|rightView|
self isMultipleVersionBrowser ifFalse:[^ self].
diffTextView := self diffTextView.
rightView := diffTextView rightTextView.
rightView acceptAction:[:theCode |
|version code|
version := self selectedVersionHolder value.
code := self getFile:(self fileHolder value) version:version.
self fileHolder value contents:code.
].
rightView menuHolder:[
|m|
m := rightView editMenu.
m enable:#accept.
m
].
rightView menuMessage:#value.
"Modified: / 08-07-2019 / 02:45:49 / Claus Gittinger"
!
getFile:fileName version:version
|errStream errorMessages inStream contents|
errStream := '' writeStream.
[
inStream := PipeStream
readingFrom:('cvs update -p -r %1 %2'
bindWith:(version ? '')
with:fileName baseName)
errorDisposition:errStream
inDirectory:fileName directory pathName.
contents := inStream upToEnd.
] ensure:[
inStream notNil ifTrue:[
inStream close
]
].
contents isEmptyOrNil ifTrue:[
errorMessages := errStream contents.
errorMessages notEmptyOrNil ifTrue:[
self halt.
].
].
^ contents
"Created: / 07-07-2019 / 22:09:21 / Claus Gittinger"
"Modified: / 08-07-2019 / 01:24:35 / Claus Gittinger"
!
informationUntranslated:msg
self infoHolder value:msg
"Created: / 09-08-2018 / 15:40:52 / Claus Gittinger"
!
resetSelectionHolders
"
reset all selection holders when a new change set is given.
First set the selection to nil.
<return: self>
"
self diffTextView text1:'' text2:''.
"Modified (comment): / 08-07-2019 / 00:06:09 / Claus Gittinger"
!
showSingleTextView
"
if a method is selected which is only in version A or B of the class,
then show the text view.
Add an accept entry to the popup menu.
<return: self>
"
(self componentAt:#diffTextViewBox) beInvisible.
"/ self addAcceptToTextViewMenus.
"Modified: / 08-07-2019 / 00:03:10 / Claus Gittinger"
! !
!FileVersionDiffBrowser methodsFor:'setup'!
setupForAllVersionsOfFile:aFilename
self fileHolder value:aFilename.
self updateVersionList.
"Created: / 07-07-2019 / 22:42:40 / Claus Gittinger"
"Modified: / 07-07-2019 / 23:46:28 / Claus Gittinger"
!
setupForFile:aFilename againstVersion:aVersionA
"compute the diffs for the file's current version against the repository version A.
When setting the diffs, the labels, list etc. of the receiver
are updated."
|text1 text2|
text1 := aFilename contentsAsString.
text2 := self getFile:aFilename version:aVersionA.
self diffTextView text1:text1 text2:text2.
self diffTextLabelA value:('File: %1' bindWith:aFilename baseName).
self diffTextLabelB value:aVersionA.
self addAcceptToTextViewMenus.
"Created: / 07-07-2019 / 19:57:27 / Claus Gittinger"
"Modified: / 08-07-2019 / 02:29:10 / Claus Gittinger"
!
setupForFile:fileA labelA:labelA andFile:fileB labelB:labelB
"generate the diffs from the two files A and B.
When setting the diffs, the labels, list etc. of the receiver
are updated."
self diffTextView
text1:(fileA contentsAsString)
text2:(fileB contentsAsString).
self diffTextLabelA value:labelA.
self diffTextLabelB value:labelB.
"Created: / 07-07-2019 / 19:59:03 / Claus Gittinger"
"Modified: / 08-07-2019 / 01:14:36 / Claus Gittinger"
! !
!FileVersionDiffBrowser class methodsFor:'documentation'!
version_CVS
^ '$Header$'
! !