lappend auto_path ..

#---------------
# GnoclEdit.tcl
#
# Simple, plain text editor using gnocl Tcl-Gtk bindings
# Created by William J Giddings
# 29-October-2007
#---------------

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

package require Gnocl

# array to contain some global variables
set GE(text)     ""           ;# name of editor widget
set GE(status)   ""           ;# name of status bar widget
set GE(filename) "untitled"   ;# filename
set GE(basefont) "Courier"    ;# besefont for text display
set GE(fontsize) "12"         ;# default font size in pixels

# array to contain tooltip strings
set TT(new)      "Clear workspace and begin a new document."
set TT(open)     "Clear existing workspace and open an existing file for editing."
set TT(save)     "Save the current, named file to disk."
set TT(saveas)   "Save an untitled file to disk or save a copy with a new name."
set TT(quit)     "Discard current document and close the GnoclEdit program."
set TT(cut)      "Cut the active selection to the clipboard."
set TT(copy)     "Copy the active selection to the clipboard."
set TT(paste)    "Paste the current clipboard into the insertion point or replace selection."
set TT(delete)   "Delete the current selection from the document."
set TT(selall)   "Select all text within the current document."

#
# build the application user interface
#
proc main {} {
	# Step 1) create menus
	# a) file
	set menu [gnocl::menu]
	$menu add [gnocl::menuItem -text "%#New" -tooltip $::TT(new) \
	-onClicked fileNew]
	$menu add [gnocl::menuItem -text "%#Open" -tooltip $::TT(open) \
	-onClicked fileOpen]
	$menu add [gnocl::menuItem -text "%#Save" -tooltip $::TT(save) \
	-onClicked fileSave]
	$menu add [gnocl::menuItem -text "%#SaveAs" -tooltip $::TT(saveas) \
	-onClicked fileSaveAs]
	$menu add [gnocl::menuSeparator]
	$menu add [gnocl::menuItem -text "%#Quit"  -tooltip $::TT(quit) \
		-onClicked exit]

	set file [gnocl::menuItem -text "%__File" -submenu $menu]

	# b) edit
	set menu [gnocl::menu]
	$menu add [gnocl::menuItem -text "%#Cut" -tooltip $::TT(cut) \
		-onClicked cut ]
	$menu add [gnocl::menuItem -text "%#Copy" -tooltip $::TT(copy) \
		-onClicked copy ]
	$menu add [gnocl::menuItem -text "%#Paste" -tooltip $::TT(paste) \
		-onClicked paste ]
	$menu add [gnocl::menuSeparator]
	$menu add [gnocl::menuItem -text "%#Delete" -tooltip $::TT(delete) \
		-onClicked delete ]
	$menu add [gnocl::menuSeparator]
	$menu add [gnocl::menuItem -text "%_Select _All" -tooltip $::TT(delete) \
		-onClicked selectAll -accelerator "<Ctrl>A" ]

	set edit [gnocl::menuItem -text "%__Edit" -submenu $menu]

	# c) about
	set menu [gnocl::menu]
	$menu add [gnocl::menuItem -text "%__About" \
		-tooltip "Show about dialog" \
		-onClicked about ]
	set help [gnocl::menuItem -text "%__Help" -submenu $menu]

	# Step 2) create toolbar
	set toolBar [gnocl::toolBar -style both]
	$toolBar add item -text "%#New" -tooltip $::TT(new) \
		-onClicked fileNew
	$toolBar add item -text "%#Open" -tooltip $::TT(open) \
		-onClicked fileOpen
	$toolBar add item -text "%#Save" -tooltip $::TT(save) \
		-onClicked fileSave
	$toolBar add space
	$toolBar add item -text "%#Cut" -tooltip $::TT(cut) \
		-onClicked cut
	$toolBar add item -text "%#Copy" -tooltip $::TT(copy) \
		-onClicked copy
	$toolBar add item -text "%#Paste" -tooltip $::TT(paste) \
		-onClicked paste

	# Step 3) create text edit area, and default formatting tag
	# No need to add scrollbars or input popumenu, these will be added automatically
	set text [gnocl::text]
	$text tag create default -fontFamily $::GE(basefont) -fontSize $::GE(fontsize)

	# Step 4) create status bar
	set status [gnocl::statusBar]

	# Step 5) create Container and toplevel window, add containter to window
	set box [gnocl::box -orientation vertical -borderWidth 0 -spacing 0]
	set win [gnocl::window -child $box -title "GnoclEdit" -onDelete exit]

	# Step 6) add elements to the container
	$box add [gnocl::menuBar -children [list $file $edit $help]]
	$box add $toolBar
	$box add $text -fill {1 1} -expand 1
	$box add $status

	# Step 7) update globals
	set ::GE(text) $text
	set ::GE(status) $status

	# Step 8) default status
	$::GE(status) push "File: $::GE(filename)"

	# enter the main input loop
	gnocl::mainLoop
}

#---------------
# update the status bar, remind us of the filename!
#---------------
proc statusUpdate {str} { $::GE(status) push "File: $str" }

#---------------
# file menu procs, they speak for themselves
#---------------
proc fileNew {} {
	$::GE(text) erase {0 0} end
	set ::GE(filename) "untitled"
	statusUpdate "untitled"
}

proc fileOpen {} {
	set file [gnocl::fileChooser \
		-action open \
		-title "Please choose a file to edit.."]

	if { $file != "" } {
		set fp [open $file "r"]
		set data [read $fp]
		close $fp
		$::GE(text) erase {0 0} end
		$::GE(text) insert end $data -tags default
		statusUpdate $file
		set ::GE(filename) $file
	}
}

proc fileSaveAs {} {
	set file [gnocl::fileChooser \
		-action save \
		-title "Please choose a file to save.."]

	if { $file != "" } {
		set fp [open $file "w"]
		set data [$::GE(text) get {0 0} end-1]
		puts $fp $data
		close $fp
		statusUpdate $file
		set ::GE(filename) $file
	}
}

proc fileSave {} {
	if {$::GE(filename) != "untitled" } {
		set fp [open $::GE(filename) "w"]
		set data [$::GE(text) get {0 0} end-1]
		puts $fp $data
		close $fp
		return
	} else {
		fileSaveAs
	}
}

#---------------
# clipboard operations
#---------------
proc cut {} {
	gnocl::clipboard clear
	gnocl::clipboard setText [$::GE(text) get selectionStart selectionEnd ]
	$::GE(text) erase selectionStart selectionEnd
}

proc paste {} {
	$::GE(text) erase selectionStart selectionEnd
	$::GE(text) insert cursor [gnocl::clipboard getText] -tags default
}

proc copy {} { gnocl::clipboard setText [$::GE(text) get selectionStart selectionEnd ] }

proc delete {} { $::GE(text) erase selectionStart selectionEnd }

proc selectAll {} { $::GE(text) select {0 0} end-1 }

#---------------
# about box
#---------------
proc about {} { gnocl::dialog -type info -text "GnoclEdit by\nWilliam J Giddings\n29-Oct-2007" }

# RUN THE APP!
main
