Skip to content
maurice_gmoccapy.py 235 KiB
Newer Older
#! /usr/bin/python2
# -*- coding:UTF-8 -*-
"""
    A GUI for LinuxCNC based on gladevcp and Python
    Based on the design of moccagui from Tom
    and with a lot of code from gscreen from Chris Morley
    and with the help from Michael Haberler
    and Chris Morley and some more

    Copyright 2012 / 2017 Norbert Schechner
    nieson@web.de

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

"""

import traceback           # needed to launch traceback errors
import hal                 # base hal class to react to hal signals
import hal_glib            # needed to make our own hal pins
import gtk                 # base for pygtk widgets and constants
import sys                 # handle system calls
import os                  # needed to get the paths and directories
import gladevcp.makepins   # needed for the dialog"s calculator widget
import atexit              # needed to register child's to be closed on closing the GUI
import subprocess          # to launch onboard and other processes
import tempfile            # needed only if the user click new in edit mode to open a new empty file
import linuxcnc            # to get our own error system
import gobject             # needed to add the timer for periodic
import locale              # for setting the language of the GUI
import gettext             # to extract the strings to be translated
from collections import OrderedDict # needed for proper jog button arrangement

from gladevcp.gladebuilder import GladeBuilder

from gladevcp.combi_dro import Combi_DRO  # we will need it to make the DRO

from time import sleep     # needed to get time in case of non wanted mode switch
from time import strftime  # needed for the clock in the GUI
from gtk._gtk import main_quit

# Throws up a dialog with debug info when an error is encountered
def excepthook(exc_type, exc_obj, exc_tb):
    try:
        w = app.widgets.window1
    except KeyboardInterrupt:
        sys.exit()
    except NameError:
        w = None
    lines = traceback.format_exception(exc_type, exc_obj, exc_tb)
    m = gtk.MessageDialog(w,
                          gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                          gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
                          ("Found an error!\nThe following information may be useful in troubleshooting:\n\n")
                          + "".join(lines))
    m.show()
    m.run()
    m.destroy()


sys.excepthook = excepthook

debug = False

if debug:
    pydevdir = '/home/emcmesa/liclipse/plugins/org.python.pydev_4.5.4.201601292050/pysrc'

    if os.path.isdir(pydevdir):  # and  'emctask' in sys.builtin_module_names:
        sys.path.append(pydevdir)
        sys.path.insert(0, pydevdir)
        try:
            import pydevd

            print("pydevd imported, connecting to Eclipse debug server...")
            pydevd.settrace()
        except:
            print("no pydevd module found")
            pass

# constants
#         # gmoccapy  #"
_RELEASE = " 3.0.9.1"
_INCH = 0                         # imperial units are active
_MM = 1                           # metric units are active

# set names for the tab numbers, its easier to understand the code
# Bottom Button Tabs
_BB_MANUAL = 0
_BB_MDI = 1
_BB_AUTO = 2
_BB_HOME = 3
_BB_TOUCH_OFF = 4
_BB_SETUP = 5
_BB_EDIT = 6
_BB_TOOL = 7
_BB_LOAD_FILE = 8
#_BB_HOME_JOINTS will not be used, we will reorder the notebooks to get the correct page shown

_TEMPDIR = tempfile.gettempdir()  # Now we know where the tempdir is, usualy /tmp

# set up paths to files
#BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), ".."))
BASE = "/usr"  # Maurice local gmoccapy
LIBDIR = os.path.join(BASE, "lib", "python")
sys.path.insert(0, LIBDIR)

# as now we know the libdir path we can import our own modules
from gmoccapy import widgets       # a class to handle the widgets
from gmoccapy import notification  # this is the module we use for our error handling
from gmoccapy import preferences   # this handles the preferences
from gmoccapy import getiniinfo    # this handles the INI File reading so checking is done in that module
from gmoccapy import dialogs       # this takes the code of all our dialogs

_AUDIO_AVAILABLE = False
try:
    import gst
    from gmoccapy import player        # a class to handle sounds
    _AUDIO_AVAILABLE = True
except:
    pass
# set up paths to files, part two
CONFIGPATH = os.environ['CONFIG_DIR']
DATADIR = os.path.join(BASE, "share", "gmoccapy")
IMAGEDIR = os.path.join(DATADIR, "images")
XMLNAME = os.path.join(DATADIR, "gmoccapy.glade")
THEMEDIR = "/usr/share/themes"
USERTHEMEDIR = os.path.join(os.path.expanduser("~"), ".themes")
LOCALEDIR = os.path.join(BASE, "share", "locale")

# path to TCL for external programs eg. halshow
TCLPATH = os.environ['LINUXCNC_TCL_DIR']

# the ICONS should must be in share/gmoccapy/images
ALERT_ICON = os.path.join(IMAGEDIR, "applet-critical.png")
INFO_ICON = os.path.join(IMAGEDIR, "std_info.gif")

# this is for hiding the pointer when using a touch screen
pixmap = gtk.gdk.Pixmap(None, 1, 1, 1)
color = gtk.gdk.Color()
INVISABLE = gtk.gdk.Cursor(pixmap, pixmap, color, color, 0, 0)


class gmoccapy(object):
    def __init__(self, argv):
        
        # prepare for translation / internationalisation
        locale.setlocale(locale.LC_ALL, '')
        locale.bindtextdomain("gmoccapy", LOCALEDIR)
        gettext.install("gmoccapy", localedir=LOCALEDIR, unicode=True)
        gettext.bindtextdomain("gmoccapy", LOCALEDIR)

        # needed components to comunicate with hal and linuxcnc
        self.halcomp = hal.component("gmoccapy")
        self.command = linuxcnc.command()
        self.stat = linuxcnc.stat()

        self.error_channel = linuxcnc.error_channel()
        # initial poll, so all is up to date
        self.stat.poll()
        self.error_channel.poll()

        self.builder = gtk.Builder()
        # translation of the glade file will be done with
        self.builder.set_translation_domain("gmoccapy")
        self.builder.add_from_file(XMLNAME)

        self.widgets = widgets.Widgets(self.builder)
        
        self.initialized = False  # will be set True after the window has been shown and all
                                  # basic settings has been finished, so we avoid some actions
                                  # because we cause click or toggle events when initializing
                                  # widget states.

        self.start_line = 0  # needed for start from line

        self.active_gcodes = []   # this are the formated G code values
        self.active_mcodes = []   # this are the formated M code values
        self.gcodes = []          # this are the unformatted G code values to check if an update is required
        self.mcodes = []          # this are the unformatted M code values to check if an update is required

        self.distance = 0         # This global will hold the jog distance
        self.tool_change = False  # this is needed to get back to manual mode after a tool change
        self.load_tool = False    # We use this avoid mode switching on reloading the tool on start up of the GUI
        self.macrobuttons = []    # The list of all macros defined in the INI file
        self.fo_counts = 0        # need to calculate difference in counts to change the feed override slider
        self.so_counts = 0        # need to calculate difference in counts to change the spindle override slider
        self.jv_counts = 0        # need to calculate difference in counts to change the jog_vel slider
        self.ro_counts = 0        # need to calculate difference in counts to change the rapid override slider

Loading full blame...