I decided to adapt my small text editor to the behaviour design pattern suggested in a previous question. It was soon clear how the behaviour design could help scale my little project by allowing adding key combinations to call the opening, saving actions and so on.
However, this design mainly uses classes and I am not sure how to make the classes communicate. A new class was added to handle saving the current file (SaveFile), but I am not being able to capture the URI of the current file (that was taken with the DocumentFileSelector class).
My suspicion is that the way to do that is through class properties, but I am not being able to actually make the document_selector variable inherit that property, so I could pass it to the SaveDocument class.
Here is the relevant part of the code:
uses
Gtk
init
Intl.setlocale()
Gtk.init (ref args)
var document = new Text( "Lorem Ipsum" )
var header = new Header ( "My text editor" )
var body = new DocumentView( document )
var editor = new EditorWindow (header,body )
var document_selector = new DocumentFileSelector( editor )
var load_new_content_command = new Load( document, document_selector )
var create_new = new CreateNew( document )
var save_file = new SaveFile( document )
header.add_item( new OpenButton( load_new_content_command ) )
header.add_item( new CreateNewButton ( create_new ) )
header.add_item( new SaveFileButton( save_file ))
editor.show_all ()
Gtk.main ()
class EditorWindow:Window
construct( header:Header, body:DocumentView )
this.window_position = WindowPosition.CENTER
this.set_default_size( 400, 400 )
this.destroy.connect( Gtk.main_quit)
this.set_titlebar(header)
var box = new Box (Gtk.Orientation.VERTICAL, 1)
box.pack_start(body, true, true, 0)
this.add(box)
class Header:HeaderBar
construct( title:string = "" )
this.show_close_button = true
this.set_title( title )
def add_item( item:Widget )
this.pack_start( item )
class SaveFileButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-save",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class OpenButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-open",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class CreateNewButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-new",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class DocumentView:ScrolledWindow
construct( document:TextBuffer )
var view = new TextView.with_buffer( document )
view.set_wrap_mode( Gtk.WrapMode.WORD )
this.add( view )
interface Command:Object
def abstract execute()
interface DocumentSelector:Object
def abstract select():bool
def abstract get_document():string
class Text:TextBuffer
construct ( initial:string = "" )
this.text = initial
class SaveFile:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents (_filename, _receiver.get_text(start, end,
false))
except ex : FileError
print "%s\n", ex.message
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
class Load:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector )
_receiver = receiver
_document_selector = document_selector
def execute()
if _document_selector.select()
_receiver.text = _document_selector.get_document()
class CreateNew:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
var should_I_save=new MessageDialog (null, Gtk.DialogFlags.MODAL,
Gtk.MessageType.INFO, Gtk.ButtonsType.YES_NO, "Hello world!")
should_I_save.format_secondary_text (
"This will delete the contets. Are you sure?")
case should_I_save.run()
when ResponseType.YES
_receiver.set_text("")
should_I_save.destroy ()
when ResponseType.NO
should_I_save.destroy ()
How to pass the URI information from the last file opened to the SaveDocument class?
As an extra question, the first line after the construct of each class is doing what? The lines that read like:
construct( parent:Window )
_parent = parent
Edit
Still couldn't solve the problem, something I recently tried was to create another method inside DocumentFileSelector class called whichFile(). This method would only return the uri. I am getting the error at execution: FileUtils.set_contents ( DocumentFileSelector.whichFile(), _receiver.get_text(start, end,false))
.
And here are the modifications to the code:
class SaveFile:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents ( DocumentFileSelector.whichFile(), _receiver.get_text(start, end,false))
except ex : FileError
print "%s\n", ex.message
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def whichFile():string
return _uri
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
You're almost there ...
Just add a reference to the DocumentSelector
to your SaveFile
command as you did for the LoadFile
command:
class SaveFile:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector)
_receiver = receiver
_document_selector = document_selector
You can then invoke your new whichFile()
method on the saved DocumentSelector
:
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents (_document_selector.whichFile(), _receiver.get_text(start, end,
false))
except ex : FileError
print "%s\n", ex.message