#!/usr/bin/python3
########  Craftsman CNC Controller   #########
####     Creator: Piet van Rensburg      #####
####     Company: Craftsman CNC          #####
####      wwww.craftsmancnc.com.au       #####
##############################################

import pygtk
pygtk.require("2.0")
import gtk
import pango
import gobject
import gladevcp.makepins
from gladevcp.gladebuilder import GladeBuilder
import hal
from gladevcp.hal_filechooser import *
import sys,os

sys.path.append('./')
sys.path.append('./screens/')
# set up paths to files
BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
libdir = os.path.join(BASE, "lib", "python")
sys.path.insert(0, libdir)
datadir = os.path.join(BASE, "share", "linuxcnc")

xmlname = os.path.join('./',"craftsmancnc.glade")


import time
import linuxcnc
import easygui
import subprocess
import webbrowser
import threading

import ConfigParser_New

import globals
import estimate_time
import traceback


from rs274.glcanon import GLCanon, GlCanonDraw

keynames = ['KP_Enter',  'Return',  'Left',  'Right',  'Up',  'Down',  'Delete',  'Home',  'End',  'Page_Up',  'Page_Down',  'Tab',  'BackSpace',  'KP_Up',  'KP_Down',  'KP_8',  'KP_2']

def exception_format(e):
	info = "".join(traceback.format_tb(sys.exc_info()[2]))
	return str(e) + "\n\n" + info        
	
	#used like this
	#try:
	#	......
	#except Exception, e:
	#	easygui.msgbox(exception_format(e), title="Exception")
	
def _message_(message):
	globals.ops_message(message)
	
k = 0
key_exsist = False

class craftsman(object):   
    ######show screens#########
	def show_screen1(self, widget, arg):
		self.change_focus()
		self.builder.get_object("notebook1").set_current_page(0)    
		
       
	def show_screen2(self, widget, arg):
		self.change_focus()
		self.builder.get_object("notebook1").set_current_page(1) 

	def show_screen3(self, widget, arg):
		self.change_focus()
		self.builder.get_object("notebook1").set_current_page(2)
		self.lc.mode(linuxcnc.MODE_MANUAL)

	def show_screen4(self, widget, arg):
		self.change_focus()
		self.builder.get_object("notebook1").set_current_page(3) 
		     
	def show_screen5(self, widget, arg):
		self.change_focus()
		self.builder.get_object("notebook1").set_current_page(4)      

	def show_screen6(self, widget, arg):
		self.change_focus()
		self.builder.get_object("notebook1").page = 5     
	
	def show_screen8(self, widget, arg):
		self.change_focus()
		url = './screens/gcodes.htm'
		webbrowser.open_new_tab(url)

	def show_screen9(self, widget, arg):
		self.change_focus()
		url = './screens/mcodes.htm'    	
		webbrowser.open_new_tab(url)
		
	##### cycle operations #####
	def cycle_start(self, widget, arg):
		self.change_focus()					
		if self.check_machine_state() == 'STATE_ON':				
			if self.line_number > 0:
				self.gcode_runfrom(widget, '')	
				_message_('Program restarted....')
			else:
				self.lc.mode(linuxcnc.MODE_AUTO)
				self.counter = 0
				self.builder.get_object("hal_toggleaction_run").set_restart_line(self.line_number )
				self.builder.get_object("hal_toggleaction_pause").set_active(False)
				self.builder.get_object("hal_toggleaction_run").set_active(True)				
				self.timer_set = True	
				self.prog_running = True
				_message_('Program started....')	
			globals.tool_changed()	
			self.program_paused = False		
		else : 
			gtk.gdk.beep()

	def cycle_pause(self, widget, arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':			
			self.line_number = self.builder.get_object("hal_sourceview1_1").get_line_number()
			self.builder.get_object("hal_toggleaction_pause").set_active(True)
			_message_('Program paused....')			
			self.timer_set = False
			self.program_paused = True
		else : 
			gtk.gdk.beep()
		
	def cycle_stop(self, widget, arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			self.status.poll()
			curr_line = self.status.current_line
			self.builder.get_object("hal_toggleaction_stop").set_active(True)
			self.lc.mode(linuxcnc.MODE_MANUAL)
			self.counter = 0
			self.timer_set = False
			self.line_number  = str(curr_line)
			#globals.tool_change('0')
			_message_('Program stopped....')
		else : 
			gtk.gdk.beep()
	
	##### gcode operations #####
	def gcode_load(self, widget, arg):
		self.change_focus()
		self.lc.mode(linuxcnc.MODE_MDI)
		self.lc.wait_complete()
		self.lc.mode(linuxcnc.MODE_AUTO)
		self.lc.wait_complete()
		self.builder.get_object("hal_action_open").activate()            		
		self.gremlin_init()
		self.status.poll()
		self.builder.get_object("messagelabel1_2").set_text(self.status.file)
		globals.add_history(self.status.file)
		self.lc.mode(linuxcnc.MODE_MANUAL)	
		gobject.timeout_add_seconds(2, self.set_extents)		
		_message_('Loaded: ' + self.status.file)

	def gcode_history(self, widget, arg):
		self.change_focus()
		texttagtable = gtk.TextTagTable()
		self.textbuffer = gtk.TextBuffer(texttagtable)

		self.file_hist_view = self.builder.get_object("file_hist_view")
		file = open("history.dat", "r")
		self.textbuffer.set_text(file.read())
		file.close()
		
		self.file_hist_view.set_buffer(self.textbuffer)
		
		self.history_dialog.show_all()
		if self.history_dialog.run() == gtk.RESPONSE_OK: #ACCEPT:
			pass
		self.history_dialog.hide()
		

	def gcode_edit(self,  widget,  arg):
		self.change_focus()
		_message_('Gcode file is being edited....')
		self.status.poll()
		os.system('gedit --new-window "' +  self.status.file + '"&')
		self.builder.get_object("hal_action_reload").activate()
		self.lc.mode(linuxcnc.MODE_MANUAL)
		_message_('Gcode file was edited....')
	
	def gcode_close(self, widget, arg):
		self.change_focus()
		self.builder.get_object("hal_sourceview1_1").load_file('')
		self.builder.get_object("hal_gremlin1"). _load('blank.ncc')
		self.builder.get_object("gcode_line1").set_text('0')
		self.lc.mode(linuxcnc.MODE_MANUAL)
		### update entry with file name
		self.gremlin_init()
		self.builder.get_object("messagelabel1_2").set_text('No file loaded')
		_message_('Gcode file closed....')
	
	def gcode_rewind(self,  widget,  arg):	
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			globals.tool_changed()
			self.builder.get_object("hal_action_reload").activate()
			self.lc.mode(linuxcnc.MODE_MANUAL)
			#self.builder.get_object("gcode_line1").set_text('0')
			self.line_number  = 0
			_message_('Gcode file rewinded....')
		else : 
			gtk.gdk.beep()
	
	def gcode_l(self, widget, arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			self.line_number  = int(widget.get_text())
			self.builder.get_object("hal_sourceview1_1").set_line_number (self.line_number )
			_message_('Gcode start from line....')
		else : 
			gtk.gdk.beep()
	
	def gcode_runfrom(self, widget, arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':			
			try:
				self.line_number  = int(self.builder.get_object("gcode_line1").get_text())
				self.timer_set = True	
				self.prog_running = True
				self.builder.get_object("hal_toggleaction_run").set_restart_line(self.line_number )
				self.builder.get_object("hal_toggleaction_pause").set_active(False)
				self.builder.get_object("hal_toggleaction_run").set_active(True)
			except Exception,  e:
				easygui.msgbox(exception_format(e), title="VFD Exception")
			_message_('Gcode started from line....')
		else : 
			gtk.gdk.beep()
	
	#### zero dro's ####
	def zero_x_dro(self,  widget,  arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			self.call_mdi('G92 X0')			
		else : 
			gtk.gdk.beep()

	def zero_y_dro(self,  widget,  arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			self.call_mdi('G92 Y0')

	def zero_z_dro(self,  widget,  arg):
		self.change_focus()		
		if self.check_machine_state() == 'STATE_ON':
			self.call_mdi('G92 Z0')

	def zero_a_dro(self,  widget,  arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			self.call_mdi('G92 A0')
	
	###############
	### feed overrides ###
	def overide_reset(self,  widget,  arg):
		self.set_label_text('feed_label',  3,  '100')
		self.feed_overide = float(self.builder.get_object("feed_label1_3").get_text())
		self.lc.set_feed_override(0)
		self.lc.feedrate(1)		
		self.change_focus()
	
	def overide_inc(self,  widget,  arg):
		self.set_label_text('feed_label',  3,  '%.0f' % (float(self.builder.get_object("feed_label1_3").get_text()) + 10))
		self.feed_overide = float(self.builder.get_object("feed_label1_3").get_text())
		self.lc.set_feed_override(1)
		self.lc.feedrate(float(self.feed_overide)/100)
		self.change_focus()
	
	def overide_dec(self,  widget,  arg):
		if float(self.builder.get_object("feed_label1_3").get_text()) - 10 >= 10:
			self.set_label_text('feed_label',  3,  '%.0f' % (float(self.builder.get_object("feed_label1_3").get_text()) - 10))
			self.feed_overide = float(self.builder.get_object("feed_label1_3").get_text())
			self.lc.set_feed_override(1)
			self.lc.feedrate(float(self.feed_overide)/100)
		self.change_focus()
	####################
	### spindle overrides ###
	def spindle_reset(self,  widget,  arg):
		self.set_label_text('spindle_label',  2,  '100')
		self.spindle_speedoveride =  float(self.builder.get_object("spindle_label1_2").get_text())
		self.lc.set_spindle_override(0)
		self.lc.spindleoverride(0)	
		self.change_focus()
	
	def spindle_up(self,  widget,  arg):
		self.set_label_text('spindle_label',  2,  '%.0f' % (float(self.builder.get_object("spindle_label1_2").get_text()) + 10))
		self.spindle_speedoveride =  float(self.builder.get_object("spindle_label1_2").get_text())
		self.lc.set_spindle_override(1)
		self.lc.spindleoverride(self.spindle_speedoveride/100)	
		self.change_focus()
	
	def spindle_down(self, widget, arg):
		if float(self.builder.get_object("spindle_label1_2").get_text()) - 10 >= 10:
			self.set_label_text('spindle_label',  2,  '%.0f' % (float(self.builder.get_object("spindle_label1_2").get_text()) - 10))
			self.spindle_speedoveride =  float(self.builder.get_object("spindle_label1_2").get_text())
			self.lc.set_spindle_override(1)
			self.lc.spindleoverride(self.spindle_speedoveride/100)
		self.change_focus()		

	def spindle_speed_changed(self,  widget,  arg):
		keystr = arg.string 
		keytype = gtk.gdk.keyval_name(arg.keyval)
		keys = ['0','1','2','3','4','5','6','7','8','9',  '+',  '-',   '.'] 
		if keystr not in keys and keytype not in keynames :
			widget.delete_text(widget.get_position()-1, widget.get_position())
			
		if key_exsist:
			widget.delete_text(widget.get_position()-1, widget.get_position())
			
		if  keytype =='KP_Enter' or keytype == 'Return':
			if widget == self.builder.get_object('spindle_label2_1'):
				self.builder.get_object('spindle_label1_1').set_text(widget.get_text())
			if widget == self.builder.get_object('spindle_label1_1'):
				self.builder.get_object('spindle_label2_1').set_text(widget.get_text())
			self.change_focus()

	####################
	### spindle control ####
	def spindle_control_press(self,  widget,  arg):
		if self.spindle_controller:
			self.spindle_controller = False
			globals.set_spindledata('0')
		else:
			self.spindle_controller = True
			globals.set_spindledata('1')
		self.change_focus()	
		
	def spindle_on(self,  widget,  arg):
		if self.spindle_controller:
			if self.status.spindle[0]['enabled'] == 0:	
				sp_speed = self.builder.get_object('spindle_label1_1').get_text()
				try:
					sp_sp = float(sp_speed)
					if sp_sp < 3000:
						sp_speed = '3000'
				except:
					sp_speed = '3000'
				self.call_mdi('M3 S' + sp_speed) #3000')
			else:
				self.call_mdi('M5')
		self.change_focus()
	####################
	### gremlin settings ###
	def gremlin_p(self,  widget,  arg):
		gremlin = self.builder.get_object('hal_gremlin' +  gtk.Buildable.get_name(widget.parent)[-1:]) 				
		gremlin.set_property('view', 'p')
		self.change_focus()
	
	def gremlin_x(self,  widget,  arg):
		gremlin = self.builder.get_object('hal_gremlin' +  gtk.Buildable.get_name(widget.parent)[-1:]) 			
		gremlin.set_property('view', 'x')
		self.change_focus()

	def gremlin_y(self,  widget,  arg):
		gremlin = self.builder.get_object('hal_gremlin' +  gtk.Buildable.get_name(widget.parent)[-1:]) 			
		gremlin.set_property('view', 'y')
		self.change_focus()

	def gremlin_z(self,  widget,  arg):
		gremlin = self.builder.get_object('hal_gremlin' +  gtk.Buildable.get_name(widget.parent)[-1:]) 			
		gremlin.set_property('view', 'z')	
		self.change_focus()

	def gremlin_z2(self,  widget,  arg):
		gremlin = self.builder.get_object('hal_gremlin' +  gtk.Buildable.get_name(widget.parent)[-1:]) 			
		gremlin.set_property('view', 'z2')	
		self.change_focus()

	def gremlin_zoom_in(self, widget, arg):
		gremlin = self.builder.get_object('hal_gremlin' +  gtk.Buildable.get_name(widget.parent)[-1:])
		gremlin.zoom_in()
		self.change_focus()

	def gremlin_zoom_out(self,  widget, arg):
		gremlin = self.builder.get_object('hal_gremlin' +  gtk.Buildable.get_name(widget.parent)[-1:])
		gremlin.zoom_out()
		self.change_focus()
	
	def gremlin_init(self):		
		##self.builder.get_object("hal_gremlin1").clear_live_plotter()
		##self.builder.get_object("hal_gremlin2").clear_live_plotter()
		##self.builder.get_object("hal_gremlin3").clear_live_plotter()
		##self.builder.get_object('hal_gremlin1').set_property('view', 'p') 
		##self.builder.get_object('hal_gremlin2').set_property('view', 'p') 
		##self.builder.get_object('hal_gremlin3').set_property('view', 'p')
		self.change_focus()
		
	####################
	def overide_limits(self,  widget,  arg):
		if self.machine_overide_limits:
			self.machine_overide_limits = False
			self.lc.mode(self.linuxcnc.MODE_MANUAL)
			self.lc.override_limits()
		else:
			self.machine_overide_limits = True
			self.lc.mode(self.linuxcnc.MODE_MANUAL)
			self.lc.override_limits()
		self.change_focus()

	def mach_coords(self,  widget,  arg):
		if self.machine_coords:
			self.machine_coords = False
		else:
			self.machine_coords = True
		self.change_focus()
	
	def soft_limits_on(self, widget, arg):
		self.soft_limits = True
		self.change_focus()	
	####################	
		
	def time_estimate(self, widget, arg):
		estimate_time.read_gcodefile(self.status.file)
		self.builder.get_object('time_label3_1').set_text(estimate_time.calculated_time)
	####################
	
	def jog_on(self,  widget,  arg):
		if not self.jog:
			self.jog = True			
		else: 
			self.jog = False

	def jog_x_plus_press(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 0, float(self.x_jog))
	
	def jog_x_minus_press(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 0, -float(self.x_jog))
	
	def jog_x_release(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_STOP, 1, 0)
	
	def jog_y_plus_press(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 1, float(self.y_jog))
	
	def jog_y_minus_press(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 1, -float(self.y_jog))
	
	def jog_y_release(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_STOP, 1, 1)

	def jog_z_plus_press(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 2, float(self.z_jog))
	
	def jog_z_minus_press(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 2, -float(self.z_jog))
	
	def jog_z_release(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_STOP, 1, 2)	

	def jog_a_plus_press(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 3, float(self.a_jog))
	
	def jog_a_minus_press(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 3, -float(self.a_jog))
	
	def jog_a_release(self, widget, event):
		if self.check_machine_state() == 'STATE_ON':
			self.lc.jog(self.linuxcnc.JOG_STOP, 1, 3)

	def ops_reset(self,  widget,  arg):	
		self.change_focus()
		_message_(self.check_machine_state())
		self.status.poll()
		curr_line = self.status.current_line	
		try:			
			if self.status.task_state >= 1 and  self.status.task_state <= 3 :		
				self.builder.get_object("hal_toggleaction_estop").set_active(False)
				self.builder.get_object("hal_toggleaction_power").set_active(True)	
				self.lc.mode(linuxcnc.MODE_MANUAL)
				self.timer_set = False
				self.set_ops_leds(4,  4,   True)
				_message_('Machine switched ON....')
			else :
				self.builder.get_object("hal_toggleaction_power").set_active(False)
				self.builder.get_object("hal_toggleaction_estop").set_active(True)				
				self.set_ops_leds(1,  4,   False)
				self.counter = 0
				self.timer_set = False
				_message_('Machine switched OFF....')		
			self.statusbar.push(0, '')
			self.line_number  = str(curr_line)
			#globals.tool_change('0')
		except Exception, e:
			easygui.msgbox(exception_format(e), title="Exception")

	def set_ops_leds(self,  from_no,  to_no,   arg):
		for i in range(1,self.screen_count):
			if self.builder.get_object("layout" + str(i)):
				for j in range(from_no, to_no + 1):
					if self.builder.get_object("ophal_led" + str(i) + "_" + str(j)):
						self.builder.get_object("ophal_led" + str(i) + "_" + str(j)).set_active(arg)						
	
	def set_label_text(self, label, no,  txt):
		for i in range(1,self.screen_count):
			if self.builder.get_object("layout" + str(i)):
				if self.builder.get_object(label + str(i) + "_" + str(no)): 
					self.builder.get_object(label + str(i) + "_" + str(no)).set_text(txt)
	
	#### macro buttons ####
	def home_xy(self, widget, arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Homing X and Y axis.......')
			self.status.poll()
			self.call_mdi('G92 x' + '%0.3f' % self.status.actual_position[0] + ' y' + '%0.3f' % self.status.actual_position[1])
			self.call_mdi('M103')
			self.lc.mode(self.linuxcnc.MODE_MANUAL)
			self.lc.home(-1)
			self.change_focus()
		else : 
			gtk.gdk.beep()
	
	def home_x(self, widget, arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Homing X axis.......')
			self.status.poll()
			self.call_mdi('G92 x' + '%0.3f' % self.status.actual_position[0])
			self.call_mdi('M103')
			self.lc.mode(self.linuxcnc.MODE_MANUAL)
			self.lc.home(0)
			self.change_focus()
		else : 
			gtk.gdk.beep()
	
	def home_y(self, widget, arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Homing Y axis.......')
			self.status.poll()
			self.call_mdi('G92 y' + '%0.3f' % self.status.actual_position[1])
			self.call_mdi('M103')
			self.lc.mode(self.linuxcnc.MODE_MANUAL)
			self.lc.home(1)
			self.change_focus()
		else : 
			gtk.gdk.beep()
			
	def home_z(self, widget, arg):	
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Homing Z axis.......')
			self.status.poll()
			self.call_mdi('G92 z' +  '%0.3f' % self.status.actual_position[2])				
			self.lc.mode(self.linuxcnc.MODE_MANUAL)
			self.lc.home(2)
			self.change_focus()
		else : 
			gtk.gdk.beep()
			
	def home_a(self, widget, arg):	
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Homing A axis.......')
			self.status.poll()
			self.call_mdi('G92 a' +  '%0.3f' % self.status.actual_position[3])				
			self.lc.mode(self.linuxcnc.MODE_MANUAL)
			self.lc.home(3)
			self.change_focus()
		else : 
			gtk.gdk.beep()
	
	def goto_zero(self, widget, arg):
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			self.call_mdi('o<m106> call')
			self.change_focus()
		else : 
			gtk.gdk.beep()
	
	def touch_z(self, widget, arg):	
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			try:			
				#####to zero axis with button####
				if  self.builder.get_object("messagelabel1_1").get_text().find('Insert tool' ) < 0:
					_message_('Touching Z axis.......')
				self.call_mdi('o<m101> call')
				self.change_focus()
			except Exception, e:
				easygui.msgbox(exception_format(e), title="Exception")
		else : 
			gtk.gdk.beep()
			
	def touch_x_minus(self, widget, arg):	
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Touching X axis in the negative direction....')
			self.call_mdi('o<m102> call')
			self.change_focus()			
		else : 
			gtk.gdk.beep()
			
	def touch_x_plus(self, widget, arg):	
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Touching X axis in the positive direction....')
			self.call_mdi('o<m103> call')			
			self.change_focus()			
		else : 
			gtk.gdk.beep()
			
	def touch_y_minus(self, widget, arg):	
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Touching Y axis in the negative direction....')
			self.call_mdi('o<m104> call')
			self.change_focus()			
		else : 
			gtk.gdk.beep()
			
	def touch_y_plus(self, widget, arg):	
		self.change_focus()
		if self.check_machine_state() == 'STATE_ON':
			_message_('Touching Y axis in the positive direction....')
			self.call_mdi('o<m105> call')			
			self.change_focus()			
		else : 
			gtk.gdk.beep()

	def call_mdi(self, mdi_command):
		self.builder.get_object("action_mdi").command = mdi_command
		self.builder.get_object("action_mdi").activate()
	
	def source_down(self, widget, arg):
		line = globals.get_clicked_line(widget)
		self.builder.get_object("hal_sourceview1_1").set_line_number (line+1)
		self.builder.get_object("hal_sourceview3_1").set_line_number (line+1)
		self.builder.get_object("hal_gremlin1").set_highlight_line(line)
		self.builder.get_object("hal_gremlin2").set_highlight_line(line)
		self.builder.get_object("hal_gremlin3").set_highlight_line(line)
		
	def source_key_down(self, widget,  arg):
		keytype = gtk.gdk.keyval_name(arg.keyval)
		#line = self.builder.get_object("hal_sourceview1_1").get_line_number()
		line = widget.get_line_number()
		if keytype == 'Up' or keytype == 'KP_8' or keytype == 'KP_Up':
			self.builder.get_object("hal_sourceview1_1").set_line_number(line-1)
			self.builder.get_object("hal_sourceview3_1").set_line_number(line-1)
			self.builder.get_object("hal_gremlin1").set_highlight_line(line-1)
			self.builder.get_object("hal_gremlin2").set_highlight_line(line-1)
			self.builder.get_object("hal_gremlin3").set_highlight_line(line-1)
		if keytype == 'Down' or keytype == 'KP_2' or keytype == 'KP_Down':
			self.builder.get_object("hal_sourceview1_1").set_line_number(line+1)
			self.builder.get_object("hal_sourceview3_1").set_line_number(line+1)
			self.builder.get_object("hal_gremlin1").set_highlight_line(line+1)
			self.builder.get_object("hal_gremlin2").set_highlight_line(line+1)
			self.builder.get_object("hal_gremlin3").set_highlight_line(line+1)
	
	
	def source_key_up(self, widget,  arg):
		_message_('t4')

	def self_key_press(self,  widget,  arg):
		keystr = arg.string 
		keytype = (gtk.gdk.keyval_name(arg.keyval))
		if self.check_machine_state() == 'STATE_ON':			
			if keytype in keynames :
				if self.jog:
					if keytype == 'Up':
						self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 0, -float(self.x_jog))
					if keytype == 'Down':
						self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 0, float(self.x_jog))
					if keytype == 'Left':
						self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 1, -float(self.y_jog))
					if keytype == 'Right':
						self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 1, float(self.y_jog))
					if keytype == 'KP_8' or keytype == 'KP_Up':
						self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 2, float(self.z_jog))
					if keytype == 'KP_2' or keytype == 'KP_Down':
						self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 2, -float(self.z_jog))
					if keytype == 'Page_Up':
						self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 3, float(self.a_jog))
					if keytype == 'Page_Down':
						self.lc.jog(self.linuxcnc.JOG_CONTINUOUS, 1, 3, -float(self.a_jog))
				else:
					gtk.gdk.beep()
					self.change_focus()	
			elif keytype.lower() == 'Escape':
				self.builder.get_object("hal_toggleaction_estop").set_active(True)
				self.builder.get_object("hal_toggleaction_power").set_active(False)	
			elif keytype.lower() == 'c' and arg.state == gtk.gdk.CONTROL_MASK | gtk.gdk.MOD2_MASK:
				self.cycle_start(widget,  arg)
			elif keytype.lower() == 'p' and arg.state == gtk.gdk.CONTROL_MASK | gtk.gdk.MOD2_MASK:
				self.cycle_pause(widget,  arg)
			elif keytype == 'space':
				self.cycle_pause(widget,  arg)
			elif keytype.lower() == 's' and arg.state == gtk.gdk.CONTROL_MASK | gtk.gdk.MOD2_MASK:
				self.cycle_stop(widget,  arg)
			elif keytype.lower() == 'r' and arg.state == gtk.gdk.CONTROL_MASK | gtk.gdk.MOD2_MASK:
				self.ops_reset(widget,  arg)
			elif keytype == 'F1':
				self.show_shortcuts(widget, arg)
		elif keytype == 'Escape':
			self.builder.get_object("hal_toggleaction_estop").set_active(True)
			self.builder.get_object("hal_toggleaction_power").set_active(False)	
		elif keytype == 'F1':
			self.show_shortcuts(widget, arg)
		elif keytype.lower() == 'r' and arg.state == gtk.gdk.CONTROL_MASK | gtk.gdk.MOD2_MASK:
			self.ops_reset(widget,  arg)
		else : 
			gtk.gdk.beep()
		return True
	
	def self_key_release(self,  widget,  arg):
		if self.check_machine_state() == 'STATE_ON':
			keystr = arg.string 
			keytype = gtk.gdk.keyval_name(arg.keyval)		
			try:			
				if keytype == 'Up' or  keytype == 'Down' :  self.lc.jog(self.linuxcnc.JOG_STOP, 1, 0)
				if keytype == 'Left' or keytype == 'Right': self.lc.jog(self.linuxcnc.JOG_STOP, 1, 1)
				if keytype == 'KP_Up' or keytype == 'KP_Down' or keytype == 'KP_8' or keytype == 'KP_2':	self.lc.jog(self.linuxcnc.JOG_STOP, 1, 2)
				if keytype == 'Page_Up' or keytype == 'Page_Down': self.lc.jog(self.linuxcnc.JOG_STOP, 1, 3)
				
				if keytype == 'Escape': self.lc.state(self.linuxcnc.STATE_ESTOP)				
			except Exception, e:
						easygui.msgbox(exception_format(e), title="Exception")
		
		self.change_focus()	
	
	def dro_key_press(self,  widget,  arg):
		if self.check_machine_state() == 'STATE_ON':
			global key_exsist
			key_exsist = False
			keystr = arg.string 
			
			if keystr in  ['+', '-',  '.']: 
				if widget.get_text().find(keystr) > -1:
					key_exsist = True
		else : 
			gtk.gdk.beep()
	
	def dro_key_release(self,  widget,  arg):
		if self.check_machine_state() == 'STATE_ON':
			keystr = arg.string 
			keytype = gtk.gdk.keyval_name(arg.keyval)
			keys = ['0','1','2','3','4','5','6','7','8','9',  '+',  '-',   '.'] 
			if keystr not in keys and keytype not in keynames :
				widget.delete_text(widget.get_position()-1, widget.get_position())
			
			if key_exsist:
				widget.delete_text(widget.get_position()-1, widget.get_position())
			
			if  keytype =='KP_Enter' or keytype == 'Return':
				dro_text = self.builder.get_object(gtk.Buildable.get_name(widget)).get_text()
				dro_no = gtk.Buildable.get_name(widget)				
				for i in range(1, self.screen_count):
					if self.builder.get_object("layout" + str(i)):
						dro = self.builder.get_object(gtk.Buildable.get_name(widget)[:-3] + str(i) + '_1')
						if dro:
							dro.set_text('%.3f' % float(dro_text))
							### set the axis pins####
							if gtk.Buildable.get_name(widget)[0] == 'x':
								self.call_mdi('G92 X' + dro_text)
							if gtk.Buildable.get_name(widget)[0] == 'y':
								self.call_mdi('G92 Y' + dro_text)
							if gtk.Buildable.get_name(widget)[0] == 'z':
								self.call_mdi('G92 Z' + dro_text)
							if gtk.Buildable.get_name(widget)[0] == 'a':
								self.call_mdi('G92 A' + dro_text)		
				self.change_focus()	


	def gcode_key_release(self,  widget,  arg):
		if self.check_machine_state() == 'STATE_ON':
			keystr = arg.string 
			keytype = gtk.gdk.keyval_name(arg.keyval)
			keynames = ['KP_Enter',  'Return',  'Left',  'Right',  'Up',  'Down',  'Delete',  'Home',  'End',  'Page_Up',  'Page_Down',  'Tab',  'BackSpace']
			keys = ['0','1','2','3','4','5','6','7','8','9'] #,  '+',  '-',   '.'] 
			if keystr not in keys and keytype not in keynames :
				widget.delete_text(widget.get_position() - 1, widget.get_position())
			
			if  keytype in ['KP_Enter',  'Return']:
				for i in range(1, self.screen_count):
					if self.builder.get_object("layout" + str(i)):
						gcode = self.builder.get_object(gtk.Buildable.get_name(widget)[:-1] + str(i))
						if gcode:
							gcode.set_text('%.0f' % float(gcode.get_text()))
							####set the line in source editor####
							self.gcode_l(widget,  '')
		
				self.change_focus()	

	def change_focus(self):
		self.builder.get_object("focus_entry").grab_focus()
	
	def show_mdi_history(self, widget, arg):
		self.builder.get_object("hal_mdihistory1").tv.show()
	
	def hide_mdi_history(self, widget, arg):
		if not self.builder.get_object("hal_mdihistory1").tv.has_focus() and not self.builder.get_object("hal_mdihistory1").entry.has_focus():
			self.builder.get_object("hal_mdihistory1").tv.hide()
	
	def mdi_key_release(self, widget, arg):
		if self.check_machine_state() == 'STATE_ON':
			keytype = gtk.gdk.keyval_name(arg.keyval)
			if keytype == 'KP_Enter' or keytype == 'Return' or keytype == 'Escape':
				self.change_focus()	
	
	def show_message(self, message):
		for i in range(1, self.screen_count):
			if self.builder.get_object("layout" + str(i)):
				self.scrnLayout = "layout" + str(i)
				for j in range(1,7):
					if self.builder.get_object("messagelabel" + str(i) + "_1"):
						self.builder.get_object("messagelabel" + str(i) + "_1").set_text(message)

	def check_machine_state(self):
		self.status.poll()
		self.state_code = self.status.task_state
		return self.state[self.status.task_state-1]
	
	def postgui(self):
		inifile = linuxcnc.ini(self.ini_file)
		postgui_halfile = inifile.find("HAL", "POSTGUI_HALFILE")
		return postgui_halfile,sys.argv[2]
	
	def on_show_hal_activate(self, widget, data=None):
		#subprocess.Popen([self.tcl_dir + "halshow.tcl", "-- -ini " + self.ini_file])
		subprocess.Popen(["halshow"])
	
	def show_scope(self, widget, data=None):
		os.system('halscope -- -ini' + self.ini_file + ' &')
	
	def edit_tool_table(self, widget,  arg):
		os.system('tooledit Z DIAM ./tool.tbl &')
		
	def reload_tool_table(self, widget,  arg):
		self.lc.load_tool_table()
	
	def show_about_box(self, widget, event):
		self.builder.get_object('about_label').set_text(self.machine_model)
		self.aboutdialog.show_all()
		if self.aboutdialog.run() == gtk.RESPONSE_CANCEL:
			pass			
		self.aboutdialog.hide()

	def show_shortcuts(self, widget, event):
		self.shortcutdialog.show_all()
		if self.shortcutdialog.run() == gtk.RESPONSE_CANCEL:
			pass			
		self.shortcutdialog.hide()

	def hist_view_clicked(self, widget, arg):
		if arg.type == gtk.gdk._2BUTTON_PRESS:
			self.open_hist_file(widget, arg)
			self.history_dialog.hide()
		
	def open_hist_file(self, widget,  arg):
		data = globals.get_clicked_string(self.file_hist_view)
		self.lc.mode(self.linuxcnc.MODE_AUTO)
		self.lc.program_open(data)		
		globals.add_history(data)
		self.gremlin_init()
		_message_('History file: ' + data)
		gobject.timeout_add_seconds(2, self.set_extents)
		
	def clear_mdi(self, widget, data=None):
		f = open(self.mdi_file, "w")
		f.close()
		self.builder.get_object("hal_mdihistory1").reload()
		_message_('MDI history cleared...')
		
	def clear_offsets(self, widget, data=None):
		self.call_mdi('G92.1')
	
	def set_extents(self):
		try:
			f2 = open('./extents.dat',  'r')
			data = f2.readline()
			data = data.split(',')
			self.set_label_text('x_dro', 3, "%0.3f" % (float(data[0])*25.4))
			self.set_label_text('x_dro', 2, "%0.3f" % (float(data[1])*25.4))
			self.set_label_text('y_dro', 3, "%0.3f" % (float(data[2])*25.4))
			self.set_label_text('y_dro', 2, "%0.3f" % (float(data[3])*25.4))
			self.set_label_text('z_dro', 3, "%0.3f" % (float(data[4])*25.4))
			self.set_label_text('z_dro', 2, "%0.3f" % (float(data[5])*25.4))
			f2.close()
		except: pass
	
	#########main program#########
	def __init__(self, inifile):				
		self.screen_count = 4
		self.linuxcnc = linuxcnc

		self.status = self.linuxcnc.stat()
		self.lc = self.linuxcnc.command()
		
		self.program_paused = True
		
		self.state_code = 0
		self.state = ['STATE_ESTOP','STATE_OFF','STATE_ESTOP_RESET','STATE_ON']
		self.lc.mode(linuxcnc.MODE_MANUAL)
		
		self.tcl_dir = os.environ["LINUXCNC_TCL_DIR"] + "/bin/"
		self.ini_file = os.environ["INI_FILE_NAME"]

		self.builder = gtk.Builder()
		self.builder.add_from_file(xmlname)
		
		self.error_channel = self.linuxcnc.error_channel()
		self.statusbar = self.builder.get_object("statusbar1")
		
		self.halcomp = hal.component("craftsmancnc")
	
		self.builder.connect_signals(self)
		self.window = self.builder.get_object("mainwindow")  
		
		self.window.maximize()
		self.window.show_all() 
		
		self.history_dialog = self.builder.get_object("hist_dialog")
		self.aboutdialog = self.builder.get_object("aboutdialog")
		self.shortcutdialog = self.builder.get_object("shortcutsdialog")
		
		self.screen_h = self.window.get_screen().get_height() - 115
		self.screen_w = self.window.get_screen().get_width()
		self.w_ratio = self.window.get_screen().get_width()/float(1587)
		self.h_ratio = self.screen_h/float(1123)
				
		self.jog = True
		self.timer_set = False
		self.prog_running = False		
		self.gremlin_init()
		self.counter = 0
		
		self.tcl_dir = os.environ["LINUXCNC_TCL_DIR"] + "/bin/"
		self.ini_file = os.environ["INI_FILE_NAME"]
		
		
		self.panel = gladevcp.makepins.GladePanel(self.halcomp, xmlname, self.builder, None)
		self.halcomp.ready()		
		
		self.line_number  = 0
		
		gobject.timeout_add(100, self.periodic) # time between calls to the function, in milliseconds
		self.machine_status = 0
		
		self.builder.get_object("focus_entry").hide()
		self.builder.get_object("power_button").hide()
		self.builder.get_object("estop_button").hide()
		self.builder.get_object("hal_button1").hide()
		
		#scale screens		
		for i in range(1,self.screen_count):
			if self.builder.get_object("screenbg"+ str(i)):
				self._scale_screen_image(self.builder.get_object("screenbg" + str(i)))
				
		for i in range(1,self.screen_count):
			if self.builder.get_object("layout" + str(i)):
				self.scrnLayout = "layout" + str(i)
				
				if i == 1 :
					self._scale_screen_widget(self.builder.get_object("power_button"))
				
				if self.builder.get_object("hal_gremlin" + str(i)):                        
					self._scale_screen_widget(self.builder.get_object("hal_gremlin" + str(i)))
				
				for j in range(1,7):
					if self.builder.get_object("scrnbutton" + str(i) + "_" + str(j)):
						self._scale_screen_widget(self.builder.get_object("scrnbutton" + str(i) + "_" + str(j)))
						self._add_clickabilitiy(self.builder.get_object("scrnbutton" + str(i) + "_" + str(j)))

				for j in range(1,30):
					if self.builder.get_object("opbutton" + str(i) + "_" + str(j)):
						self._scale_screen_widget(self.builder.get_object("opbutton" + str(i) + "_" + str(j)))
						self._add_clickabilitiy(self.builder.get_object("opbutton" + str(i) + "_" + str(j)))
			
				for j in range(1,8):
					if self.builder.get_object("combutton" + str(i) + "_" + str(j)):
						self._scale_screen_widget(self.builder.get_object("combutton" + str(i) + "_" + str(j)))
						self._add_clickabilitiy(self.builder.get_object("combutton" + str(i) + "_" + str(j)))
				
				for j in range(1,5):
					if self.builder.get_object("zero_button" + str(i) + "_" + str(j)):
						self._scale_screen_widget(self.builder.get_object("zero_button" + str(i) + "_" + str(j)))
						self._add_clickabilitiy(self.builder.get_object("zero_button" + str(i) + "_" + str(j)))
			
				for j in range(1,5):
					if self.builder.get_object("control_button" + str(i) + "_" + str(j)):
						self._scale_screen_widget(self.builder.get_object("control_button" + str(i) + "_" + str(j)))
						self._add_clickabilitiy(self.builder.get_object("control_button" + str(i) + "_" + str(j)))

				for j in range(1,9):
					if self.builder.get_object("jogbutton" + str(i) + "_" + str(j)):
						self._scale_screen_widget(self.builder.get_object("jogbutton" + str(i) + "_" + str(j)))
						self._add_clickabilitiy(self.builder.get_object("jogbutton" + str(i) + "_" + str(j)))
				
				for j in range(1,7):
					if self.builder.get_object("gcode_button" + str(i) + "_" + str(j)):
						self._scale_screen_widget(self.builder.get_object("gcode_button" + str(i) + "_" + str(j)))
						self._add_clickabilitiy(self.builder.get_object("gcode_button" + str(i) + "_" + str(j)))

				if self.builder.get_object("gcode_line" + str(i)):                        
					self._scale_screen_widget(self.builder.get_object("gcode_line" + str(i)))
					self.set_dro_props(self.builder.get_object("gcode_line" + str(i)))

				for j in range(1,20):
					if self.builder.get_object("ophal_led" + str(i) + "_" + str(j)):
						self._scale_screen_led(self.builder.get_object("ophal_led" + str(i) + "_" + str(j)))										
						#self._scale_screen_widget(self.builder.get_object("ophal_led" + str(i) + "_" + str(j)))										
			
			
				for j in range(1,8):
					if self.builder.get_object("messagelabel" + str(i) + "_" + str(j)):                        
						self._scale_screen_widget(self.builder.get_object("messagelabel" + str(i) + "_" + str(j)))
				
				for j in range(1,5):
					if self.builder.get_object("feed_label" + str(i) + "_" + str(j)):                        
						self._scale_screen_widget(self.builder.get_object("feed_label" + str(i) + "_" + str(j)))
	
				for j in range(1,4):
					if self.builder.get_object("tool_label" + str(i) + "_" + str(j)):                        
						self._scale_screen_widget(self.builder.get_object("tool_label" + str(i) + "_" + str(j)))

				for j in range(1,3):
					if self.builder.get_object("spindle_label" + str(i) + "_" + str(j)):                        
						self._scale_screen_widget(self.builder.get_object("spindle_label" + str(i) + "_" + str(j)))
						#if j == 1:
						self.set_dro_props(self.builder.get_object("spindle_label" + str(i) + "_" +str(j)))

				for j in range(1,4):
					if self.builder.get_object("x_dro" + str(i) + "_"+str(j)):                        
						self._scale_screen_widget(self.builder.get_object("x_dro" + str(i) + "_"+str(j)))
						self.set_dro_props(self.builder.get_object("x_dro" + str(i) + "_"+str(j)))
				
				for j in range(1,4):
					if self.builder.get_object("y_dro" + str(i) + "_"+str(j)):                        
						self._scale_screen_widget(self.builder.get_object("y_dro" + str(i) + "_"+str(j)))
						self.set_dro_props(self.builder.get_object("y_dro" + str(i) + "_"+str(j)))
				
				for j in range(1,4):
					if self.builder.get_object("z_dro" + str(i) + "_"+str(j)):                        
						self._scale_screen_widget(self.builder.get_object("z_dro" + str(i) + "_"+str(j)))
						self.set_dro_props(self.builder.get_object("z_dro" + str(i) + "_"+str(j)))
				
				for j in range(1,4):
					if self.builder.get_object("a_dro" + str(i) + "_"+str(j)):                        
						self._scale_screen_widget(self.builder.get_object("a_dro" + str(i) + "_"+str(j)))
						self.set_dro_props(self.builder.get_object("a_dro" + str(i) + "_"+str(j)))	
					
				if self.builder.get_object("time_label" + str(i) + "_1" ):                        
					self._scale_screen_widget(self.builder.get_object("time_label" + str(i) + "_1"))
		
				if i == 2:
					self._scale_screen_widget(self.builder.get_object("hal_mdihistory1"))
	
				#sourceview scroll window
				for j in range(1,4): 
					if self.builder.get_object('scrolledwindow'+ str(i) + "_" + str(j)):
						self._scale_screen_widget(self.builder.get_object('scrolledwindow'+ str(i) + "_" + str(j)))
		
		###screen1###

		####screen2###
		self.builder.get_object("hal_mdihistory1").realize()	
		self.builder.get_object("hal_mdihistory1").entry.connect("key-release-event", self.mdi_key_release)
				
		#### Set initial Ops LED state ####
		self.set_ops_leds(1,  4,   False)
		self.set_ops_leds(9,  9,   True)
		
		globals.ensure_mode(self.status,  self.lc, linuxcnc.MODE_MDI)
		self.lc.wait_complete()
		globals.ensure_mode(self.status,  self.lc, linuxcnc.MODE_AUTO)
		self.lc.wait_complete()
		self.lc.program_open('./screens/craftsmancnc.ngc')


		gobject.timeout_add_seconds(1, self.callback)
		
		####Load settings from settings file
		self.load_settings()		
		
		self.builder.get_object("focus_entry").grab_focus()
		self.change_focus()
		
		gobject.timeout_add_seconds(3, self.set_extents)
		globals.tool_changed()
		
	def callback(self):
		if self.timer_set:
			seconds = self.counter
			minutes = seconds // 60
			hours = minutes // 60
			self.set_label_text('time_label',  1, "%02d:%02d:%02d" % (hours, minutes % 60, seconds % 60)) 
			self.counter += 1					
		return True
		pass

	def load_settings(self):		
		config = ConfigParser_New.RawConfigParser() 
		config.read('craftsmancnc.ini')
		##config.read('axis.ini')
		self.x_jog = config.get('AXIS_X', 'MAX_VELOCITY') #,  '80')
		self.y_jog = config.get('AXIS_Y', 'MAX_VELOCITY') #,  '80') #80
		self.z_jog = config.get('AXIS_Z', 'MAX_VELOCITY') #30
		#self.a_jog = config.get('AXIS_A', 'MAX_VELOCITY') #850
		#self.b_jog = config.get('AXIS_4', 'MAX_VELOCITY') #80
		self.machine_model = config.get('EMC', 'MACHINE')
		self.mdi_file = config.get('DISPLAY', 'MDI_HISTORY_FILE')
		
		config.read('cnc_settings.ini')
		self.spindle_controller = config.getboolean('CRAFTSMANCNC_SETTINGS', 'SPINDLE_CONTROL')
		self.machine_coords = config.getboolean('CRAFTSMANCNC_SETTINGS', 'MACHINE_COORDS')
		
		self.set_label_text('messagelabel',  5, self.machine_model) 
		
		self.soft_limits = True
		self.machine_overide_limits = False
		
		self.feed_overide = 100
		self.spindle_speedoveride = 100
		self.tool_dia = 6
		self.tool_length = 50
		self.set_extents()
		globals.get_spindledata()
		globals.clear_log()

	#######Scale widgets########
	def _scale_screen_image(self, screen_image):  
		####screen original size 1587x1123
		new_width = self.window.get_screen().get_width()
		new_height = self.screen_h
		screen_image.set_from_pixbuf(screen_image.get_pixbuf().scale_simple(new_width, new_height, gtk.gdk.INTERP_BILINEAR))
		screen_image.show()
	
	def _scale_screen_led(self, widget):
		self.builder.get_object(self.scrnLayout).move(widget, int(widget.allocation.x  * self.w_ratio), int(widget.allocation.y * self.h_ratio))		
		widget.set_dia(int(widget._dia * self.w_ratio)-1)
	
	def _scale_screen_widget(self, widget):
		#print(gtk.Buildable.get_name(widget))
		self.builder.get_object(self.scrnLayout).move(widget, int(widget.allocation.x  * self.w_ratio), int(widget.allocation.y * self.h_ratio))		
		widget.set_size_request(int(widget.size_request()[0] * self.w_ratio), int(widget.size_request()[1] * self.h_ratio))
	########################### 
	
	def change_hand_cursor(self,  widget,  arg):	
		widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))

	def change_arrow_cursor(self,  widget,  arg):
		widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))
	
	#######Add click event to event boxes(Buttons)########
	def _add_clickabilitiy(self, widget):
		widget.realize()		
		widget.connect("enter_notify_event", self.change_hand_cursor)    
		widget.connect("leave_notify_event", self.change_arrow_cursor)   	

	def set_dro_props(self,  widget):
		if gtk.Buildable.get_name(widget).find("label" ) == -1:		
			font = 'lucida sans unicode  Bold 20'
		else:
			font = 'lucida sans unicode  Bold ' 
		font_desc = pango.FontDescription(font)  
		widget.modify_font(font_desc)
		widget.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("green"))
		widget.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("black")) 
		widget.select_region(0, 0)
			
	def periodic(self): # fetch status items and update screen	
		## poll the status channel		
		self.status.poll()
		if  self.machine_coords:
			data =  self.status.actual_position[0]
		else:
			data =  self.status.actual_position[0] - self.status.g92_offset[0]
		text = "% 0.3f"% (data)
		if not self.builder.get_object("x_dro1_1").has_focus() and not self.builder.get_object("x_dro2_1").has_focus():
			self.set_label_text('x_dro',  1,  text)

		if  self.machine_coords:
			data =  self.status.actual_position[1]
		else:
			data =  self.status.actual_position[1] - self.status.g92_offset[1]			
		text = "% 0.3f"% (data)
		if not self.builder.get_object("y_dro1_1").has_focus() and not self.builder.get_object("y_dro2_1").has_focus():
			self.set_label_text('y_dro',  1,  text)

		if  self.machine_coords:
			data =  self.status.actual_position[2]
		else:
			data =  self.status.actual_position[2] - self.status.g92_offset[2]  
		text = "% 0.3f"% (data)
		if not self.builder.get_object("z_dro1_1").has_focus() and not self.builder.get_object("z_dro2_1").has_focus():
			self.set_label_text('z_dro',  1,  text)
		
		if  self.machine_coords:
			data =  self.status.actual_position[3]
		else:
			data =  self.status.actual_position[3] - self.status.g92_offset[3]  
		text = "% 0.3f"% (data)
		if not self.builder.get_object("a_dro1_1").has_focus() and not self.builder.get_object("a_dro2_1").has_focus():
			self.set_label_text('a_dro',  1,  text)
	
		self.set_label_text('feed_label',  1,  '%.0f' % ((self.status.settings[1] * (float(self.feed_overide)/100))))
		self.set_label_text('feed_label',  2,  ('%.0f' % self.status.settings[1]))
		self.set_label_text('feed_label',  3,  '%.0f' % self.feed_overide)
		self.set_label_text('feed_label',  4, '%.0f' % (self.status.current_vel * 60))
				
		if not self.builder.get_object("spindle_label1_1").has_focus():
			if self.status.spindle[0]['enabled']:
				self.set_label_text('spindle_label',  1,  '%.0f' % (self.status.spindle[0]['speed'] * self.status.spindle[0]['override']))
		self.set_label_text('spindle_label',  2,  '%.0f' % ((float(self.spindle_speedoveride)/100)*100))

		if not self.builder.get_object("gcode_line1").has_focus():
			try:
				self.builder.get_object("gcode_line1").set_text('%.0f' % self.builder.get_object("hal_sourceview1_1").get_line_number ()) 
			except:
				self.builder.get_object("gcode_line1").set_text('0')

		active_codes = []
		for i in self.status.gcodes[1:]:
			if i == -1: continue
			if i % 10 == 0:
				active_codes.append("G%d" % (i/10))
			else:
				active_codes.append("G%(ones)d.%(tenths)d" % {'ones': i/10, 'tenths': i%10})			
		self.builder.get_object("messagelabel1_3").set_text('Codes: ' + ' '.join(active_codes))
				
		data = 'Paused: %.000f' % self.status.paused + ' ' + '   Task: %.000f' % self.status.task_state + '  ' + '    State: %.000f' % self.status.state #exec_state
		self.set_label_text('messagelabel',  4, data)
		if self.status.state == 1 or self.status.state == 3: self.lc.mode(linuxcnc.MODE_MANUAL)
						
		try: globals.get_tooldata() 
		except: pass
		try: self.set_label_text('tool_label',  1,  globals.tool) 
		except: self.set_label_text('tool_label',  1, '%.0f' % self.status.tool_in_spindle)
		try: self.set_label_text('tool_label',  2, globals.diameter)		
		except: self.set_label_text('tool_label',  2,  '0')
		try: self.set_label_text('tool_label',  3, globals.length)  
		except: self.set_label_text('tool_label',  3,  '0')
		

		##Reset LED
		if self.status.task_state == 4:
			self.set_ops_leds(4, 4, True)
		else: 
			self.set_ops_leds(4, 4, False)

	
		##E-Stop LED
		if self.status.task_state == 1 or self.status.task_state == 2:
			self.set_ops_leds(1, 3, True)
		else: 
			self.set_ops_leds(1, 3, False)
		
		##Overide limits LED			
		#if self.machine_overide_limits:		
		if self.status.joint[0]['override_limits'] != 0:
			self.set_ops_leds(5,  5,   True)
			self.machine_overide_limits = True			
		else:
			self.set_ops_leds(5,  5,   False)
			self.machine_overide_limits = False

		##Soft limits LED			
		if self.soft_limits:		
			self.set_ops_leds(6,  6,   True)			
		else:
			self.set_ops_leds(6,  6,   False)

		##Soft limits LED
		if self.machine_coords:	
			self.set_ops_leds(7,  7,   True)
		else:
			self.set_ops_leds(7,  7,   False)

		##Delay LED
		if self.status.delay_left > 0 or self.status.paused == 1:			
			self.set_ops_leds(9,  9,   True)
		else:
			self.set_ops_leds(9,  9,   False)

		##Jog LED
		self.set_ops_leds(8, 8, self.jog)

		##CV Mode LED
		if 'G64' in self.builder.get_object("messagelabel1_3").get_text():
			self.set_ops_leds(10, 10, True)
		else:
			self.set_ops_leds(10, 10, False)

		##Feed LED
		if self.status.feedrate != 1 :
			self.set_ops_leds(11,  11,   True)
		else:
			self.set_ops_leds(11,  11,   False)

		self.show_message(open('messages', 'rb').read())
		##Tool change LED
		if  self.builder.get_object("messagelabel1_1").get_text().find('Insert tool' ) != -1:
			self.set_ops_leds(12,  12,   True)
			self.program_paused = True
		else:
			self.set_ops_leds(12,  12,   False)
			self.program_paused = False

		##Spindle Control LED
		if self.spindle_controller:		
			self.set_ops_leds(13,  13,   True)
		else:
			self.set_ops_leds(13,  13,   False)

		##Spindle On LED
		globals.get_spindledata()
		if self.status.spindle[0]['enabled'] == 1 and globals.spindle_controll == '1':
			self.set_ops_leds(14,  14,   True)
		else:
			self.set_ops_leds(14,  14,   False)

		if globals.spindle_controll == '0':
			if self.status.task_state == 3:
				self.lc.spindle(self.linuxcnc.SPINDLE_OFF)

		globals.get_toolchangedata()
		if globals.change_tool != '0':
			self.line_number = int(globals.change_tool)
			self.builder.get_object("hal_sourceview1_1").set_line_number (self.line_number)
			self.builder.get_object("hal_sourceview3_1").set_line_number (self.line_number)
			self.builder.get_object("hal_gremlin1").set_highlight_line(self.line_number)
			self.builder.get_object("hal_gremlin2").set_highlight_line(self.line_number)
			self.builder.get_object("hal_gremlin3").set_highlight_line(self.line_number)
				
		if self.prog_running and globals.change_tool == '0' and not self.program_paused:
			if self.status.exec_state == self.linuxcnc.EXEC_DONE and self.status.state == self.linuxcnc.RCS_DONE:
				self.timer_set = False
				self.prog_running = False
				self.line_number = 0 
				_message_('Program finished....')

		if self.prog_running : self.timer_set = True

		try:
			self.show_message(open('messages', 'rb').read())
		except:
			pass		
		self.report_error()
		return True
		pass

	def report_error(self):
		self.error_status = self.error_channel.poll()
		if self.error_status: 
			print type(self.error_status)
			print self.error_status
			self.error_kind, self.error_text = self.error_status
			if self.error_kind in (linuxcnc.NML_ERROR, linuxcnc.OPERATOR_ERROR):
				self.error_type = "Error "
			else:
				self.error_type = "Info "
			if self.error_text.find('Unexpected realtime delay') == -1 and self.error_text.find('do that (EMC_TASK_PLAN_RUN) in manual mode') == -1 :
				self.message_id = self.statusbar.push(0, self.error_type + self.error_text)
			if self.error_text.find('do that (EMC_TASK_PLAN_RUN) in manual mode') > -1 :
				self.lc.mode(linuxcnc.MODE_MANUAL)
				self.gcode_runfrom(self, '')				
	
	
	def on_menu_halshow_activate(self, widget, data=None):
		subprocess.Popen([self.tcl_dir + "halshow.tcl", "-- -ini " + self.ini_file])
		
	def write_settings(self):
		config = ConfigParser_New.RawConfigParser() 
		config.read('cnc_settings.ini')
		config.set('CRAFTSMANCNC_SETTINGS', 'SPINDLE_CONTROL', self.spindle_controller)
		config.set('CRAFTSMANCNC_SETTINGS', 'MACHINE_COORDS', self.machine_coords)
		with open('cnc_settings.ini', 'wb') as configfile:
			config.write(configfile)
		pass


	def on_mainwindow_destroy(self, widget, data=None):
		self.write_settings()
		globals.clear_tooldata()
		globals.clear_extents()
		globals.ops_message('Machine switched off')
		gtk.main_quit()

	def on_gtk_quit_activate(self, menuitem, data=None):
		self.write_settings()
		globals.clear_tooldata()
		globals.clear_extents()		
		globals.ops_message('Machine switched off')
		gtk.main_quit()

if __name__ == "__main__":
  if len(sys.argv) > 2 and sys.argv[1] == '-ini':
    app = craftsman(sys.argv[2])
  else:
    app = craftsman()

  # load a postgui file if one is present in the INI file
  postgui_halfile,inifile = craftsman.postgui(app)

  if postgui_halfile:
    res = os.spawnvp(os.P_WAIT, "halcmd", ["halcmd", "-i",inifile,"-f", postgui_halfile])
    if res: raise SystemExit, res

  gtk.main()
