Grafoscopio/repository/Grafoscopio/GrafoscopioBrowser.class.st

1129 lines
37 KiB
Smalltalk

"
I am a graphical interface for showing trees, outlines and grafoscopio notebooks.
Instance Variables
browser: <Object>
browser
- xxxxx
"
Class {
#name : #GrafoscopioBrowser,
#superclass : #Object,
#instVars : [
'browser',
'mainTree',
'tagsAvailable',
'cacheNode',
'workingFile'
],
#classVars : [
'dockingBar',
'draftsLocation',
'recentTrees'
],
#classInstVars : [
'workingFile'
],
#category : #'Grafoscopio-UI'
}
{ #category : #updating }
GrafoscopioBrowser class >> docDataManual [
"I define some metadata associated to the manual document.
Language is provided according to the ISO 639-1 code convention."
| docData |
docData := Dictionary
with: 'type' -> 'manual'
with: 'languageCode' -> 'ES_CO'
with: 'remoteRepo' -> 'http://mutabit.com/repos.fossil/grafoscopio/'
with: 'relativePath' -> 'Docs/Es/Manual/'
with: 'filename' -> 'manual-grafoscopio.ston'.
^ docData
]
{ #category : #updating }
GrafoscopioBrowser class >> docDataTutorial [
"I define some metadata associated to the tutorial document.
Language is provided according to the ISO 639-1 code convention."
| docData |
docData := Dictionary
with: 'type' -> 'tutorial'
with: 'languageCode' -> 'ES_CO'
with: 'remoteRepo' -> 'http://mutabit.com/repos.fossil/grafoscopio/'
with: 'relativePath' -> 'Docs/Es/Tutoriales/'
with: 'filename' -> 'tutorial.ston'.
^ docData
]
{ #category : #updating }
GrafoscopioBrowser class >> docDownloadFor: aDocumentType [
"I download the interactive documentation in STON format, according to the document
type which can be: 'tutorial' or 'manual'.
If a the documentation is already present in the system I made a temporal backup and
download a new copy"
| docInfo rootFolder localDoc temporalBackup remoteDoc |
(aDocumentType = 'tutorial') ifTrue: [ docInfo := self docDataTutorial ].
(aDocumentType = 'manual') ifTrue: [ docInfo := self docDataManual ].
rootFolder := (FileLocator documents asFileReference / 'Grafoscopio').
rootFolder exists ifFalse: [
rootFolder ensureCreateDirectory.
OSProcess command: ('exec mkdir -p ', rootFolder fullName, '/', (docInfo at: 'relativePath'))
].
localDoc := rootFolder fullName, '/', (docInfo at: 'relativePath'), (docInfo at: 'filename').
temporalBackup := rootFolder fullName, '/', (docInfo at: 'relativePath'), aDocumentType, '.temp.ston'.
remoteDoc :=
(self docDataTutorial at: 'remoteRepo'), 'doc/tip/',
(self docDataTutorial at: 'relativePath'), (self docDataTutorial at: 'filename').
localDoc asFileReference exists
ifTrue: [
temporalBackup asFileReference exists ifTrue: [ temporalBackup asFileReference delete].
localDoc asFileReference renameTo: aDocumentType, '.temp.ston'
].
self
downloadingFrom: remoteDoc
withMessage: 'Actualizando el ', aDocumentType,'...'
into: (rootFolder fullName, '/', (docInfo at: 'relativePath')).
]
{ #category : #'graphical interface' }
GrafoscopioBrowser class >> downloadingFrom: downloadUrl withMessage: aString into: location [
[: bar |
bar title: aString.
[ZnClient new
enforceHttpSuccess: true;
url: downloadUrl;
downloadTo: location;
signalProgress: true
]
on: HTTPProgress
do: [ :progress |
progress isEmpty ifFalse: [ bar current: progress percentage ].
progress resume ].
] asJob run.
]
{ #category : #updating }
GrafoscopioBrowser class >> isDocUpdatedFor: aDocumentType [
"I compare the cryptografic signatures of the local copy of aDocumentType and the remote one to see if the're the same,
in which case I return True or False in any other cases.
aDocumentType is a string that can be 'tutorial' or 'manual' according to the type of document we're querying for.
Now documentation is mainly on Spanish. When support for multiple languages be enabled this method needs revision"
| folderLastContents lastRemoteTutorial localTutorial docInfo |
(aDocumentType = 'tutorial') ifTrue: [ docInfo := self docDataTutorial ].
(aDocumentType = 'manual') ifTrue: [ docInfo := self docDataManual ].
localTutorial := FileLocator documents / 'Grafoscopio', (docInfo at: 'relativePath'), (docInfo at: 'filename').
localTutorial exists
ifFalse: [
self docDownloadFor: 'tutorial'.
^ true.
]
ifTrue: [
folderLastContents := NeoJSONReader fromString:
(ZnEasy get: (docInfo at: 'remoteRepo'), 'json/dir?ci=tip&name=', (docInfo at: 'relativePath')) contents.
lastRemoteTutorial := ((folderLastContents at: 'payload') at: 'entries')
detect: [:entry | (entry at: 'name') = (docInfo at: 'filename') ].
^ (lastRemoteTutorial at: 'uuid') = (SHA1 new hashMessage: (localTutorial asFileReference contents)) hex]
]
{ #category : #'graphical interface' }
GrafoscopioBrowser class >> messageAbout [
"Shows the author, license, sponsors and main contributors to the project and point to further documentation on the web"
LongMessageDialogWindow new
entryText:
'_.:| Grafoscopio |:._',
(String with: Character cr),
'(c) Copyright 2014-2016 by Offray Vladimir Luna Cárdenas',
(String with: Character cr),
'Covered under MIT license.',
(String with: Character cr),
(String with: Character cr),
'[ Sponsors ]',
(String with: Character cr),
'mutabiT | www.mutabit.com ',
(String with: Character cr),
'HiTec Lab, Fundación Universitaria Los Libertadores | www.ulibertadores.edu.co ',
(String with: Character cr),
(String with: Character cr),
'[ Thanks to ]',
(String with: Character cr),
'HackBo, Hackerspace Bogota | http://hackbo.co',
(String with: Character cr),
'// Regular workshops attendees \\
Rafael Medida, Iván Pulido, Camilo Hurtado',
(String with: Character cr),
'// Coffe talk (mostly about grafoscopio) \\
Yanneth Gil, Andrés Calderón, Luis Alejandro Bernal',
(String with: Character cr),
'// Pharo, Moose and Agile Visualization communities \\
Tudor Girba, Alexandre Bergel, Nicolai Hess, Peter Uhnák, Milton Mamani ',
(String with: Character cr),
'// Family support while writing, coding & travelling (among others!) \\
Divian Luna, Hilda Cárdenas',
(String with: Character cr),
(String with: Character cr),
'For further details and versions go to:',
(String with: Character cr),
(String with: Character cr),
'http://mutabit.com/grafoscopio';
title: 'About Grafoscopio';
open.
]
{ #category : #'graphical interface' }
GrafoscopioBrowser class >> messageNoRecentDocuments [
"Shows that a feature is not implemeted and point to further documentation on the web"
UIManager default abort:
'No hay documentos recientes.',
(String with: Character cr),
'Abra un documento usando el menú:',
(String with: Character cr),
(String with: Character cr),
'"Lanzar > Documento interactivo desde archivo"',
(String with: Character cr),
(String with: Character cr)
title: 'No hay documentos recientes'.
]
{ #category : #'graphical interface' }
GrafoscopioBrowser class >> messageNotImplementedYet [
"Shows that a feature is not implemeted and point to further documentation on the web"
UIManager default abort:
'Esta funcionalidad aún no está implementada!',
(String with: Character cr),
'Para información sobre futuras versiones, por favor visite: ',
(String with: Character cr),
(String with: Character cr),
'http://mutabit.com/grafoscopio',
(String with: Character cr),
(String with: Character cr)
title: 'No implementado aún'.
]
{ #category : #'graphical interface' }
GrafoscopioBrowser class >> open [
^ self new open
]
{ #category : #'graphical interface' }
GrafoscopioBrowser class >> openFromRecentlyUsed [
"Opens a recent notebooks list"
| selection |
recentTrees isNil
ifFalse: [
selection := UIManager default chooseFrom: recentTrees title: 'Elija una documento'.
GrafoscopioBrowser new openFromFile: (recentTrees at: selection)
]
ifTrue: [self messageNoRecentDocuments].
"browser update".
]
{ #category : #'graphical interface' }
GrafoscopioBrowser class >> openHelpInHtml [
"Launches the help manual in PDF format in an external viewer."
| htmlHelpFileLocation |
htmlHelpFileLocation := (FileSystem disk workingDirectory parent / 'Docs' /'Es' / 'Manual' / 'manual-grafoscopio.html') fullName.
Smalltalk platform name = 'unix'
ifTrue: [OSProcess command: 'xdg-open ', htmlHelpFileLocation].
Smalltalk platform name = 'Win32'
ifTrue: [OSProcess command: 'explorer ', htmlHelpFileLocation].
Smalltalk platform name = 'Mac OS'
ifTrue: [OSProcess command: 'open ', htmlHelpFileLocation].
]
{ #category : #'graphical interface' }
GrafoscopioBrowser class >> openHelpInPdf [
"Launches the help manual in PDF format in an external viewer."
| pdfHelpFileLocation |
pdfHelpFileLocation := (FileSystem disk workingDirectory parent / 'Docs' /'Es' / 'Manual' / 'manual-grafoscopio.pdf') fullName.
Smalltalk platform name = 'unix'
ifTrue: [OSProcess command: 'xdg-open ', pdfHelpFileLocation].
Smalltalk platform name = 'Win32'
ifTrue: [OSProcess command: 'explorer ', pdfHelpFileLocation].
Smalltalk platform name = 'Mac OS'
ifTrue: [OSProcess command: 'open ', pdfHelpFileLocation].
]
{ #category : #configuration }
GrafoscopioBrowser class >> showSettings [
"Shows the settings in a Transcript. This should return a dictionary for better management of the settings. For the moment
is a quick a dirty hack"
Transcript show: fossil; cr.
Transcript show: pandoc
]
{ #category : #updating }
GrafoscopioBrowser class >> updateDataviz [
"I'm update the Dataviz package with new versions of itself take from the source code repository.
DataViz contains Data visualization helpers"
Gofer it
smalltalkhubUser: 'Offray' project: 'Dataviz';
configurationOf: 'Dataviz';
loadVersion: #development.
self inform: 'Actualización del paquete Dataviz terminada'
]
{ #category : #updating }
GrafoscopioBrowser class >> updateDatavizUI [
"I'm the User Interface for updating the Dataviz package with new versions of itself take from the source code repository"
| update |
update := (UIManager default
question: 'Dataviz es un paquete de visualización de datos'
title: 'Actualizar paquete Dataviz').
update ifNotNil: [
update
ifTrue: [self updateDataviz]
ifFalse: [self inform: 'Actualización del paquete dataviz no realizada']]
]
{ #category : #updating }
GrafoscopioBrowser class >> updateDocumentation [
"Updates documentation (manual, tutorials) from official repository"
| docs |
docs := #('tutorial' 'manual').
docs do: [ :eachDoc |
(self isDocUpdatedFor: eachDoc)
ifFalse: [ self docDownloadFor: eachDoc]
ifTrue: [
self inform:
'NADA QUE ACTUALIZAR!', String cr,
'El ', eachDoc,' ya se encuentra en su versión más reciente.'
]
]
]
{ #category : #updating }
GrafoscopioBrowser class >> updateDocumentationUI [
"Updates documentation (manual, tutorials) from official repository"
| update |
update := (UIManager default
confirm: '¿Desea actualizar la documentación?'
label: 'Actualizar documentación').
update ifTrue: [self updateDocumentation]
]
{ #category : #updating }
GrafoscopioBrowser class >> updateGrafoscopio [
"Updates Grafoscopio with new versions of itself take from the source code repository and
the User Interface"
Gofer new
smalltalkhubUser: 'Offray' project: 'Grafoscopio';
package: 'Grafoscopio';
load.
self updateUI.
]
{ #category : #updating }
GrafoscopioBrowser class >> updateGrafoscopioUI [
"Updates Grafoscopio with new versions of itself take from the source code repository and
the User Interface"
| update |
update := (UIManager default
question: '¿Desea actualizar grafoscopio?'
title: 'Actualizar grafoscopio').
update ifNotNil: [
update
ifTrue: [
self updateGrafoscopio.
self inform: 'Actualización de grafoscopio terminada']
ifFalse: [self inform: 'Actualización de grafoscopio no realizada']]
]
{ #category : #updating }
GrafoscopioBrowser class >> updatePrerrequisitesScript [
"Updates the system prerequisites with new versions of itself take from the source code repository"
"Visualization library (which also makes main menu loadable)"
Gofer it
smalltalkhubUser: 'ObjectProfile' project: 'Roassal2';
configurationOf: 'Roassal2';
loadStable.
"Support for the STON format used in file persistance for grafoscopio notebooks"
Gofer new
smalltalkhubUser: 'SvenVanCaekenberghe' project: 'STON';
configurationOf: 'Ston';
loadBleedingEdge.
"Moose and Roassal integration"
Gofer new
smalltalkhubUser: 'Moose' project: 'Glamour';
package: 'Glamour-Tools';
package: 'Glamour-Roassal2-Presentations';
load.
Gofer new
smalltalkhubUser: 'Moose' project: 'GToolkit';
package: 'GT-InspectorExtensions-CoreRoassal';
load.
"Fast Table support"
Gofer it
smalltalkhubUser: 'estebanlm' project: 'FastTable';
package: 'FastTable';
load.
"Integration with external tools"
Gofer new
smalltalkhubUser: 'Offray' project: 'Grafoscopio';
package: 'Grafoscopio-ExternalTools';
load.
"HTML scrapping"
Gofer new
smalltalkhubUser: 'PharoExtras' project: 'Soup';
configurationOf: 'Soup';
loadStable.
"SQLite support"
Gofer new
url: 'http://smalltalkhub.com/mc/PharoExtras/NBSQLite3/main';
package: 'NBSQLite3';
load.
Gofer new
url: 'http://smalltalkhub.com/mc/PharoExtras/NBSQLite3/main';
package: 'NBSQLite3-Examples';
load.
"Support for Operative System integration"
Gofer new
squeaksource: 'OSProcess';
package: 'OSProcess';
load.
Gofer new
squeaksource: 'CommandShell';
package: 'CommandShell-Piping';
load.
"Bibliographic support"
Gofer new
squeaksource: 'Citezen';
package: 'ConfigurationOfCitezen';
load.
]
{ #category : #updating }
GrafoscopioBrowser class >> updateSystem [
"Updates the system with new versions of itself take from the source code repository"
| update |
update := (UIManager default
question: '¿Desea actualizar grafoscopio?'
title: 'Actualizar grafoscopio').
update ifNotNil: [
update
ifFalse: [ self inform: 'Actualización de todo el sistema NO realizada.' ]
ifTrue: [
self
updateGrafoscopio;
updateDocumentation;
updateDataviz.
ExternalApp installSQLite32Bits.
self inform: 'Actualización de todo el sistema terminada.']
]
]
{ #category : #updating }
GrafoscopioBrowser class >> updateUI [
"I update the User Interface (UI) with new versions of the docking bar or logos where available.
I'm helpful while testing new functionality that should be expossed to the user via the UI"
dockingBar delete.
GrafoscopioGUI startDockingBar.
]
{ #category : #tags }
GrafoscopioBrowser >> addTagTo: aNode [
"Tags the node passed as argument with a value from the collection of tags available"
| selection |
tagsAvailable isNil
ifFalse: [
selection := UIManager default chooseFrom: tagsAvailable title: 'Elija una etiqueta'.
aNode tagAs: (tagsAvailable at: selection)
]
ifTrue: [self messageNoTagsAvailable].
browser update.
]
{ #category : #tags }
GrafoscopioBrowser >> addToTagsAvailable [
"Adds a tag to the collection of tags available"
| tag |
tagsAvailable isNil
ifTrue: [tagsAvailable := OrderedCollection new].
tag := UIManager default
textEntry: 'Nombre de la etiqueta'
title: 'Agregue una etiqueta'.
tagsAvailable add: tag.
]
{ #category : #'graphical interface' }
GrafoscopioBrowser >> bodyForCodeIn: constructor for: aNode [
"Shows the body of a node as an interactive playground. If node is not tagged it will return itself,
so it can be rendered properly for other messages"
| innerBrowser |
aNode tags = 'código'
ifFalse: [^self].
innerBrowser := GTPlayground new.
constructor custom: innerBrowser.
]
{ #category : #'graphical interface' }
GrafoscopioBrowser >> bodyIn: constructor for: aNode [
"Shows the body in a constructor for selected node, if node is not tagged.
If it is tagged it will return itself, so it can be rendered properly for other messages"
| specialTags |
specialTags := #('código').
(specialTags includes: aNode tags)
ifTrue: [^self].
(constructor text)
title: 'Texto ';
format:[
aNode body isNil
ifTrue: [ '' ]
ifFalse: [ aNode body]].
]
{ #category : #'graphical interface' }
GrafoscopioBrowser >> buildBrowserNamed: aName [
"Main method for building the interface for trees and its nodes.
The name of the browser corresponds to the name of the file
where tree is stored (or is named 'draft.ston' by default)"
self configureInitialTags.
browser := GLMTabulator new
title: aName, ' | Grafoscopio'.
browser
column: [:c |
c row: #tree span: 6;
row: #nodeHeader span: 1] span: 2;
column: [ :c |
c row: #nodeBody span: 2] span: 5.
browser
updateOn: GLMItemAdded from: #yourself;
updateOn: GLMItemRemoved from: #yourself.
(browser transmit)
to: #tree;
andShow: [:a | self treeOn: a].
"Creating a self updatable body pane"
(browser transmit)
from: #tree port: #selection;
to: #nodeBody;
when: [:selection | selection notNil];
andShow: [ :a :node |
self bodyIn: a for: node.
self bodyForCodeIn: a for: node ].
(browser transmit )
from: #tree port: #selection;
from: #nodeBody port: #text;
when: [:node :text | text notNil & node notNil];
to: #nodeBody port: #neverland;
transformed: [:node :content |
node body: content asString.
"node tags = 'código'
ifFalse: [node body: content asString]
ifTrue: [node body: content asString. Transcript show: content asString]"].
(browser transmit)
from: #tree;
to: #nodeHeader;
andShow: [ :h | self headerOn: h ].
(browser transmit )
from: #tree port: #selection;
from: #nodeHeader port: #text;
to: #nodeHeader port: #neverland1;
when: [:node :text | text notNil & node notNil];
transformed: [:node :text | node header: text asString]
]
{ #category : #'system-support' }
GrafoscopioBrowser >> configureInitialTags [
"Configures a list of predefined tags available to use. More tags should be added from a repository.
The idea is that nodes are processed and show differently according to their tags. So users should be
able to define their own tags with custom UI and behaviour"
tagsAvailable := OrderedCollection new.
tagsAvailable
add: 'código';
add: 'ejercicio';
add: 'invisible';
add: 'obra';
add: 'original';
add: 'transmediado'.
]
{ #category : #persistence }
GrafoscopioBrowser >> copyNodeIntoCache: aNode [
"Copy the contents of the current node into cacheNode. It doesn't work recursively yet, so it doen't copy the children of the nodes"
cacheNode := GrafoscopioNode new.
cacheNode header: (aNode header).
cacheNode body: (aNode body).
self inform: 'Nodo copiado: ', aNode header
]
{ #category : #bibliography }
GrafoscopioBrowser >> customKeys [
"Replaces the default key in a BibTeX file for a custom key taken from the 'shorttitle' field.
Useful when autogenerated BibTeX has cryptic or non easy to memorize keys (for example in some
Zotero exports)"
| bibFile bibliography bibStream bibOutputer |
bibFile := ((workingFile parent) children
detect: [:each | each basename endsWith: 'bib' ] ifNone: [ ]).
bibFile ifNotNil: [
bibliography := CZBibParser parse: bibFile contents.
bibStream := '' writeStream.
(bibliography entries) do: [:bibItem |
bibItem fields do: [:some | some key = 'shorttitle'
ifTrue: [ bibItem key: some value ]].
bibOutputer := CZBibtexOutputer new.
bibStream nextPutAll:
(bibOutputer entryToBibtexString: bibItem); cr].
bibFile writeStreamDo: [:stream |
stream nextPutAll: bibStream contents withUnixLineEndings ]].
]
{ #category : #persistence }
GrafoscopioBrowser >> exportAsHtml [
"I exports the current tree to HTML, using the same name but different extension (.html).
IMPORTANT: Pandoc must be installed in your system. In the future Grafoscopio will provide"
| markdownFileLocation htmlFileLocation |
markdownFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.markdown'.
htmlFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.html'.
ExternalApp pandoc notNil
ifTrue:[
(Smalltalk platform name = 'unix') | (Smalltalk platform name = 'Mac OS')
ifTrue: [
OSProcess command: 'pandoc ', ' ', markdownFileLocation , ' --standalone -o ' , htmlFileLocation.
OSProcess command: 'exec echo "exportando como html"'.
self inform: 'Archivo exportado como html en: ', htmlFileLocation].
Smalltalk platform name = 'Win32'
ifTrue: [ OSProcess command: 'pandoc ', markdownFileLocation , ' --standalone -o ' , htmlFileLocation ]]
ifFalse: [ExternalApp pandoc].
]
{ #category : #persistence }
GrafoscopioBrowser >> exportAsLatex [
"I Export the current tree to LaTeX, using the same name but different extension (.tex).
IMPORTANT: The user needs to have TeX installed with minted support and pygments for syntax highlighting.
More details at: http://ctan.dcc.uchile.cl/macros/latex/contrib/minted/minted.pdf"
| markdownFileLocation latexFileLocation fileName |
fileName := workingFile basenameWithoutExtension.
markdownFileLocation := ((workingFile parent) / fileName) fullName, '.markdown'.
latexFileLocation := ((workingFile parent) / fileName) fullName, '.tex'.
ExternalApp pandoc binaryLocation exists
ifFalse: [ExternalApp configurePandoc]
ifTrue:[
OSProcess command:
'pandoc ', markdownFileLocation,
' -V documentclass:article -V geometry:margin=2cm --standalone -o ' ,
fileName, '.tex'.
"Moving the pdf output to the expected location"
latexFileLocation asFileReference exists ifTrue: [latexFileLocation asFileReference ensureDelete ].
(FileLocator imageDirectory parent / (fileName, '.tex'))
moveTo: latexFileLocation asFileReference.
"Cleaning left overs"
(FileLocator imageDirectory parent / (fileName, '.tex')) ensureDelete.
self inform: 'Archivo exportado como latex en: ', latexFileLocation
]
]
{ #category : #persistence }
GrafoscopioBrowser >> exportAsMarkdown: aTree on: locator [
locator writeStreamDo: [:stream | stream nextPutAll: aTree asMarkdown]
]
{ #category : #persistence }
GrafoscopioBrowser >> exportAsPdf [
"Exports the current tree to HTML, using the same name but different extension (.pdf).
IMPORTANT: The user needs to have installed TeX to create the pdf."
| latexFileLocation pdfFileLocation fileName |
fileName := workingFile basenameWithoutExtension.
self exportAsLatex.
latexFileLocation := ((workingFile parent) / fileName) fullName, '.tex'.
pdfFileLocation := ((workingFile parent) / fileName) fullName, '.pdf'.
'/usr/bin/xelatex' asFileReference exists
ifTrue: [
"Generating the pdf"
OSProcess command: 'xelatex --shell-escape ', latexFileLocation.
"Moving the pdf output to the expected location"
pdfFileLocation asFileReference exists ifTrue: [pdfFileLocation asFileReference ensureDelete ].
(FileLocator imageDirectory parent / (fileName, '.pdf'))
moveTo: pdfFileLocation asFileReference.
"Cleaning left overs"
#('.aux' '.out' '.log') do: [ :fileExension |
(FileLocator imageDirectory parent asFileReference / (fileName, fileExension)) ensureDelete].
(FileLocator imageDirectory parent asFileReference / ('_minted-', fileName)) deleteAll.
self inform: 'Archivo exportado como pdf en: ', pdfFileLocation]
ifFalse: [
self inform:
'Necesita instalar XeLaTeX/TeX más información en:', String cr,'
http://xetex.sourceforge.net/' ].
]
{ #category : #persistence }
GrafoscopioBrowser >> exportAsSton: aTree on: locator [
| stonPrettyString |
aTree flatten.
stonPrettyString := String streamContents: [ :stream |
(STON writer on: stream)
newLine: String crlf;
prettyPrint: true;
keepNewLines: true;
nextPut: aTree children].
locator nextPutAll: stonPrettyString
]
{ #category : #'graphical interface' }
GrafoscopioBrowser >> headerOn: constructor [
"Shows the body of a selected node"
(constructor text)
title: 'Cabecera ';
format:[:eachNode |
(eachNode header) isNil
ifTrue: [ '' ]
ifFalse: [ eachNode header]].
]
{ #category : #'system-support' }
GrafoscopioBrowser >> installPandoc [
"Installs pandoc binary for each major platform: Linux, Windows, Mac"
| linuxSupplies |
linuxSupplies := (FileSystem disk workingDirectory
/ 'Platform' / 'Linux' / 'Programs' / 'Pandoc')
ensureCreateDirectory.
]
{ #category : #'graphical interface' }
GrafoscopioBrowser >> messageNoTagsAvailable [
"Shows that there is no tags available and the procedure to add some tags"
UIManager default
abort:
'Use primero el menu:',
(String with: Character cr),
'"Etiquetas > Agregar a disponibles"',
(String with: Character cr),
'para agregar etiquetas y luego sí agregue etiquetas al nodo'
title: 'Sin etiquetas disponibles!'
]
{ #category : #'graphical interface' }
GrafoscopioBrowser >> messageNotImplementedYet [
"Shows that a feature is not implemeted and point to further documentation on the web"
UIManager default abort:
'Esta funcionalidad aún no está implementada!',
(String with: Character cr),
'Para información sobre futuras versiones, por favor visite: ',
(String with: Character cr),
(String with: Character cr),
'http://mutabit.com/grafoscopio',
(String with: Character cr),
(String with: Character cr)
title: 'No implementado aún'.
]
{ #category : #persistence }
GrafoscopioBrowser >> open [
"Opens a new browser with a default tree and assigns a default draft file for storing it.
This is changed when the file is saved with the 'Save as' menu option"
"Opens a new browser with a default tree"
"GrafoscopioBrowser configureSettings."
self openDefault.
]
{ #category : #persistence }
GrafoscopioBrowser >> openDefault [
"Opens a new browser with a default tree"
"GrafoscopioBrowser configureSettings."
self buildBrowserNamed: 'draft.ston'.
mainTree := GrafoscopioNode new.
mainTree becomeDefaultTree.
workingFile := draftsLocation / 'draft.ston'.
self saveToFile: workingFile.
self openFromFile: workingFile.
" browser openOn: mainTree children."
]
{ #category : #persistence }
GrafoscopioBrowser >> openFromFile: aFileName [
"Opens a tree from a file named aFileName"
| currentChildren |
"GrafoscopioBrowser configureSettings."
workingFile := aFileName.
currentChildren := (STON fromString: aFileName contents).
self buildBrowserNamed: aFileName basenameWithIndicator.
mainTree := GrafoscopioNode new
header: (currentChildren at: 1) parent header;
level: (currentChildren at: 1) parent level;
metadata: (currentChildren at: 1) parent metadata;
children: currentChildren.
browser openOn: mainTree children.
]
{ #category : #persistence }
GrafoscopioBrowser >> openFromFileSelector [
"Opens a tree from a file by using the file selector GUI."
"REFACTORING NOTES: This sould call openFromFile, instead of having the code repeated here.
This creates errors on debugging and worse on proper behavior"
| fileStream currentChildren |
"GrafoscopioBrowser configureSettings."
fileStream := UITheme builder
fileOpen: 'Elija un archivo .ston'
extensions: #('ston').
fileStream isNil ifTrue: [ ^nil ].
workingFile := fileStream name asFileReference.
currentChildren := (STON fromStream: fileStream).
self buildBrowserNamed: workingFile basenameWithIndicator.
recentTrees isNil
ifTrue:[recentTrees := OrderedCollection new].
"recentTrees detect: workingFile ifFound: [recentTrees add: workingFile]."
recentTrees add: workingFile.
mainTree := GrafoscopioNode new
header: (currentChildren at: 1) parent header;
level: (currentChildren at: 1) parent level;
metadata: (currentChildren at: 1) parent metadata;
children: currentChildren.
browser openOn: mainTree children.
]
{ #category : #persistence }
GrafoscopioBrowser >> openFromUrl: anUrl [
"Opens a tree from a file named aFileName"
| client fileName |
client := ZnClient new.
client get: anUrl.
client isSuccess
ifTrue:[
"GrafoscopioBrowser configureSettings."
fileName := draftsLocation / ((anUrl findTokens: '/') last).
fileName writeStreamDo: [:stream | stream nextPutAll: client contents asString ].
self openFromFile: fileName.]
ifFalse: [self inform: 'Algo salió mal. Verifique su conexión a Internet y que el contenido buscado estén disponibles' ]
]
{ #category : #persistence }
GrafoscopioBrowser >> openFromUrlUI [
"This method generates the UI for the openFromUrl: method, it asks for a URL from the user"
| fileUrl |
"GrafoscopioBrowser configureSettings."
fileUrl := UIManager default
textEntry: 'Ingrese la URL'
title: 'Nuevo documento desde URL'.
fileUrl isNil ifTrue: [ ^nil ].
GrafoscopioBrowser new openFromUrl: fileUrl
]
{ #category : #persistence }
GrafoscopioBrowser >> openHelpInGrafoscopio [
"Opens the help tree from a file"
| currentChildren |
"GrafoscopioBrowser configureSettings."
workingFile := (FileSystem disk workingDirectory / 'Docs' / 'Es' / 'Manual' / 'manual-grafoscopio.ston') asFileReference.
currentChildren := (STON fromString: workingFile contents).
self buildBrowserNamed: workingFile basenameWithIndicator.
mainTree := GrafoscopioNode new
header: 'Arbol principal';
level: 0.
mainTree children: currentChildren.
browser openOn: mainTree children.
]
{ #category : #persistence }
GrafoscopioBrowser >> openTutorialInGrafoscopio [
"Opens the help tree from a file"
| currentChildren |
"GrafoscopioBrowser configureSettings."
workingFile := (FileSystem disk workingDirectory / 'Docs' / 'Es' / 'Tutoriales' / 'tutorial.ston') asFileReference.
currentChildren := (STON fromString: workingFile contents).
self buildBrowserNamed: workingFile basenameWithIndicator.
mainTree := GrafoscopioNode new
header: 'Arbol principal';
level: 0.
mainTree children: currentChildren.
browser openOn: mainTree children.
]
{ #category : #persistence }
GrafoscopioBrowser >> replaceContentsFromCache: aNode [
"Replaces the contents of aNode from the ones in cacheNode. It doesn't work recursively yet, so it doen't copy the children of the nodes"
cacheNode notNil
ifTrue: [
aNode header: cacheNode header.
aNode body: cacheNode body.
self inform: 'Contenidos reemplazados']
ifFalse: [self inform: 'El nodo cache está vacio']
]
{ #category : #persistence }
GrafoscopioBrowser >> repositoryCommit [
"Commits current changes to the open repository"
fossil notNil ifTrue: [
OSProcess command:
'cd ', localRepository parent fullName, '; ',
fossil, ' commit -m "" --no-warnings; ',
'echo "Commited changes to the repository"'. ]
]
{ #category : #persistence }
GrafoscopioBrowser >> repositoryCredentials [
"Asks for the user credentials of the current project repository"
repositoryUser := UIManager default request: 'Ingrese su usuario en el repositorio del proyecto'.
repositoryPassword := UIManager default request: 'Ingrese su contraseña en el repositorio del proyecto'.
]
{ #category : #persistence }
GrafoscopioBrowser >> saveToFile: aFileReference [
"Saves the current tree/document to a file"
| file writeStream markdownFile |
file := aFileReference.
file ifNil: [ self inform: 'Exportación cancelada'. ^ self ].
writeStream := file writeStream.
workingFile := writeStream name asFileReference.
markdownFile := (workingFile parent) / (workingFile basenameWithoutExtension, '.markdown').
markdownFile ensureCreateFile.
[ self exportAsSton: mainTree on: writeStream.
self exportAsMarkdown: mainTree on: markdownFile ]
ensure: [ writeStream ifNotNil: #close ].
recentTrees isNil
ifTrue:[recentTrees := OrderedCollection new].
recentTrees add: workingFile.
browser update.
]
{ #category : #persistence }
GrafoscopioBrowser >> saveToFileUI [
"Saves the current tree to a file"
| file |
file := UITheme builder
fileSave: 'Guardar archivo como...'
extensions: #('ston')
path: nil.
file
ifNil: [ self inform: 'Exportación cancelada'. ^ self ]
ifNotNil:[self saveToFile: file].
browser update.
]
{ #category : #persistence }
GrafoscopioBrowser >> saveWorkingTree [
"Saves the current tree to the user predefined file location used when he/she opened it."
| markdownFile |
markdownFile := (workingFile parent) / (workingFile basenameWithoutExtension, '.markdown').
markdownFile exists ifTrue: [ markdownFile delete ].
markdownFile ensureCreateFile.
workingFile exists ifTrue: [ workingFile delete ].
workingFile ensureCreateFile.
[ self exportAsSton: mainTree on: (workingFile writeStream).
self exportAsMarkdown: mainTree on: markdownFile
] ensure: [ (workingFile writeStream) ifNotNil: #close.].
self inform: 'Archivo guardado como: ', workingFile asString.
]
{ #category : #tags }
GrafoscopioBrowser >> showTagsAvailable [
"Adds a tag to the collection of tags available"
tagsAvailable isNil
ifTrue: [self messageNoTagsAvailable]
ifFalse: [self messageNotImplementedYet]
]
{ #category : #'graphical interface' }
GrafoscopioBrowser >> treeOn: constructor [
"Shows the correspondent tree of a node"
(constructor tree) "Layout"
title: mainTree header;
children: [ :eachNode |
(eachNode children) isNil
ifTrue: [ self inform: 'Seleccione un nodo para ver su contenido' ]
ifFalse:[ eachNode children ] ];
format:[:eachNode |
(eachNode header) isNil
ifTrue: [ '' ]
ifFalse: [ eachNode header ]];
tags: [:eachNode |
(eachNode tags) isNil
ifFalse: [ (eachNode tags) asSymbol ]
ifTrue: [ #() ] ];
"Nodes Toolbar
=============="
"Adding nodes"
act: [:treePresentation |
(treePresentation selection) isNotNil
ifTrue: [treePresentation selection addNodeAfter].
treePresentation update]
icon: GLMUIThemeExtraIcons glamorousZoomIn
entitled: 'Adicionar nodo';
"Removing nodes"
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [(treePresentation selection parent)
removeNode: treePresentation selection]
ifFalse: [treePresentation entity removeLast].
treePresentation update]
icon: GLMUIThemeExtraIcons glamorousZoomOut
entitled: 'Remover nodo';
"Move nodes in the same hierarchy"
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [treePresentation selection moveBefore].
treePresentation update]
icon: GLMUIThemeExtraIcons glamorousUp
entitled: 'Mover nodo hacia arriba';
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [treePresentation selection moveAfter].
treePresentation update]
icon: GLMUIThemeExtraIcons glamorousDown
entitled: 'Mover nodo hacia abajo';
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [treePresentation selection promote].
treePresentation update]
icon: GLMUIThemeExtraIcons glamorousLeft
entitled: 'Mover nodo hacia la izquierda';
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [treePresentation selection demote].
treePresentation update]
icon: GLMUIThemeExtraIcons glamorousRight
entitled: 'Mover nodo hacia la derecha';
act: [ :treePresentation | treePresentation update ]
icon: GLMUIThemeExtraIcons glamorousRefresh
entitled: 'Actualizar vista del árbol';
act: [self saveWorkingTree]
icon: GLMUIThemeExtraIcons glamorousSave
entitled: 'Guardar árbol';
"Options Menu
============="
"For trees"
act: [self saveToFileUI] entitled: 'Guardar como ...' categorized: 'Arbol';
act: [self saveWorkingTree; exportAsHtml] entitled: 'Exportar como HTML' categorized: 'Arbol';
act: [self saveWorkingTree; exportAsLatex] entitled: 'Exportar como LaTeX' categorized: 'Arbol';
act: [self saveWorkingTree; exportAsPdf] entitled: 'Exportar como PDF' categorized: 'Arbol';
act: [self viewExportedHtml] entitled: 'Ver HTML' categorized: 'Arbol';
act: [self messageNotImplementedYet] entitled: 'Ver PDF' categorized: 'Arbol';
"For nodes"
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [self copyNodeIntoCache: treePresentation selection].
treePresentation update] entitled: 'Copiar nodo' categorized: 'Nodo';
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [self replaceContentsFromCache: treePresentation selection].
treePresentation update] entitled: 'Pegar nodo' categorized: 'Nodo';
"For tags"
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [self addTagTo: treePresentation selection]]
entitled: 'Etiquetar nodo como...' categorized: 'Etiquetas';
act: [:treePresentation |
(treePresentation selection isNotNil)
ifTrue: [
treePresentation selection tagAs: nil.
browser update.
]]
entitled: 'Desetiquetar nodo como...' categorized: 'Etiquetas';
act: [self showTagsAvailable] entitled: 'Ver disponibles' categorized: 'Etiquetas';
act: [self addToTagsAvailable] entitled: 'Agregar a disponibles' categorized: 'Etiquetas'.
]
{ #category : #persistence }
GrafoscopioBrowser >> viewExportedHtml [
"Exports the current tree to HTML, using the same name but different extension (.html)"
| htmlFileLocation |
htmlFileLocation := ((workingFile parent) / workingFile basenameWithoutExtension) fullName, '.html'.
Smalltalk platform name = 'unix'
ifTrue: [OSProcess command: 'xdg-open ', htmlFileLocation].
Smalltalk platform name = 'Win32'
ifTrue: [OSProcess command: 'explorer ', htmlFileLocation].
Smalltalk platform name = 'Mac OS'
ifTrue: [OSProcess command: 'open ', htmlFileLocation].
]