#!/usr/bin/env python3 # -*- encoding: utf-8 -*- # QT_VCP # Copyright 2016 Chris Morley # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import os from qtvcp.widgets.simple_widgets import _HalWidgetBase from qtvcp.widgets.screen_options import ScreenOptions from qtpy.QtCore import QObject from qtpy.QtWidgets import QApplication from qtvcp.core import Info # Set up logging from . import logger LOG = logger.getLogger(__name__) INFO = Info() # Force the log level for this module #LOG.setLevel(logger.DEBUG) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL class QTPanel(): def __init__(self, halcomp, path, window, debug): xmlname = path.XML self.window = window self.window['panel_'] = self self._screenOptions = None self._geo_string = '' self.PATH = path window._VCPWindowList.append(window) # see if a screenoptions widget is present # if it is then initiate the preference file # and pass a preference object to the window # it's then available to all HALified objects # also allow screenoptions to inject data into # our main window object -Ie reference to Notify lib # we must do this first of course for widget in window.findChildren(QObject): if isinstance(widget, _HalWidgetBase): if isinstance(widget, ScreenOptions): self._screenOptions = widget try: self.window['OPTIONS_'] = widget except Exception as e: LOG.warning('Screen OPTIONS instance injection error: {}'.format(e)) self.window['OPTIONS_'] = None # change HAL base name to screenOptions setting if # a new base name was not specified on the command line # and screenOptions name is not blank oldHALName = halcomp.comp.getprefix() if oldHALName == path.BASENAME: newHALName = widget.property('halCompBaseName') if not newHALName == '': halcomp.comp.setprefix(newHALName) LOG.info('Changed HAL Component basename to {}, as specified in screenOptions: '.format(newHALName)) try: self.window['PREFS_'], pref_fn = widget._pref_init() except Exception as e: LOG.warning('Preference instance error: {}'.format(e)) self.window['PREFS_'], pref_fn = (None, None) path.PREFS_FILENAME = pref_fn try: widget._VCPObject_injection(window) except Exception as e: LOG.warning('VCPObject Injection error: {}'.format(e)) # load any external embed qtvcp panels () found from INI entry. if INFO.TAB_CMDS: for name, loc, cmd in INFO.ZIPPED_TABS: # install a QTvcp panel instance # if 'loadusr' is present, it's assumed embedding into AXIS # so ignore it. if 'qtvcp' in cmd and not 'loadusr' in cmd: temp = cmd.split() hdlrName = temp[len(cmd.split())-1] LOG.info('green'.format(hdlrName)) pName = name.replace(' ','_') window[pName] = window.makeMainPage(name) # find and pass -o option variables ucmd = [] for num,i in enumerate(temp): if i == '-o': ucmd.append(temp[num+1]) LOG.debug('user commands:{}'.format(ucmd)) if ucmd == []: window[pName].USEROPTIONS_ = None else: window[pName].USEROPTIONS_ = ucmd # search for handler path and load if available hndlr = self.PATH.find_embed_handler_path(hdlrName) if hndlr is not True and os.path.exists(hndlr): window[pName].load_extension(hndlr) # do any class patching now #TODO not tested feature if "class_patch__" in dir(window[pName].handler_instance): window[pName].handler_instance.class_patch__() # search for ui path and load if available uipath = self.PATH.find_embed_panel_path(hdlrName) window[pName].instance(uipath) window._VCPWindowList.append(window[pName]) # record HAL component base name because we are going to change it oldname = halcomp.comp.getprefix() halName = hdlrName.replace('_','-') halcomp.comp.setprefix('{}.{}'.format(oldname,halName)) LOG.debug('embedded halpin prefix name: cyan<{}.{}>'.format(oldname,halName)) LOG.debug('QTVCP: Parsing external qtvcp {} panel for EMBEDDED HAL widgets.'.format(hdlrName)) for widget in window[pName].findChildren(QObject): if isinstance(widget, _HalWidgetBase): idname = widget.objectName() LOG.verbose('{}: HAL-ified widget: {}'.format(name.upper(), idname)) if not isinstance(widget, ScreenOptions): # give panel name to halified widgets widget.hal_init(INSTANCE_NAME= pName) # restore HAL component name halcomp.comp.setprefix(oldname) # initialize handler if available if hndlr is not True and os.path.exists(hndlr): window[pName].handler_instance.initialized__() # parse for HAL objects: # initiate the hal function on each # keep a register list of these widgets for later LOG.debug('QTVCP: Parsing for HAL widgets.') for widget in window.findChildren(QObject): if isinstance(widget, _HalWidgetBase): idname = widget.objectName() LOG.verbose('HAL-ified widget: {}'.format(idname)) widget.hal_init() # Search all hal-ifed widgets for _hal_cleanup functions and call them # used for such things as preference recording current settings def shutdown(self): if not self.window['PREFS_'] is None: self.record_preference_geometry() LOG.debug("Calling widget's _hal_cleanup functions.") for widget in self.window.getRegisteredHalWidgetList(): try: widget._hal_cleanup() except Exception as e: print(e) # old way - will remove in future. if 'closing_cleanup__' in dir(widget): idname = widget.objectName() LOG.info('Closing cleanup on: {}'.format(idname)) LOG.info('"closing_cleanup__" function name is depreciated, please using "_hal_cleanup".') widget.closing_cleanup__() # if there is a prefrence file and it is has digits (so no key word), then record # the window geometry def record_preference_geometry(self): temp = self._geo_string.replace(' ', '') temp = temp.strip('-') if temp == '' or temp.isdigit(): LOG.debug('Saving Main Window geometry to preference file.') x = self.window.geometry().x() y = self.window.geometry().y() w = self.window.geometry().width() h = self.window.geometry().height() geo = '%s %s %s %s' % (x, y, w, h) mainName = self.window.objectName()+ '-geometry' self.window['PREFS_'].putpref(mainName, geo, str, 'SCREEN_OPTIONS') # if there is a screen option widget and we haven't set INI switch geometry # then call screenoptions function to set preference geometry def set_preference_geometry(self): if not self.window['PREFS_'] is None: self.geometry_parsing() else: LOG.info('No preference file - cannot set preference geometry.') def geometry_parsing(self): def go(x, y, w, h): self.window.setGeometry(x, y, w, h) try: mainName = self.window.objectName() + '-geometry' self._geo_string = self.window.PREFS_.getpref(mainName, '', str, 'SCREEN_OPTIONS') LOG.debug('Calculating geometry of main window using natural placement: {}'.format(self._geo_string)) # If there is a preference file object use it to load the geometry if self._geo_string in ('default', ''): return elif 'center' in self._geo_string.lower(): geom = self.window.frameGeometry() geom.moveCenter(QApplication.primaryScreen().availableGeometry().center()) self.window.setGeometry(geom) return else: temp = self._geo_string.split(' ') go(int(temp[0]), int(temp[1]), int(temp[2]), int(temp[3])) except Exception as e: LOG.exception('main window geometry python error: {}'.format(e)) LOG.error('Calculating geometry of main window using natural placement.') x = self.window.geometry().x() y = self.window.geometry().y() w = self.window.geometry().width() h = self.window.geometry().height() go(x, y, w, h) def __getitem__(self, item): return getattr(self, item) def __setitem__(self, item, value): return setattr(self, item, value) if __name__ == "__main__": print("qtvcp_make_pins cannot be run on its own") print("It must be called by qtscreen or a python program") print("that loads and displays the QT panel and creates a HAL component") # vim: sts=4 sw=4 et