/ lib / python / gladevcp / tooledit_widget.py
tooledit_widget.py
  1  #!/usr/bin/env python
  2  # GladeVcp Widget - tooledit
  3  #
  4  # Copyright (c) 2012 Chris Morley
  5  # Modified 2016 Jim Craig <jimcraig5615  at  windstream dot  net>
  6  #
  7  # This program is free software: you can redistribute it and/or modify
  8  # it under the terms of the GNU General Public License as published by
  9  # the Free Software Foundation, either version 2 of the License, or
 10  # (at your option) any later version.
 11  #
 12  # This program is distributed in the hope that it will be useful,
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15  # GNU General Public License for more details.
 16  
 17  import sys, os, pango, linuxcnc, hashlib, glib
 18  datadir = os.path.abspath(os.path.dirname(__file__))
 19  KEYWORDS = ['S','T', 'P', 'X', 'Y', 'Z', 'A', 'B', 'C', 'U', 'V', 'W', 'D', 'I', 'J', 'Q', ';']
 20  try:
 21      import gobject,gtk
 22  except:
 23      print('GTK not available')
 24      sys.exit(1)
 25  
 26  # localization
 27  import locale
 28  BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
 29  LOCALEDIR = os.path.join(BASE, "share", "locale")
 30  locale.setlocale(locale.LC_ALL, '')
 31  
 32  # we put this in a try so there is no error in the glade editor
 33  # linuxcnc is probably not running then
 34  try:
 35      INIPATH = os.environ['INI_FILE_NAME']
 36  except:
 37      INIPATH = None
 38  
 39  class ToolEdit(gtk.VBox):
 40      __gtype_name__ = 'ToolEdit'
 41      __gproperties__ = {
 42          'font' : ( gobject.TYPE_STRING, 'Pango Font', 'Display font to use',
 43                  "sans 12", gobject.PARAM_READWRITE|gobject.PARAM_CONSTRUCT),
 44          'hide_columns' : (gobject.TYPE_STRING, 'Hidden Columns', 'A no-spaces list of columns to hide: stpxyzabcuvwdijq and ; are the options',
 45                      "", gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT),
 46          'lathe_display_type' : ( gobject.TYPE_BOOLEAN, 'Display Type', 'True: Lathe layout, False standard layout',
 47                      False, gobject.PARAM_READWRITE | gobject.PARAM_CONSTRUCT),
 48      }
 49      __gproperties = __gproperties__
 50  
 51      def __init__(self,toolfile=None, *a, **kw):
 52          super(ToolEdit, self).__init__()
 53          self.emcstat = linuxcnc.stat()
 54          self.hash_check = None 
 55          self.lathe_display_type = True
 56          self.toolfile = toolfile
 57          self.num_of_col = 1
 58          self.font="sans 12"
 59          self.hide_columns =''
 60          self.toolinfo_num = 0
 61          self.toolinfo = []
 62          self.wTree = gtk.Builder()
 63          self.wTree.set_translation_domain("linuxcnc") # for locale translations
 64          self.wTree.add_from_file(os.path.join(datadir, "tooledit_gtk.glade") )
 65          # connect the signals from Glade
 66          dic = {
 67              "on_delete_clicked" : self.delete,
 68              "on_add_clicked" : self.add,
 69              "on_reload_clicked" : self.reload,
 70              "on_save_clicked" : self.save,
 71              "cell_toggled" : self.toggled
 72              }
 73          self.wTree.connect_signals( dic )
 74  
 75          self.treeview1 = self.wTree.get_object("treeview1")
 76          self.treeview1.connect("key-release-event", self.on_tree_navigate_key_press, None)
 77  
 78          # for raw view 1:
 79  
 80          # toggle button useable
 81          renderer = self.wTree.get_object("cell_toggle1")
 82          renderer.set_property('activatable', True)
 83          # make colums editable
 84          self.tool_cell_list = "cell_tool#","cell_pos","cell_x","cell_y","cell_z","cell_a","cell_b","cell_c","cell_u","cell_v","cell_w","cell_d", \
 85                  "cell_front","cell_back","cell_orient","cell_comments"
 86          for col,name in enumerate(self.tool_cell_list):
 87              #print name,col
 88              renderer = self.wTree.get_object(name+'1')
 89              renderer.connect( 'edited', self.col_editted, col+1, None)
 90              renderer.props.editable = True
 91          self.all_label = self.wTree.get_object("all_label")
 92  
 93          # for lathe wear view2:
 94  
 95          # make columns editable
 96          temp =[ ("cell_x2",3),("cell_z2",5),("cell_front2",13),("cell_back2",14), \
 97                  ("cell_orient2",15), ("cell_comments2",16)]
 98          for name,col in temp:
 99              renderer = self.wTree.get_object(name)
100              renderer.connect( 'edited', self.col_editted, col, 'wear' )
101              renderer.props.editable = True
102          # Hide columns we don't want to see
103          self.set_col_visible(list='spyabcuvwdijq', bool= False, tab= '2')
104          self.wear_label = self.wTree.get_object("wear_label")
105  
106          # for tool offsets view 3:
107  
108          # make columns editable
109          temp =[ ("cell_x3",3),("cell_z3",5),("cell_front3",13),("cell_back3",14), \
110                  ("cell_orient3",15), ("cell_comments3",16)]
111          for name,col in temp:
112              renderer = self.wTree.get_object(name)
113              renderer.connect( 'edited', self.col_editted, col, 'tool' )
114              renderer.props.editable = True
115          # Hide columns we don't want to see
116          self.set_col_visible(list='spyabcuvwdij', bool= False, tab= '3')
117          self.tool_label = self.wTree.get_object("tool_label")
118  
119          # global references
120          self.model = self.wTree.get_object("liststore1")
121          self.notebook = self.wTree.get_object("tool_offset_notebook")
122          self.all_window = self.wTree.get_object("all_window")
123          self.wear_window = self.wTree.get_object("wear_window")
124          self.tool_window = self.wTree.get_object("tool_window")
125          self.view1 = self.wTree.get_object("treeview1")
126          self.view2 = self.wTree.get_object("treeview2")
127          # sort routine for tool diameter
128          def compare(model, row1, row2, user_data=None):
129              sort_column, _ = model.get_sort_column_id()
130              value1 = model.get_value(row1,sort_column)
131              value2 = model.get_value(row2,sort_column)
132              return cmp(value1,value2)
133          model = self.view1.get_model()
134          model.set_sort_func(12, compare)
135          #self.view2.connect('button_press_event', self.on_treeview2_button_press_event)
136          self.view2.connect("key-release-event", self.on_tree_navigate_key_press, 'wear')
137          self.selection = self.view2.get_selection()
138          self.selection.set_mode(gtk.SELECTION_SINGLE)
139          self.view3 = self.wTree.get_object("treeview3")
140          #self.view3.connect('button_press_event', self.on_treeview2_button_press_event)
141          self.view3.connect("key-release-event", self.on_tree_navigate_key_press, 'tool')
142          self.apply = self.wTree.get_object("apply")
143          self.buttonbox = self.wTree.get_object("buttonbox")
144          self.tool_filter = self.wTree.get_object("tool_modelfilter")
145          self.tool_filter.set_visible_func(self.match_type,False)
146          self.wear_filter = self.wTree.get_object("wear_modelfilter")
147          self.wear_filter.set_visible_func(self.match_type,True)
148          # reparent tooledit box from Glades tp level window to tooledit's VBox
149          window = self.wTree.get_object("tooledit_box")
150          window.reparent(self)
151          # If the toolfile was specified when tooledit was created load it
152          if toolfile:
153              self.reload(None)
154          # check the ini file if display-type: LATHE is set
155          try:
156              self.inifile = linuxcnc.ini(INIPATH)
157              test = self.inifile.find("DISPLAY", "LATHE")
158              if test == '1' or test == 'True':
159                  self.lathe_display_type = True
160                  self.set_lathe_display(True)
161              else:
162                  self.lathe_display_type = False
163                  self.set_lathe_display(False)
164          except:
165              pass
166  
167          # check linuxcnc status every second
168          gobject.timeout_add(1000, self.periodic_check)
169  
170      # used to split tool and wear data by the tool number
171      # if the tool number is above 10000 then its a wear offset (as per fanuc)
172      # returning true will show the row
173      def match_type(self, model, iter, data):
174          value = model.get_value(iter, 1)
175          if value < 10000:
176              return not data
177          return data
178  
179          # delete the selected tools
180      def delete(self,widget):
181          liststore  = self.model
182          def match_value_cb(model, path, iter, pathlist):
183              if model.get_value(iter, 0) == 1 :
184                  pathlist.append(path)
185              return False     # keep the foreach going
186  
187          pathlist = []
188          liststore.foreach(match_value_cb, pathlist)
189          # foreach works in a depth first fashion
190          pathlist.reverse()
191          for path in pathlist:
192              liststore.remove(liststore.get_iter(path))
193  
194          # return the selected tool number
195      def get_selected_tool(self):
196          liststore  = self.model
197          def match_value_cb(model, path, iter, pathlist):
198              if model.get_value(iter, 0) == 1 :
199                  pathlist.append(path)
200              return False     # keep the foreach going
201          pathlist = []
202          liststore.foreach(match_value_cb, pathlist)
203          # foreach works in a depth first fashion
204          if len(pathlist) != 1:
205              return None
206          else:
207              return(liststore.get_value(liststore.get_iter(pathlist[0]),1))
208  
209      def set_selected_tool(self,toolnumber):
210          try:
211              treeselection = self.view2.get_selection()
212              liststore  = self.model
213              def match_tool(model, path, iter, pathlist):
214                  if model.get_value(iter, 1) == toolnumber:
215                      pathlist.append(path)
216                  return False     # keep the foreach going
217              pathlist = []
218              liststore.foreach(match_tool, pathlist)
219              # foreach works in a depth first fashion
220              if len(pathlist) == 1:
221                  liststore.set_value(liststore.get_iter(pathlist[0]),0,1)
222                  treeselection.select_path(pathlist[0])
223          except:
224              print _("tooledit_widget error: cannot select tool number"),toolnumber
225  
226      def add(self,widget,data=[1,0,0,'0','0','0','0','0','0','0','0','0','0','0','0','0',"comment"]):
227          self.model.append(data)
228          self.num_of_col +=1
229  
230          # this is for adding a filename path after the tooleditor is already loaded.
231      def set_filename(self,filename):
232          self.toolfile = filename
233          self.reload(None)
234  
235          # Reload the tool file into display
236      def reload(self,widget):
237          self.hash_code = self.md5sum(self.toolfile)
238          # clear the current liststore, search the tool file, and add each tool
239          if self.toolfile == None:return
240          self.model.clear()
241          #print "toolfile:",self.toolfile
242          if not os.path.exists(self.toolfile):
243              print _("Toolfile does not exist")
244              return
245          logfile = open(self.toolfile, "r").readlines()
246          self.toolinfo = []
247          for rawline in logfile:
248              # strip the comments from line and add directly to array
249              # if index = -1 the delimiter ; is missing - clear comments
250              index = rawline.find(";")
251              comment =''
252              if not index == -1:
253                  comment = (rawline[index+1:])
254                  comment = comment.rstrip("\n")
255                  line = rawline.rstrip(comment)
256              else:
257                  line = rawline
258              array = [0,0,0,'0','0','0','0','0','0','0','0','0','0','0','0','0',comment]
259              toolinfo_flag = False
260              # search beginning of each word for keyword letters
261              # offset 0 is the checkbutton so ignore it
262              # if i = ';' that is the comment and we have already added it
263              # offset 1 and 2 are integers the rest floats
264              # we strip leading and following spaces from the comments
265              for offset,i in enumerate(KEYWORDS):
266                  if offset == 0 or i == ';': continue
267                  for word in line.split():
268                      if word.startswith(';'): break
269                      if word.startswith(i):
270                          if offset == 1:
271                              if int(word.lstrip(i)) == self.toolinfo_num:
272                                  toolinfo_flag = True
273                          if offset in(1,2):
274                              try:
275                                  array[offset]= int(word.lstrip(i))
276                              except:
277                                  print _("Tooledit widget int error")
278                          else:
279                              try:
280                                  array[offset]= locale.format("%10.4f", float(word.lstrip(i)))
281                              except:
282                                  print _("Tooledit_widget float error")
283                          break
284              if toolinfo_flag:
285                  self.toolinfo = array
286              # add array line to liststore
287              self.add(None,array)
288  
289          # Note we have to save the float info with a decimal even if the locale uses a comma
290      def save(self,widget):
291          if self.toolfile == None:return
292          file = open(self.toolfile, "w")
293          #print self.toolfile
294          liststore = self.model
295          for row in liststore:
296              values = [ value for value in row ]
297              #print values
298              line = ""
299              for num,i in enumerate(values):
300                  if num == 0: continue
301                  elif num in (1,2): # tool# pocket#
302                      line = line + "%s%d "%(KEYWORDS[num], i)
303                  elif num == 16: # comments
304                      test = i.strip()
305                      line = line + "%s%s "%(KEYWORDS[num],test)
306                  else:
307                      test = i.lstrip() # localized floats
308                      line = line + "%s%s "%(KEYWORDS[num], locale.atof(test))
309  
310              print >>file,line
311          # Theses lines are required to make sure the OS doesn't cache the data
312          # That would make linuxcnc and the widget to be out of synch leading to odd errors
313          file.flush()
314          os.fsync(file.fileno())
315          # tell linuxcnc we changed the tool table entries
316          try:
317              linuxcnc.command().load_tool_table()
318          except:
319              print _("Reloading tooltable into linuxcnc failed")
320  
321          # This is for changing the display after tool editor was loaded using the style button
322          # note that it toggles the display
323      def display_toggle(self,widget=None):
324          value = (self.display_type * -1) +1
325          self.set_display(value)
326  
327          # There is an 'everything' display and a 'lathe' display
328          # the same model is used in each case just the listview is different
329          # does the actual display change by hiding what we don't want
330          # for whatever reason I have to hide/show both the view and it's container
331      def set_lathe_display(self,value):
332          #print "    lathe_display    ",value
333          self.lathe_display_type = value
334          #if self.all_window.flags() & gtk.VISIBLE:
335          self.notebook.set_show_tabs(value)
336          if value:
337              self.wear_window.show()
338              self.view3.show()
339              self.tool_window.show()
340              self.view2.show()
341          else:
342              self.view2.hide()
343              self.wear_window.hide()
344              
345              self.tool_window.hide()
346              self.view3.hide()
347  
348      def set_font(self, value, tab='123'):
349          for i in range(0, len(tab)):
350              if tab[i] in ('1','2','3'):
351                  for col,name in enumerate(self.tool_cell_list):
352                      temp2 = self.wTree.get_object(name+tab[i])
353                      temp2.set_property('font', value)
354          self.set_title_font(value, tab)
355          self.set_tab_font(value, tab)
356  
357      # set font of the column titles
358      def set_title_font(self, value, tab='123'):
359          objectlist = "s","t","p","x","y","z","a","b","c","u","v","w","d","i","j","q",";"
360          for i in range(0, len(tab)):
361              if tab[i] in ('1','2','3'):
362                  for j in objectlist:
363                      column = self.wTree.get_object(j+tab[i])
364                      label = gtk.Label(column.get_title())
365                      label.modify_font(pango.FontDescription(value))
366                      label.show()
367                      column.set_widget(label)
368  
369      def set_tab_font (self, value, tab='123'):
370          for i in range(0, len(tab)):
371              if tab[i] in ('1','2','3'):
372                  if tab[i] =='1':
373                      self.all_label.modify_font(pango.FontDescription(value))
374                  elif tab[i] =='2':
375                      self.wear_label.modify_font(pango.FontDescription(value))
376                  elif tab[i] =='3':
377                      self.tool_label.modify_font(pango.FontDescription(value))
378                  else:
379                      pass
380  
381      # for legacy interface
382      def set_visible(self,list,bool):
383          self.set_col_visible(list, bool, tab= '1')
384  
385      # This allows hiding or showing columns from a text string of columnns
386      # eg list ='xyz'
387      # tab= selects what tabs to apply it to
388      def set_col_visible(self, list, bool= False, tab= '1'):
389          #print list,bool,tab
390          for i in range(0, len(tab)):
391              if tab[i] in ('1','2','3'):
392                  #print tab[i]
393                  for index in range(0, len(list)):
394                      colstr = str(list[index])
395                      #print colstr
396                      colnum = 'stpxyzabcuvwdijq;'.index(colstr.lower())
397                      #print colnum
398                      name = KEYWORDS[colnum].lower()+tab[i]
399                      #print name
400                      renderer = self.wTree.get_object(name)
401                      renderer.set_property('visible', bool)
402  
403      # For single click selection when in edit mode
404      def on_treeview2_button_press_event(self, widget, event):
405          if event.button == 1 : # left click
406              try:
407                  path, model, x, y = widget.get_path_at_pos(int(event.x), int(event.y))
408                  widget.set_cursor(path, None, True)
409              except:
410                  pass
411  
412          # depending what is editted add the right type of info integer,float or text
413          # If it's a filtered display then we must convert the path 
414      def col_editted(self, widget, path, new_text, col, filter):
415          if filter == 'wear':
416              (store_path,) = self.wear_filter.convert_path_to_child_path(path)
417              path = store_path
418          elif filter == 'tool':
419              (store_path,) = self.tool_filter.convert_path_to_child_path(path)
420              path = store_path
421          
422          if col in(1,2):
423              try:
424                  self.model[path][col] = int(new_text)
425              except:
426                  pass
427          elif col in range(3,16):
428              try:
429                  self.model[path][col] = locale.format("%10.4f",locale.atof(new_text))
430              except:
431                  pass
432          elif col == 16:
433              try:
434                  self.model[path][col] = (new_text)
435              except:
436                  pass
437          #print path,new_text, col
438          if filter in('wear','tool'):
439              self.save(None)
440  
441          # this makes the checkboxes actually update
442      def toggled(self, widget, path):
443          model = self.model
444          model[path][0] = not model[path][0]
445  
446          # check for linnuxcnc ON and IDLE which is the only safe time to edit the tool file.
447          # check to see if the tool file is current
448      def periodic_check(self):
449          try:
450              self.emcstat.poll()
451              on = self.emcstat.task_state > linuxcnc.STATE_OFF
452              idle = self.emcstat.interp_state == linuxcnc.INTERP_IDLE
453              self.apply.set_sensitive(bool(on and idle))
454          except:
455              pass
456          if self.toolfile:
457              self.file_current_check()
458          return True
459  
460          # create a hash code
461      def md5sum(self,filename):
462          try:
463              f = open(filename, "rb")
464          except IOError:
465              return None
466          else:
467              return hashlib.md5(f.read()).hexdigest()
468  
469          # check the hash code on the toolfile against
470          # the saved hash code when last reloaded.
471      def file_current_check(self):
472          m = self.hash_code
473          m1 = self.md5sum(self.toolfile)
474          if m1 and m != m1:
475              self.toolfile_stale()
476  
477          # you could overload this to do something else.
478      def toolfile_stale(self):
479          print _("Tool file was modified since it was last read")
480          self.reload(None)
481          self.set_selected_tool(self.toolinfo_num)
482  
483          # Returns the tool information array of the requested toolnumber
484          # or current tool if no tool number is specified
485          # returns None if tool not found in table or if there is no current tool
486      def get_toolinfo(self,toolnum=None):
487          if toolnum == None:
488              self.toolinfo_num = self.emcstat.tool_in_spindle
489          else:
490              self.toolinfo_num = toolnum
491          self.reload(None)
492          if self.toolinfo == []: return None
493          return self.toolinfo
494  
495          # 'convenience' method to hide buttons
496          # you must call this after show_all()
497      def hide_buttonbox(self, data):
498          if data:
499              self.buttonbox.hide()
500          else:
501              self.buttonbox.show()
502  
503          # standard Gobject method
504      def do_get_property(self, property):
505          name = property.name.replace('-', '_')
506          if name in self.__gproperties.keys():
507              return getattr(self, name)
508          else:
509              raise AttributeError('unknown property %s' % property.name)
510  
511          # standard Gobject method
512          # changing the Gobject property 'display_type' will actually change the display
513          # This is so that in the Glade editor, you can change the display
514          # Note this sets the display absolutely vrs the display_toggle method that toggles the display
515      def do_set_property(self, property, value):
516          name = property.name.replace('-', '_')
517          if name == 'font':
518              try:
519                  self.set_font(value)
520              except:
521                  pass
522          elif name == 'lathe_display_type':
523              #print value
524              if INIPATH is None:
525                  try:
526                      self.set_lathe_display(value)
527                  except:
528                      pass
529          elif name == 'hide_columns':
530              try:
531                  self.set_col_visible("sptxyzabcuvwdijq;", True)
532                  self.set_col_visible("%s" % value, False)
533              except:
534                  pass
535  
536      # define the callback for keypress events
537      def on_tree_navigate_key_press(self, treeview, event, filter):
538          keyname = gtk.gdk.keyval_name(event.keyval)
539          path, col = treeview.get_cursor()
540          columns = [c for c in treeview.get_columns()]
541          colnum = columns.index(col)
542  
543          focuschild = treeview.focus_child
544  
545          if filter == 'wear':
546              store_path = self.wear_filter.convert_path_to_child_path(path)
547              path = store_path
548          elif filter == 'tool':
549              store_path = self.tool_filter.convert_path_to_child_path(path)
550              path = store_path
551  
552          if keyname == 'Tab' or keyname == 'Right':
553  
554              cont = True
555              cont2 = True
556              i = 0
557              while cont:
558                  i += 1
559                  if colnum + i < len(columns):
560                      if columns[colnum + i].props.visible:
561                          renderer = columns[colnum + i].get_cell_renderers()
562                          if renderer[0].props.editable:
563                              next_column = columns[colnum + i]
564                              cont = False
565  
566                  else:
567                      i = 1
568                      while cont2:
569                          renderer = columns[i].get_cell_renderers()
570                          if renderer[0].props.editable:
571                              next_column = columns[i]
572                              cont2 = False
573                          else:
574                              i += 1
575                      cont = False
576  
577              if keyname == 'Right':
578                  renderer = columns[colnum].get_cell_renderers()
579                  if type(focuschild) is gtk.Entry:
580                      self.col_editted(renderer[0], path, treeview.focus_child.props.text, colnum, filter)
581              glib.timeout_add(50,
582                               treeview.set_cursor,
583                               path, next_column, True)
584  
585          elif keyname == 'Left':
586  
587              cont = True
588              cont2 = True
589              i = 0
590              while cont:
591                  i -= 1
592                  if colnum + i > 0:
593                      if columns[colnum + i].props.visible:
594                          renderer = columns[colnum + i].get_cell_renderers()
595                          if renderer[0].props.editable:
596                              next_column = columns[colnum + i]
597                              cont = False
598  
599                  else:
600                      i = -1
601                      while cont2:
602                          renderer = columns[i].get_cell_renderers()
603                          if renderer[0].props.editable:
604                              next_column = columns[i]
605                              cont2 = False
606                          else:
607                              i -= 1
608                      cont = False
609  
610              renderer = columns[colnum].get_cell_renderers()
611              if type(focuschild) is gtk.Entry:
612                  self.col_editted(renderer[0], path, treeview.focus_child.props.text, colnum, filter)
613              glib.timeout_add(50,
614                               treeview.set_cursor,
615                               path, next_column, True)
616  
617          elif keyname == 'Return' or keyname == 'KP_Enter' or keyname == 'Down':
618  
619              model = treeview.get_model()
620              # Check if currently in last row of Treeview
621              if path[0] + 1 == len(model):
622                  path = (0, )
623                  # treeview.set_cursor(path, columns[colnum], True)
624                  glib.timeout_add(50,
625                                   treeview.set_cursor,
626                                   path, columns[colnum], True)
627              else:
628                  newpath = path[0] + 1
629                  # treeview.set_cursor(path, columns[colnum], True)
630                  glib.timeout_add(50,
631                                   treeview.set_cursor,
632                                   newpath, columns[colnum], True)
633  
634          elif keyname == 'Up':
635              model = treeview.get_model()
636              if path[0] == 0:
637                  newpath = len(model)-1
638              else:
639                  newpath = path[0] - 1
640              glib.timeout_add(50,
641                               treeview.set_cursor,
642                               newpath, columns[colnum], True)
643  
644  
645          else:
646              pass
647  
648  
649  # for testing without glade editor:
650  # for what ever reason tooledit always shows both display lists,
651  # in the glade editor it shows only one at a time (as it should)
652  # you can specify a tool table file at the command line
653  # or uncomment the line and set the path correctly.
654  def main(filename=None):
655      window = gtk.Dialog("My dialog",
656                     None,
657                     gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
658                     (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
659                      gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
660      tooledit = ToolEdit(filename)
661      
662      window.vbox.add(tooledit)
663      window.connect("destroy", gtk.main_quit)
664      tooledit.set_col_visible("abcUVW", False, tab='1')
665      # uncommented the below line for testing.
666      tooledit.set_filename("/home/jim/linuxcnc/configs/sim.gmoccapy/tool.tbl")
667      #tooledit.set_filename("/home/chris/emc2-dev/configs/sim/lathe.tbl")
668      tooledit.set_font("sans 16",tab='23')
669      window.show_all()
670      #tooledit.set_lathe_display(True)
671      response = window.run()
672      if response == gtk.RESPONSE_ACCEPT:
673         print "True"
674      else:
675         print "False"
676  
677  if __name__ == "__main__":
678      # if there are two arguments then specify the path
679      if len(sys.argv) > 1: main(sys.argv[1])
680      else: main()
681      
682