#FEATURE by exept
class: DirectoryDifferenceViewApplication
filters
class definition
added:
#excludedDirectoryNamePatternHolder
#generateResultStringForTimeElapsed:
#ignoreCaseInDirectoryNameHolder
#ignoreCaseInExcludedDirectoryNameHolder
#ignoreCaseInExcludedNameHolder
#ignoreCaseInNameHolder
changed: #doSearch
class: DirectoryDifferenceViewApplication class
added:
#documentation
#examples
changed:
#helpSpec
#windowSpec
"{ Encoding: utf8 }"
"
COPYRIGHT (c) 2006 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:libtool' }"
"{ NameSpace: Smalltalk }"
AbstractFileFinderApplicationComponent subclass:#DirectoryDifferenceViewApplication
instanceVariableNames:'directory1Holder directory2Holder directory1 directory2
filesOnlyInDirectory1 filesOnlyInDirectory2
filesWhichAreDifferent directoriesOnlyInDirectory1
directoriesOnlyInDirectory2 namePatternHolder
excludedNamePatternHolder excludedDirectoryNamePatternHolder
ignoreCaseInNameHolder ignoreCaseInExcludedNameHolder
ignoreCaseInExcludedDirectoryNameHolder
ignoreCaseInDirectoryNameHolder filesSkippedCount
directoriesSkippedCount'
classVariableNames:''
poolDictionaries:''
category:'Interface-Tools-File'
!
!DirectoryDifferenceViewApplication class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 2006 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
"
documentation to be added.
class:
<a short class summary here, describing what instances represent>
responsibilities:
<describing what my main role is>
collaborators:
<describing with whom and how I talk to>
API:
<public api and main messages>
example:
<a one-line examples on how to use - can also be in a separate example method>
implementation:
<implementation points>
[author:]
exept MBP
[instance variables:]
[class variables:]
[see also:]
"
!
examples
"
Notice that everything between [exBegin] and [exEnd] is extracted by the html-doc generator
to create nicely formatted and clickable executable examples in the generated html-doc.
(see the browser's class-documentation menu items for more)
opening the application:
[exBegin]
DirectoryDifferenceViewApplication open
[exEnd]
opening the application on some model:
[exBegin]
DirectoryDifferenceViewApplication openOn:aModel
[exEnd]
"
! !
!DirectoryDifferenceViewApplication class methodsFor:'help specs'!
helpSpec
"This resource specification was automatically generated
by the UIHelpTool of ST/X."
"Do not manually edit this!! If it is corrupted,
the UIHelpTool may not be able to read the specification."
"
UIHelpTool openOnClass:DirectoryDifferenceViewApplication
"
<resource: #help>
^ super helpSpec addPairsFrom:#(
#excludedDirectoryNamePattern
'Directory name(s) to skip.\Can be matchPatterns, separated by ";"'
#excludedNamePattern
'File name(s) to skip.\Can be matchPatterns, separated by ";"'
#ignoreCaseInExcludedDirectoryName
'Ignore case in directory name exclude pattern(s)'
#ignoreCaseInExcludedName
'Ignore case in file name exclude pattern(s)'
#ignoreCaseInName
'Ignore case in file name pattern(s)'
#namePattern
'Filename(s) to search for.\Can be matchPatterns, separated by ";".\(eg. "*.c ; *.h" searches for C and header files. So does "*.[ch]")'
#searchDirectory1
'The first folder, to be compared against folder2'
#searchDirectory2
'The second folder, to be compared against folder1'
)
! !
!DirectoryDifferenceViewApplication 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:DirectoryDifferenceViewApplication andSelector:#windowSpec
DirectoryDifferenceViewApplication new openInterface:#windowSpec
DirectoryDifferenceViewApplication open
"
<resource: #canvas>
^
#(FullSpec
name: windowSpec
uuid: '523f01a8-baab-11e9-a284-10ddb1cc5928'
window:
(WindowSpec
label: 'Directory Diff'
name: 'Directory Diff'
uuid: '09a5b9c0-baa9-11e9-a284-10ddb1cc5928'
min: (Point 377 131)
bounds: (Rectangle 0 0 758 512)
)
component:
(SpecCollection
collection: (
(MenuPanelSpec
name: 'ToolBar1'
layout: (LayoutFrame 0 0.0 0 0 0 1.0 32 0)
uuid: '09a5bd8a-baa9-11e9-a284-10ddb1cc5928'
level: 0
menu: searchMenu
textDefault: true
)
(ProgressIndicatorSpec
name: 'ProgressIndicator1'
layout: (LayoutFrame 125 0 11 0 231 0 21 0)
uuid: '09a5c06e-baa9-11e9-a284-10ddb1cc5928'
visibilityChannel: enableStop
backgroundColor: (Color 0.0 67.0 67.0)
showPercentage: false
isActivityIndicator: true
)
(ViewSpec
name: 'Box1'
layout: (LayoutFrame 0 0.0 32 0 0 1.0 154 0)
uuid: '09a5c2d0-baa9-11e9-a284-10ddb1cc5928'
component:
(SpecCollection
collection: (
(LabelSpec
label: 'Directory1:'
name: 'DirectoryLabel'
layout: (LayoutFrame 2 0 7 0 154 0 24 0)
activeHelpKey: searchDirectory1
uuid: '09a5c42e-baa9-11e9-a284-10ddb1cc5928'
translateLabel: true
adjust: right
)
(FilenameInputFieldSpec
name: 'DirectoryEntryField'
layout: (LayoutFrame 156 0 4 0 0 1 24 0)
activeHelpKey: searchDirectory1
uuid: '09a5c67c-baa9-11e9-a284-10ddb1cc5928'
model: directory1Holder
immediateAccept: true
acceptOnPointerLeave: false
)
(LabelSpec
label: 'Directory2:'
name: 'Label2'
layout: (LayoutFrame 2 0 31 0 154 0 48 0)
activeHelpKey: searchDirectory2
uuid: '09a5ca00-baa9-11e9-a284-10ddb1cc5928'
translateLabel: true
adjust: right
)
(FilenameInputFieldSpec
name: 'FilenameEntryField1'
layout: (LayoutFrame 156 0 28 0 0 1 48 0)
activeHelpKey: searchDirectory2
uuid: '09a5cb40-baa9-11e9-a284-10ddb1cc5928'
model: directory2Holder
immediateAccept: true
acceptOnPointerLeave: false
)
(LabelSpec
label: 'Compare Files Named:'
name: 'FileNameLabel'
layout: (LayoutFrame 2 0 55 0 154 0 72 0)
activeHelpKey: namePattern
uuid: '09a5ccda-baa9-11e9-a284-10ddb1cc5928'
translateLabel: true
adjust: right
)
(InputFieldSpec
name: 'FileNameEntryField'
layout: (LayoutFrame 156 0 52 0 -180 1 72 0)
activeHelpKey: namePattern
uuid: '09a5cdf2-baa9-11e9-a284-10ddb1cc5928'
tabable: true
model: namePatternHolder
immediateAccept: true
acceptOnLeave: false
acceptOnPointerLeave: false
)
(CheckBoxSpec
label: 'Ignore Case'
name: 'IgnoreCaseInNameCheckBox'
layout: (LayoutFrame -169 1 53 0 -4 1 76 0)
activeHelpKey: ignoreCaseInName
uuid: '09a5cfb4-baa9-11e9-a284-10ddb1cc5928'
tabable: true
model: ignoreCaseInNameHolder
translateLabel: true
)
(LabelSpec
label: 'But Not Named:'
name: 'Label1'
layout: (LayoutFrame 2 0 79 0 190 0 96 0)
activeHelpKey: excludedNamePattern
uuid: '09a5d16c-baa9-11e9-a284-10ddb1cc5928'
translateLabel: true
adjust: right
)
(InputFieldSpec
name: 'EntryField1'
layout: (LayoutFrame 190 0 76 0 -180 1 96 0)
activeHelpKey: excludedNamePattern
uuid: '09a5d284-baa9-11e9-a284-10ddb1cc5928'
tabable: true
model: excludedNamePatternHolder
immediateAccept: true
acceptOnLeave: false
acceptOnPointerLeave: false
)
(CheckBoxSpec
label: 'Ignore Case'
name: 'CheckBox1'
layout: (LayoutFrame -169 1 77 0 -4 1 100 0)
activeHelpKey: ignoreCaseInExcludedName
uuid: '09a5d414-baa9-11e9-a284-10ddb1cc5928'
tabable: true
model: ignoreCaseInExcludedNameHolder
translateLabel: true
)
(LabelSpec
label: 'Ignore Folders Named:'
name: 'Label3'
layout: (LayoutFrame 2 0 103 0 190 0 120 0)
activeHelpKey: excludedDirectoryNamePattern
uuid: '09a5d518-baa9-11e9-a284-10ddb1cc5928'
translateLabel: true
adjust: right
)
(InputFieldSpec
name: 'EntryField2'
layout: (LayoutFrame 190 0 100 0 -180 1 120 0)
activeHelpKey: excludedDirectoryNamePattern
uuid: '09a5d63a-baa9-11e9-a284-10ddb1cc5928'
tabable: true
model: excludedDirectoryNamePatternHolder
immediateAccept: true
acceptOnLeave: false
acceptOnPointerLeave: false
)
(CheckBoxSpec
label: 'Ignore Case'
name: 'CheckBox2'
layout: (LayoutFrame -169 1 101 0 -4 1 124 0)
activeHelpKey: ignoreCaseInExcludedDirectoryName
uuid: '09a5d7d4-baa9-11e9-a284-10ddb1cc5928'
tabable: true
model: ignoreCaseInExcludedDirectoryNameHolder
translateLabel: true
)
)
)
)
(VariableVerticalPanelSpec
name: 'VariableVerticalPanel1'
layout: (LayoutFrame 0 0.0 164 0 0 1.0 0 1)
uuid: '09a5d914-baa9-11e9-a284-10ddb1cc5928'
component:
(SpecCollection
collection: (
(DataSetSpec
name: 'Table1'
uuid: '09a5daa4-baa9-11e9-a284-10ddb1cc5928'
model: selectionHolder
hasHorizontalScrollBar: true
hasVerticalScrollBar: true
dataList: matchedFilesList
doubleClickSelector: fileDoubleClick:
columnHolder: searchResultTable
valueChangeSelector: fileSelected:
multipleSelectOk: true
)
(ArbitraryComponentSpec
name: 'DiffTextView'
uuid: '09a5deaa-baa9-11e9-a284-10ddb1cc5928'
hasHorizontalScrollBar: true
hasVerticalScrollBar: true
component: DiffTextView
)
)
)
handles: (Any 0.5 1.0)
)
)
)
)
! !
!DirectoryDifferenceViewApplication class methodsFor:'menu specs'!
searchMenu
"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:FindFileApplication andSelector:#searchMenu
(Menu new fromLiteralArrayEncoding:(FindFileApplication searchMenu)) startUp
"
<resource: #menu>
^
#(Menu
(
(MenuItem
label: 'Search'
itemValue: doSearch
translateLabel: true
isButton: true
labelImage: (ResourceRetriever ToolbarIconLibrary searchFileIcon)
)
(MenuItem
enabled: enableStop
label: 'Stop'
itemValue: stop
translateLabel: true
isButton: true
isVisible: enableStop
labelImage: (ResourceRetriever XPToolbarIconLibrary stop22x22Icon)
)
(MenuItem
label: 'Close'
itemValue: doClose
translateLabel: true
isButton: true
startGroup: right
isVisible: false
labelImage: (ResourceRetriever ToolbarIconLibrary removeTabIcon)
)
)
nil
nil
)
! !
!DirectoryDifferenceViewApplication class methodsFor:'tableColumns specs'!
searchResultTable
"This resource specification was automatically generated
by the DataSetBuilder of ST/X."
"Do not manually edit this!! If it is corrupted,
the DataSetBuilder may not be able to read the specification."
"
DataSetBuilder new openOnClass:DirectoryDifferenceViewApplication andSelector:#searchResultTable
"
<resource: #tableColumns>
^#(
(DataSetColumnSpec
label: 'Filename'
id: 'FileName'
labelButtonType: Button
model: at:
menuFromApplication: false
writeSelector: at:put:
showRowSeparator: false
showColSeparator: false
)
(DataSetColumnSpec
label: 'Diff'
id: 'Diff'
labelButtonType: Button
model: at:
menuFromApplication: false
writeSelector: at:put:
showRowSeparator: false
showColSeparator: false
)
)
! !
!DirectoryDifferenceViewApplication methodsFor:'accessing'!
directory1:directory1Arg directory2:directory2Arg
self directory1Holder value:directory1Arg.
self directory2Holder value:directory2Arg.
"/ self namePatternHolder value:newPattern.
self enableStop value:false.
self enableSearch value:true.
^ true.
"Modified: / 12-01-2012 / 01:36:54 / cg"
!
directory1Holder
directory1Holder isNil ifTrue:[
directory1Holder := nil asValue
].
^ directory1Holder
"Created: / 12-01-2012 / 01:37:31 / cg"
!
directory2Holder
directory2Holder isNil ifTrue:[
directory2Holder := nil asValue
].
^ directory2Holder
"Created: / 12-01-2012 / 01:37:41 / cg"
! !
!DirectoryDifferenceViewApplication methodsFor:'actions'!
fileSelected:entries
|entry file fn1 fn2 text1 text2 differ|
entries isEmptyOrNil ifTrue:[^ self].
entry := self shownList at:entries first.
file := entry first.
fn1 := self directory1Holder value asFilename construct:file.
fn2 := self directory2Holder value asFilename construct:file.
(fn1 exists and:[fn1 isRegularFile]) ifTrue:[
text1 := fn1 contentsAsString.
].
(fn2 exists and:[fn2 isRegularFile]) ifTrue:[
text2 := fn2 contentsAsString.
].
differ := builder componentAt:'DiffTextView'.
differ text1:(text1 ? '') text2:(text2 ? '').
"Created: / 12-01-2012 / 03:21:52 / cg"
! !
!DirectoryDifferenceViewApplication methodsFor:'aspects'!
excludedDirectoryNamePatternHolder
excludedDirectoryNamePatternHolder isNil ifTrue:[
excludedDirectoryNamePatternHolder := '' asValue.
].
^ excludedDirectoryNamePatternHolder.
"Created: / 13-01-2012 / 14:42:47 / cg"
!
excludedNamePatternHolder
excludedNamePatternHolder isNil ifTrue:[
excludedNamePatternHolder := '' asValue.
].
^ excludedNamePatternHolder.
"Created: / 13-01-2012 / 14:42:47 / cg"
!
ignoreCaseInDirectoryNameHolder
ignoreCaseInDirectoryNameHolder isNil ifTrue:[
ignoreCaseInDirectoryNameHolder := true asValue.
].
^ ignoreCaseInDirectoryNameHolder.
"Created: / 13-01-2012 / 14:37:28 / cg"
!
ignoreCaseInExcludedDirectoryNameHolder
ignoreCaseInExcludedDirectoryNameHolder isNil ifTrue:[
ignoreCaseInExcludedDirectoryNameHolder := true asValue.
].
^ ignoreCaseInExcludedDirectoryNameHolder.
"Created: / 13-01-2012 / 14:37:28 / cg"
!
ignoreCaseInExcludedNameHolder
ignoreCaseInExcludedNameHolder isNil ifTrue:[
ignoreCaseInExcludedNameHolder := true asValue.
].
^ ignoreCaseInExcludedNameHolder.
"Created: / 13-01-2012 / 14:37:28 / cg"
!
ignoreCaseInNameHolder
ignoreCaseInNameHolder isNil ifTrue:[
ignoreCaseInNameHolder := true asValue.
].
^ ignoreCaseInNameHolder.
"Created: / 13-01-2012 / 14:37:28 / cg"
!
namePatternHolder
namePatternHolder isNil ifTrue:[
namePatternHolder := '*' asValue.
].
^ namePatternHolder.
"Created: / 13-01-2012 / 14:37:28 / cg"
! !
!DirectoryDifferenceViewApplication methodsFor:'comparing'!
doSearch
|dir1 dir2
namePattern excludedNamePattern excludedDirectoryNamePattern
ignoreCaseInName ignoreCaseInExcludeName ignoreCaseInExcludeDirectoryName
fileExcludeFilterOrNil directoryExcludeFilterOrNil checkDir|
filesOnlyInDirectory1 := OrderedCollection new.
filesOnlyInDirectory2 := OrderedCollection new.
directoriesOnlyInDirectory1 := OrderedCollection new.
directoriesOnlyInDirectory2 := OrderedCollection new.
filesWhichAreDifferent := OrderedCollection new.
filesSkippedCount := directoriesSkippedCount := 0.
dir1 := self directory1Holder value.
dir1 isNil ifTrue:[^ self].
dir2 := self directory2Holder value.
dir2 isNil ifTrue:[^ self].
dir1 := dir1 asFilename.
dir2 := dir2 asFilename.
dir1 pathName = dir2 pathName ifTrue:[
self notify:('Same folder.' allBold).
^ self.
].
namePattern := self namePatternHolder value.
namePattern notEmptyOrNil ifTrue:[
namePattern := namePattern withoutSeparators.
(namePattern isEmptyOrNil or:[namePattern = '*']) ifTrue:[
namePattern := nil
]
].
ignoreCaseInName := self ignoreCaseInNameHolder value.
ignoreCaseInExcludeName := self ignoreCaseInExcludedNameHolder value.
ignoreCaseInExcludeDirectoryName := self ignoreCaseInExcludedDirectoryNameHolder value.
excludedNamePattern := self excludedNamePatternHolder value.
excludedNamePattern notEmptyOrNil ifTrue:[
excludedNamePattern := excludedNamePattern withoutSeparators.
excludedNamePattern notEmptyOrNil ifTrue:[
fileExcludeFilterOrNil :=
ignoreCaseInExcludeName
ifTrue:[ [:baseName | (excludedNamePattern compoundMatch:baseName caseSensitive:false) not ] ]
ifFalse:[ [:baseName | (excludedNamePattern compoundMatch:baseName caseSensitive:true) not ] ].
].
].
excludedDirectoryNamePattern := self excludedDirectoryNamePatternHolder value.
excludedDirectoryNamePattern notEmptyOrNil ifTrue:[
excludedDirectoryNamePattern := excludedDirectoryNamePattern withoutSeparators.
excludedDirectoryNamePattern notEmptyOrNil ifTrue:[
checkDir :=
ignoreCaseInExcludeDirectoryName
ifTrue:[ [:dir | (excludedDirectoryNamePattern compoundMatch:(dir baseName) caseSensitive:false) not ] ]
ifFalse:[ [:dir | (excludedDirectoryNamePattern compoundMatch:(dir baseName) caseSensitive:true) not ] ].
directoryExcludeFilterOrNil :=
[:fn |
(checkDir value:fn) ifFalse:[
directoriesSkippedCount := directoriesSkippedCount + 1.
false.
] ifTrue:[
true
]
].
].
].
self matchedFilesList removeAll.
self windowGroup repairDamage.
self
startSearchTask:[
self changeInformationTo:'Directory Diff - searching ' toTab:true.
self shownListHolder valueHolder:(self matchedFilesList).
dir1
recursiveDirectoryContentsDo:[:relFn1 |
|fn1 fn2 fn1BaseName|
fn1 := dir1 construct:relFn1.
fn1BaseName := fn1 baseName.
(namePattern isNil or:[namePattern compoundMatch:fn1BaseName caseSensitive:ignoreCaseInName not]) ifTrue:[
(fileExcludeFilterOrNil isNil or:[fileExcludeFilterOrNil value:fn1BaseName]) ifTrue:[
fn2 := dir2 construct:relFn1.
fn1 isDirectory ifTrue:[
self notify:('Comparing %1...' bindWith:relFn1 asString allBold).
fn2 exists ifFalse:[
directoriesOnlyInDirectory1 add:fn1.
self matchedFilesList add:{ relFn1 . 'Directory only in directory1' }.
].
] ifFalse:[
fn2 exists ifTrue:[
filesSearchedCount := filesSearchedCount + 1.
(fn1 sameContentsAs:fn2) ifFalse:[
filesWhichAreDifferent add:fn1.
self matchedFilesList add:{ relFn1 . 'Different' }.
].
] ifFalse:[
filesOnlyInDirectory1 add:fn1.
self matchedFilesList add:{ relFn1 . 'File only in directory1' }.
].
].
] ifFalse:[
filesSkippedCount := filesSkippedCount + 1.
]
]
]
filterForVisitingDirectories:directoryExcludeFilterOrNil.
dir2
recursiveDirectoryContentsDo:[:relFn2 |
|fn1 fn2 fn2BaseName|
fn2 := dir2 construct:relFn2.
fn2BaseName := fn2 baseName.
(namePattern isNil or:[namePattern compoundMatch:fn2BaseName caseSensitive:ignoreCaseInName not]) ifTrue:[
(fileExcludeFilterOrNil isNil or:[fileExcludeFilterOrNil value:fn2BaseName]) ifFalse:[
fn1 := dir1 construct:relFn2.
fn1 exists ifFalse:[
fn1 isDirectory ifTrue:[
directoriesOnlyInDirectory1 add:fn1.
self matchedFilesList add:{ relFn2 . 'Directory only in directory2' }.
] ifFalse:[
filesOnlyInDirectory2 add:fn2.
self matchedFilesList add:{ relFn2 . 'File only in directory2' }.
]
].
].
] ifFalse:[
filesSkippedCount := filesSkippedCount + 1.
]
]
filterForVisitingDirectories:directoryExcludeFilterOrNil.
Transcript showCR:'--- search summary ------'.
directoriesSkippedCount ~~ 0 ifTrue:[
Transcript showCR:'%1 directories skipped' with:directoriesSkippedCount.
].
filesSkippedCount ~~ 0 ifTrue:[
Transcript showCR:'%1 files skipped' with:filesSkippedCount.
].
filesOnlyInDirectory1 notEmpty ifTrue:[
Transcript showCR:'%1 files only in directory1' with:filesOnlyInDirectory1 size.
].
filesOnlyInDirectory2 notEmpty ifTrue:[
Transcript showCR:'%1 files only in directory2' with:filesOnlyInDirectory2 size.
].
directoriesOnlyInDirectory1 notEmpty ifTrue:[
Transcript showCR:'%1 directories only in directory1' with:directoriesOnlyInDirectory1 size.
].
directoriesOnlyInDirectory2 notEmpty ifTrue:[
Transcript showCR:'%1 directories only in directory2' with:directoriesOnlyInDirectory2 size.
].
filesWhichAreDifferent notEmpty ifTrue:[
Transcript showCR:'%1 files are different' with:filesWhichAreDifferent size.
]
]
name:'Directory Diff'.
"Created: / 12-01-2012 / 01:07:20 / cg"
"Modified: / 15-02-2019 / 09:42:51 / Claus Gittinger"
!
generateResultStringForTimeElapsed:timeDuration
"at the end of a search, generate a nice informative summary string.
Redefined to generate a different message."
|timeMillis timeString nIn1 nIn2 nDifferent|
timeMillis := timeDuration asMilliseconds.
timeString := timeDuration printStringForApproximation.
nIn1 := filesOnlyInDirectory1 size.
nIn2 := filesOnlyInDirectory1 size.
nDifferent := filesWhichAreDifferent size.
^ resources
string:('different:%1, only in one:%2 / %3 (%4 files visited; %6 files/s).')
with:nDifferent
with:nIn1
with:nIn2
with:filesSearchedCount
with:(UnitConverter fileSizeSIStringFor:(bytesSearchedCount * 1000 / (timeMillis max:1)))
with:((filesSearchedCount * 1000 / (timeMillis max:1)) asFixedPoint:1).
! !
!DirectoryDifferenceViewApplication methodsFor:'startup & release'!
postOpenWith:aBuilder
super postOpenWith:aBuilder.
self doSearch
"Created: / 12-01-2012 / 01:41:18 / cg"
! !
!DirectoryDifferenceViewApplication class methodsFor:'documentation'!
version
^ '$Header$'
!
version_CVS
^ '$Header$'
! !