VDBSourceApplication.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Wed, 13 Mar 2019 13:54:14 +0000
changeset 148 7d2d523173af
parent 133 16a1f7a5eed0
child 154 26937faa5a97
permissions -rw-r--r--
Workaround: assume native target when issuing `run` or `attach` commands using simple console Background command execution is not supported by some targets, most notably by Windows native target. However, at the point we have to decided whether use background execution or not, we don't know which target will get connected and therefore we cannot check target features. So, make a guess and assime we gonna use native target. This is so bad, this *absolutely* has to be fixed somehow.

"
jv:vdb - Visual / VM Debugger
Copyright (C) 2015-now Jan Vrany

This software is licensed under 'Creative Commons Attribution-NonCommercial 4.0 International License'

You may find a full license text in LICENSE.txt or at http://creativecommons.org/licenses/by-nc/4.0/
"
"{ Package: 'jv:vdb' }"

"{ NameSpace: Smalltalk }"

VDBAbstractApplication subclass:#VDBSourceApplication
	instanceVariableNames:'frameHolder sourceFileHolder sourceStringHolder sourceView'
	classVariableNames:''
	poolDictionaries:''
	category:'VDB-UI-Source'
!

!VDBSourceApplication class methodsFor:'documentation'!

copyright
"
jv:vdb - Visual / VM Debugger
Copyright (C) 2015-now Jan Vrany

This software is licensed under 'Creative Commons Attribution-NonCommercial 4.0 International License'

You may find a full license text in LICENSE.txt or at http://creativecommons.org/licenses/by-nc/4.0/
"
! !

!VDBSourceApplication 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:VDBSourceApplication andSelector:#windowSpec
     VDBSourceApplication new openInterface:#windowSpec
     VDBSourceApplication open
    "

    <resource: #canvas>

    ^ 
    #(FullSpec
       name: windowSpec
       window: 
      (WindowSpec
         label: 'Source View'
         name: 'Source View'
         min: (Point 10 10)
         bounds: (Rectangle 0 0 300 300)
       )
       component: 
      (SpecCollection
         collection: (
          (NonScrollableArbitraryComponentSpec
             name: 'SourceView'
             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
             model: sourceStringHolder
             component: sourceView
           )
          )
        
       )
     )
! !

!VDBSourceApplication class methodsFor:'plugIn spec'!

aspectSelectors
    "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."

    "Return a description of exported aspects;
     these can be connected to aspects of an embedding application
     (if this app is embedded in a subCanvas)."

    ^ #(
        #debuggerHolder
        #frameHolder
      ).

! !

!VDBSourceApplication methodsFor:'aspects'!

frameHolder
    "return/create the 'frameHolder' value holder (automatically generated)"

    frameHolder isNil ifTrue:[
        frameHolder := ValueHolder new.
        frameHolder addDependent:self.
    ].
    ^ frameHolder
!

frameHolder:something
    "set the 'frameHolder' value holder (automatically generated)"

    |oldValue newValue|

    frameHolder notNil ifTrue:[
        oldValue := frameHolder value.
        frameHolder removeDependent:self.
    ].
    frameHolder := something.
    frameHolder notNil ifTrue:[
        frameHolder addDependent:self.
    ].
    newValue := frameHolder value.
    oldValue ~~ newValue ifTrue:[
        self update:#value with:newValue from:frameHolder.
    ].
!

sourceFileHolder
    "return/create the 'sourceFileHolder' value holder (automatically generated)"

    sourceFileHolder isNil ifTrue:[
        sourceFileHolder := ValueHolder new.
        sourceFileHolder addDependent:self.
    ].
    ^ sourceFileHolder
!

sourceFileHolder:something
    "set the 'sourceFileHolder' value holder (automatically generated)"

    |oldValue newValue|

    sourceFileHolder notNil ifTrue:[
        oldValue := sourceFileHolder value.
        sourceFileHolder removeDependent:self.
    ].
    sourceFileHolder := something.
    sourceFileHolder notNil ifTrue:[
        sourceFileHolder addDependent:self.
    ].
    newValue := sourceFileHolder value.
    oldValue ~~ newValue ifTrue:[
        self update:#value with:newValue from:sourceFileHolder.
    ].
!

sourceStringHolder
    "return/create the 'sourceStringHolder' value holder (automatically generated)"

    sourceStringHolder isNil ifTrue:[
        sourceStringHolder := ValueHolder new.
        sourceStringHolder addDependent:self.
    ].
    ^ sourceStringHolder
!

sourceStringHolder:something
    "set the 'sourceStringHolder' value holder (automatically generated)"

    |oldValue newValue|

    sourceStringHolder notNil ifTrue:[
        oldValue := sourceStringHolder value.
        sourceStringHolder removeDependent:self.
    ].
    sourceStringHolder := something.
    sourceStringHolder notNil ifTrue:[
        sourceStringHolder addDependent:self.
    ].
    newValue := sourceStringHolder value.
    oldValue ~~ newValue ifTrue:[
        self update:#value with:newValue from:sourceStringHolder.
    ].
!

sourceView
    sourceView isNil ifTrue:[ 
        sourceView := Tools::CodeView2 new.
        sourceView font: self textFont.
        sourceView compilerClass: (VDBEvaluator new setDebugger: debugger).    
        sourceView readOnly: true.
        sourceView services: #()        
    ].
    ^ sourceView

    "Created: / 21-09-2014 / 01:42:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 20-08-2018 / 11:03:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBSourceApplication methodsFor:'change & update'!

update:aspect with:param from:sender 
    "Invoked when an object that I depend upon sends a change notification."
    
    sender == frameHolder ifTrue:[
        self updateSourceFile.
        ^ self.
    ].
    sender == sourceFileHolder ifTrue:[
        self updateSourceString.
        ^ self.
    ].
    super update:aspect with:param from:sender

    "Modified: / 02-10-2018 / 10:50:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

updateCurrentLine
    | frame file |

    frame := frameHolder value.
    file := sourceFileHolder value.
    (frame notNil and:[file notNil]) ifTrue:[
        | line |
        line := frame line.
        line notNil ifTrue:[
            sourceView selectLine:line.
            sourceView makeSelectionVisible.
            ^ self.
        ]
    ].
    sourceView unselect

    "Created: / 02-10-2018 / 11:03:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

updateSourceFile
    | frame |

    frame := frameHolder value.
    frame notNil ifTrue:[
        | file |

        file := frame file.
        file notNil ifTrue:[ file := file asFilename ].
        file notNil ifTrue:[ 
            self sourceFileHolder value: file.
        ] ifFalse:[
            "/ If file is nil, this means that it is either unknown (no 
            "/ debug info) or it cannot be resolved. If the latter, a 
            "/ help text is shown, see #updateSourceString.
            "/ 
            "/ Therefore, here we force an update to make sure that
            "/ help text is regenerated.
            self sourceFileHolder 
                setValue: file;
                changed: #value
        ]
    ].

    "Created: / 01-02-2018 / 15:16:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 16-01-2019 / 23:55:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

updateSourceString
    | source file |

    source := nil.
    file := sourceFileHolder value.
    (file notNil and:[file exists]) ifTrue:[
        source := file contents asString.
    ] ifFalse:[ 
        "/ We have no source. As a courtesy to the user, display some info
        "/ on what's the problem and
        | frame |

        frame := self frameHolder value.
        source := Text streamContents:[ :info |
            | frameFile frameFullname |
            info emphasis: #color -> (UserPreferences current codeViewTheme ? UserPreferences current) commentColor.
            info nextPutAll: '//' ; cr.
            info nextPutAll: '// '; nextPutAll: (resources string: 'No source available :-('); cr.
            info nextPutAll: '//' ; cr.
            frameFile := frame propertyAt: #file.
            frameFullname := frame propertyAt: #fullname.
            (frameFile isNil and:[ frameFullname notNil ]) ifTrue:[ 
                info nextPutAll: '// '; nextPutLine: (resources string: 'Source file reference missing (no debug info?)').
            ] ifFalse:[ 
                info nextPutAll: '// '; nextPutLine: (resources string: 'Source file cannot be resolved:').
                info nextPutAll: '// '; cr.
                frameFile notNil ifTrue:[
                    info nextPutAll: '//   '; nextPutLine: frameFile.
                ].
                frameFullname notNil ifTrue:[
                    info nextPutAll: '//   '; nextPutLine: frameFullname.
                ].
                info nextPutAll: '// '; cr.
                info nextPutAll: '// '; nextPutLine: (resources string: 'Configured source directories:').
                debugger directories do:[:each | 
                    info nextPutAll: '//   '; nextPutLine: each.
                ].
                info nextPutAll: '// '; cr.
                info nextPutAll: '// '; nextPutLine: (resources string: 'See also:').
                info nextPutAll: '// [1]: https://sourceware.org/gdb/onlinedocs/gdb/Source-Path.html'.
            ].

        ]

    ].
    self sourceStringHolder value:source.
    self updateCurrentLine.
    ^ self.

    "Modified: / 07-10-2018 / 20:47:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBSourceApplication methodsFor:'change & update-delayed'!

delayedUpdateCurrentLine
    self updateCurrentLine

    "Created: / 02-10-2018 / 11:04:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBSourceApplication methodsFor:'event handling'!

onStoppedEvent: aGDBStoppedEvent
    self enqueueDelayedUpdate: #delayedUpdateCurrentLine

    "Created: / 01-02-2018 / 15:23:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 02-10-2018 / 11:04:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBSourceApplication methodsFor:'initialization & release'!

subscribe   
    "Register for debugger events. To be overrided by subclasses"

    debugger announcer
        when: GDBStoppedEvent               send: #onStoppedEvent: to: self.

    sourceView notNil ifTrue:[ 
        sourceView compilerClass setDebugger: debugger.
    ].

    "Created: / 01-02-2018 / 15:18:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 21-03-2018 / 22:18:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!VDBSourceApplication class methodsFor:'documentation'!

version_HG

    ^ '$Changeset: <not expanded> $'
! !