diff --git a/src/Grafoscopio/GrafoscopioAbstractNode.class.st b/src/Grafoscopio/GrafoscopioAbstractNode.class.st index 57854ea..1c37012 100644 --- a/src/Grafoscopio/GrafoscopioAbstractNode.class.st +++ b/src/Grafoscopio/GrafoscopioAbstractNode.class.st @@ -9,9 +9,63 @@ Class { 'parent', 'tags' ], + #classInstVars : [ + 'clipboard' + ], #category : #'Grafoscopio-Model' } +{ #category : #utility } +GrafoscopioAbstractNode class >> cleanTreeRootReferences [ + + | ref | + clipboard ifNil: [ ^ self ]. + clipboard children ifNil: [ ^ self ]. + clipboard preorderTraversal allButFirstDo: [ :n | + ref := n. + n level - 1 timesRepeat: [ ref := ref parent ]. + ref parent = clipboard parent ifTrue: [ ref parent: nil ]]. + clipboard parent: nil. +] + +{ #category : #accessing } +GrafoscopioAbstractNode class >> clipboard [ + ^ clipboard +] + +{ #category : #accessing } +GrafoscopioAbstractNode class >> clipboard: anObject [ + clipboard := anObject +] + +{ #category : #utility } +GrafoscopioAbstractNode class >> contentProviders [ + "I list the domains of certain providers that are treated specially, because they + store and offer content like Smalltalk playgrounds or source code, that can be used + in particular ways while importing or exporting content in a node." + + ^ Dictionary new + at: 'playgrounds' put: #('ws.stfx.eu'); + at: 'fossil' put: #('mutabit.com/repos.fossil'); + at: 'etherpads' put: #('pad.tupale.co' ); + yourself. +] + +{ #category : #testing } +GrafoscopioAbstractNode class >> isAbstract [ + ^ self = GrafoscopioAbstractNode +] + +{ #category : #utility } +GrafoscopioAbstractNode class >> specialWords [ + "I return a list of word that were used in the first versions of Grafoscopio to mark node + headers to indicate special ways to handle them and their node contents. + Previous versions of first notebooks stored in Grafoscopio using this convention should be + migrated to newer versions where tags are used for the same function with simpler code" + + ^ #('%config' '%abstract' '%invisible' '%idea' '%footnote' '%metadata' '%output' '%embed' '%item'). +] + { #category : #'add/remove nodes' } GrafoscopioAbstractNode >> addNodeAfterMe: genericNode [ "Adds a generic node after the given node so they become slibings of the same parent" @@ -120,6 +174,14 @@ GrafoscopioAbstractNode >> initialize [ edited := DateAndTime now ] +{ #category : #accessing } +GrafoscopioAbstractNode >> instantiateBody [ + | body | + body := self specModelClass new. + body content: self content. + ^ body +] + { #category : #accessing } GrafoscopioAbstractNode >> isLeaf [ ^ true @@ -149,8 +211,11 @@ GrafoscopioAbstractNode >> moveUp [ { #category : #accessing } GrafoscopioAbstractNode >> openIn: aNotebook [ aNotebook header text: self header. - aNotebook body: (aNotebook instantiate: self specModelClass new). - aNotebook body content: self content + aNotebook + body: + (self instantiateBody + owner: aNotebook; + yourself) ] { #category : #accessing } diff --git a/src/Grafoscopio/GrafoscopioCodeNode.class.st b/src/Grafoscopio/GrafoscopioCodeNode.class.st index 877a72b..5ab1f4b 100644 --- a/src/Grafoscopio/GrafoscopioCodeNode.class.st +++ b/src/Grafoscopio/GrafoscopioCodeNode.class.st @@ -8,6 +8,11 @@ Class { #category : #'Grafoscopio-Model' } +{ #category : #'as yet unclassified' } +GrafoscopioCodeNode class >> nameForSelection [ + ^ 'New Code Node' +] + { #category : #adding } GrafoscopioCodeNode >> addNode: aNode [ "Adds the given node to the receivers collection of children, and sets this object as the parent @@ -18,6 +23,16 @@ GrafoscopioCodeNode >> addNode: aNode [ ^aNode ] +{ #category : #'as yet unclassified' } +GrafoscopioCodeNode >> body [ + ^ body +] + +{ #category : #'as yet unclassified' } +GrafoscopioCodeNode >> body: aBody [ + body := aBody +] + { #category : #'as yet unclassified' } GrafoscopioCodeNode >> content [ ^ body ifNil:[ '' ] @@ -28,6 +43,14 @@ GrafoscopioCodeNode >> header [ ^ super header, ' (Code)' ] +{ #category : #'as yet unclassified' } +GrafoscopioCodeNode >> instantiateBody [ + | widget | + widget := super instantiateBody. + widget body whenTextChangedDo: [ :arg | self body: arg ]. + ^ widget +] + { #category : #'as yet unclassified' } GrafoscopioCodeNode >> shouldAskBeforeRemove [ ^ self content isNotEmpty diff --git a/src/Grafoscopio/GrafoscopioNewNotebook.class.st b/src/Grafoscopio/GrafoscopioNewNotebook.class.st index 6bb6e18..c9fd000 100644 --- a/src/Grafoscopio/GrafoscopioNewNotebook.class.st +++ b/src/Grafoscopio/GrafoscopioNewNotebook.class.st @@ -58,7 +58,7 @@ GrafoscopioNewNotebook class >> defaultSpec [ { #category : #'instance creation' } GrafoscopioNewNotebook class >> kindsOfNode [ - ^ GrafoscopioAbstractNode allSubclasses + ^ GrafoscopioAbstractNode allSubclasses select: [ : c | c isAbstract not ] ] { #category : #'instance creation' } @@ -91,13 +91,16 @@ GrafoscopioNewNotebook >> addCommandFrom: dictionary into: stream [ { #category : #'editing nodes' } GrafoscopioNewNotebook >> addNode [ - | newNode kind | + | newNode kind previousPath | kind := self chooseKindOfNode. kind isClass ifTrue: [ newNode := kind new. + self currentNode addNodeAfterMe: newNode. + previousPath := tree selection selectedPath. self notebookContent: notebook. - self selectedItem: newNode ] + + self selectedPathNextTo: previousPath ] ] { #category : #persistence } @@ -137,7 +140,7 @@ GrafoscopioNewNotebook >> chooseKindOfNode [ | idx values | values := self kindsOfNode. idx := UIManager default - chooseFrom: values + chooseFrom: (values collect: [ :v | v nameForSelection ]) lines: {} title: 'What kind of node? '. ^ idx = 0 @@ -501,18 +504,17 @@ GrafoscopioNewNotebook >> initialize [ { #category : #initialization } GrafoscopioNewNotebook >> initializePresenter [ tree - whenActivatedDo: - [ :selection | selection ifNotNil: [ self updateBodyFor: selection selectedItem ] ]. + whenSelectionChangedDo: + [ :selection | selection selectedItem ifNotNil: [ self updateBodyFor: selection selectedItem ] ]. header whenTextChangedDo: [ :arg | tree selectedItem header = arg - ifFalse: [ - | item | - item := tree selectedItem. - tree selectedItem header: arg. + ifFalse: [ | item | + item := tree selectedItem. + tree selectedItem header: arg. tree selectedItem updateEditionTimestamp. tree roots: tree roots. - tree selectItem:item ] ]. + tree selectItem: item ] ]. links whenTextChangedDo: [ :arg | (tree respondsTo: #link:) @@ -538,9 +540,6 @@ GrafoscopioNewNotebook >> initializeWidgets [ node isLeaf ifTrue: [ {} ] ifFalse: [ node children ] ]. - " tree - childrenBlock: [ :node | node children value ]; - displayBlock: [ :node | node title value ]." self focusOrder add: tree; add: header; @@ -552,7 +551,7 @@ GrafoscopioNewNotebook >> initializeWidgets [ GrafoscopioNewNotebook >> initializeWindow: aWindowPresenter [ super initializeWindow: aWindowPresenter. aWindowPresenter - title: ' New | Grafoscopio notebook'; + title: ' New | Grafoscopio 2.0 notebook'; windowIcon: self taskbarIcon; askOkToClose: true ] @@ -650,7 +649,8 @@ GrafoscopioNewNotebook >> moveSelectedNodeDown [ editedNode := tree selectedItem. editedNode moveDown. self notebookContent: notebook. - tree needRebuild: true + tree needRebuild: true. + tree selectItem: editedNode. ] { #category : #'editing nodes' } @@ -966,8 +966,7 @@ GrafoscopioNewNotebook >> resetSelectedItem [ { #category : #'editing nodes' } GrafoscopioNewNotebook >> resetSelectedItemTo: aPath [ - tree selectPath: {(aPath first min: notebook children size)}. - tree updatePresenter + self selectedPathPreviousTo: aPath ] { #category : #persistence } @@ -1027,6 +1026,30 @@ GrafoscopioNewNotebook >> selectedItem: anItem [ tree selectItem: (tree roots detect: [ : p | p = anItem ]). ] +{ #category : #'asdas yet unclassified' } +GrafoscopioNewNotebook >> selectedItem: aGrafoscopioTextNode path: aPath [ + aPath + at: aPath size + put: (aPath at: aPath size) + 1. + tree selectPath: aPath +] + +{ #category : #'asdas yet unclassified' } +GrafoscopioNewNotebook >> selectedPathNextTo: aPath [ + aPath + at: aPath size + put: (aPath at: aPath size) + 1. + tree selectPath: aPath +] + +{ #category : #'asdas yet unclassified' } +GrafoscopioNewNotebook >> selectedPathPreviousTo: aPath [ + (aPath at: aPath size) - 1 > 0 + ifTrue: [ aPath at: aPath size put: (aPath at: aPath size) - 1. + tree selectPath: aPath ] + ifFalse: [ self selectedPathPreviousTo: aPath allButLast ] +] + { #category : #persistence } GrafoscopioNewNotebook >> subtreeAsMarkdown [ | currentNode | diff --git a/src/Grafoscopio/GrafoscopioTextNode.class.st b/src/Grafoscopio/GrafoscopioTextNode.class.st index 24f9aa9..01e974f 100644 --- a/src/Grafoscopio/GrafoscopioTextNode.class.st +++ b/src/Grafoscopio/GrafoscopioTextNode.class.st @@ -17,56 +17,12 @@ Class { 'body', 'links' ], - #classInstVars : [ - 'clipboard' - ], #category : #'Grafoscopio-Model' } -{ #category : #utility } -GrafoscopioTextNode class >> cleanTreeRootReferences [ - - | ref | - clipboard ifNil: [ ^ self ]. - clipboard children ifNil: [ ^ self ]. - clipboard preorderTraversal allButFirstDo: [ :n | - ref := n. - n level - 1 timesRepeat: [ ref := ref parent ]. - ref parent = clipboard parent ifTrue: [ ref parent: nil ]]. - clipboard parent: nil. -] - -{ #category : #accessing } -GrafoscopioTextNode class >> clipboard [ - ^ clipboard -] - -{ #category : #accessing } -GrafoscopioTextNode class >> clipboard: anObject [ - clipboard := anObject -] - -{ #category : #utility } -GrafoscopioTextNode class >> contentProviders [ - "I list the domains of certain providers that are treated specially, because they - store and offer content like Smalltalk playgrounds or source code, that can be used - in particular ways while importing or exporting content in a node." - - ^ Dictionary new - at: 'playgrounds' put: #('ws.stfx.eu'); - at: 'fossil' put: #('mutabit.com/repos.fossil'); - at: 'etherpads' put: #('pad.tupale.co' ); - yourself. -] - -{ #category : #utility } -GrafoscopioTextNode class >> specialWords [ - "I return a list of word that were used in the first versions of Grafoscopio to mark node - headers to indicate special ways to handle them and their node contents. - Previous versions of first notebooks stored in Grafoscopio using this convention should be - migrated to newer versions where tags are used for the same function with simpler code" - - ^ #('%config' '%abstract' '%invisible' '%idea' '%footnote' '%metadata' '%output' '%embed' '%item'). +{ #category : #'as yet unclassified' } +GrafoscopioTextNode class >> nameForSelection [ + ^ 'New Text Node' ] { #category : #operation } @@ -527,6 +483,14 @@ GrafoscopioTextNode >> initialize [ self body: '' ] +{ #category : #accessing } +GrafoscopioTextNode >> instantiateBody [ + | widget | + widget := super instantiateBody. + widget body whenTextChangedDo: [ :arg | self body: arg ]. + ^ widget +] + { #category : #accessing } GrafoscopioTextNode >> isEmpty [ body ifNil: [ ^ true ] ifNotNil: [ ^ false ] diff --git a/src/Grafoscopio/GrafoscopioTrunkNode.class.st b/src/Grafoscopio/GrafoscopioTrunkNode.class.st index 58d4762..ba2c120 100644 --- a/src/Grafoscopio/GrafoscopioTrunkNode.class.st +++ b/src/Grafoscopio/GrafoscopioTrunkNode.class.st @@ -7,6 +7,11 @@ Class { #category : #'Grafoscopio-Model' } +{ #category : #testing } +GrafoscopioTrunkNode class >> isAbstract [ + ^ self = GrafoscopioTrunkNode +] + { #category : #accessing } GrafoscopioTrunkNode >> children [ "Returns the receivers list of children" diff --git a/src/Grafoscopio/GrafoscopioUrlCachedNode.class.st b/src/Grafoscopio/GrafoscopioUrlCachedNode.class.st index 913050d..7d52409 100644 --- a/src/Grafoscopio/GrafoscopioUrlCachedNode.class.st +++ b/src/Grafoscopio/GrafoscopioUrlCachedNode.class.st @@ -7,6 +7,11 @@ Class { #category : #'Grafoscopio-Model' } +{ #category : #'instance creation' } +GrafoscopioUrlCachedNode class >> nameForSelection [ + ^ 'New URL-Cached Node' +] + { #category : #accessing } GrafoscopioUrlCachedNode >> content [ ^ content isEmptyOrNil diff --git a/src/Grafoscopio/GrafoscopioUrlNode.class.st b/src/Grafoscopio/GrafoscopioUrlNode.class.st index 0928afd..db13793 100644 --- a/src/Grafoscopio/GrafoscopioUrlNode.class.st +++ b/src/Grafoscopio/GrafoscopioUrlNode.class.st @@ -7,6 +7,11 @@ Class { #category : #'Grafoscopio-Model' } +{ #category : #'instance creation' } +GrafoscopioUrlNode class >> nameForSelection [ + ^ 'New URL Node' +] + { #category : #'instance creation' } GrafoscopioUrlNode class >> new [ ^ super new