#!/bin/env python
#===============================================================================
# NAME: MainPanelFactory.py
#
# DESCRIPTION: This is a factory class for instancing the main GSE panel.
#                It exists as a singlton and also destroys the toplevel
#                windows as well.
#
# AUTHOR: reder
# EMAIL:  <EMAIL>
# DATE CREATED  : Jan. 11, 2015
#
# Copyright 2015, California Institute of Technology.
# ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged.
#===============================================================================
#
# Python standard modules
#

import os
import sys
import glob
import time
import socket
import logging
import exceptions
import Tkinter
import Pmw
import subprocess


from views import main_panel
from views import command_panel
from views import log_event_panel
from views import telemetry_panel
from views import seq_panel
from views import status_panel
from views import status_bar
from views import file_panel
from views import stripchart_panel
from views import help_panel

from controllers import command_loader
from controllers import commander
from controllers import event_loader
from controllers import event_listener
from controllers import channel_loader
from controllers import channel_listener
from controllers import status_bar_updater
from controllers import status_updater
from controllers import exceptions
from controllers import file_listener
from controllers import stripchart_listener

# Global logger init. below.
PRINT = logging.getLogger('output')
DEBUG = logging.getLogger('debug')

class MainPanelFactory:
    """
    This is a concrete factory method object used to create the 
    main UI panel instances for the GSE application.  It is
    also used to destroy and clean up mediator and observer
    associations.
    """
    __parsed   = None
    __instance = None


    def __init__(self, opts):
        """ 
        Private Constructor (singleton pattern) 
        """
        self.__parsed   = None
        self.__instance = None
        self.__window_instance = 0
        self.__configured_visitors = dict()
        self.__opts = opts
        #
        self.__main_panels = dict()
    def getInstance():
        """
        Return instance of singleton.
        """
        if(MainPanelFactory.__instance is None) :
            MainPanelFactory.__instance = MainPanelFactory()
        
        return MainPanelFactory.__instance


    #define static method
    getInstance = staticmethod(getInstance)


    def getOpts(self):
        """
        Return Options Parsed.
        """
        return self.__opts


    def create(self, root, top=True):
        """
        Create a main panel here.
        """
        #
        # Load and initialize commands here.
        # Read in generated command modules here and instance Command objects
        #
        cmdl = command_loader.CommandLoader.getInstance()
        #
        # Load and initialize event log messages here.
        #
        eventl = event_loader.EventLoader.getInstance()
        #
        # Load and initialize channel telemetry here.
        #
        channell = channel_loader.ChannelLoader.getInstance()
        #
        # Read all the command/event/channel telemetry, etc.
        if top:
            try:
                # add path for serializables
                sys.path.append(self.__opts.generated_path + os.sep + "serializable")
                
                sys.path.append(self.__opts.generated_path)
                generated_path1 = self.__opts.generated_path + os.sep + "commands"
                cmdl.create(generated_path1)
                generated_path2 = self.__opts.generated_path + os.sep + "events"
                eventl.create(generated_path2)
                generated_path3 = self.__opts.generated_path + os.sep + "channels"
                channell.create(generated_path3)
            
            except exceptions.GseControllerUndefinedDirectoryException, e:
                sys.stderr.write(e.getMsg())
                sys.stderr.write("\n\nPlease specify the correct dictionary location")
                sys.stderr.write("\nvia the command line or a gse.ini file.\n\n")

                gse_path = None
                if 'BUILD_ROOT' in os.environ:
                    gse_path = os.environ['BUILD_ROOT'] + os.sep + "Gse" + os.sep + "bin" + os.sep + "gse.py"
                elif './bin' in glob.glob("./*"):
                    gse_path = "./bin/gse.py"
                elif "../bin" in glob.glob("../*"):
                    gse_path = "../bin/gse.py"
                elif "./Gse" in glob.glob("./*"):
                    gse_path = "./Gse/bin/gse.py"

                if gse_path:
                    cmd = "python {} --help".format(gse_path)
                    os.system(cmd)
                
                sys.exit(-1)

        #
        the_panel = main_panel.TopPanel(root, self.__opts, self.__window_instance, top=top)
        the_panel.configureStyle()
        # Register this call with the main panel so new instances can be created.
        the_panel.register(self)

        # Hold references to main panels here
        self.__main_panels[self.__window_instance] = the_panel

        #
        # Populate each panel with widgets for the instance.
        #
        
        #
        # Create status bar and updater
        #
        stat_bar_updater = status_bar_updater.StatusBarUpdater.getInstance()
        stat_bar = status_bar.StatusBar(root, bg="lightblue")
        stat_bar_updater.observers_add(stat_bar)
        # Register with main panel
        the_panel.register_panel(stat_bar)
        # Register help balloon with top
        if top == True:
            stat_bar_updater.register_balloon(root)


        cmd_panel = command_panel.CommandPanel(the_panel.p1(), the_panel, self.__opts)
        the_panel.register_panel(cmd_panel)
        #
        logger_panel = log_event_panel.LogEventPanel(the_panel.p2(), the_panel, self.__opts)
        the_panel.register_panel(logger_panel)
        #
        telm_panel = telemetry_panel.TelemetryPanel(the_panel.p3(), the_panel, self.__opts)
        root.after(100, telm_panel.refresh())
        the_panel.register_refreshable(telm_panel)
        #
        sequencer_panel = seq_panel.SeqPanel(the_panel.p4(), the_panel)
        the_panel.register_seq_panel(sequencer_panel)
        

        #
        # Create an event_listener thread and periodic updater here.
        # This will receive messages and update whatever panels are
        # instanced.
        #
        time_period = 200
        ev_listen = event_listener.EventListener.getInstance()
        ev_listen.observers_add(logger_panel)
        if top == True:
            ev_listen.setupLogging(self.__opts)
        #
        # This will set up logging of the raw data from the socket if
        # command line flag is set.
        #
        if top == True:
            ev_listen.setupBinaryLogging(self.__opts)


        #
        # Create a channelized telemetry listener here. This uses
        # the event_listener thread so when messages are channel
        # telemetry this decodes them and sends the notify to the UI.
        #
        ch_listen = channel_listener.ChannelListener.getInstance()
        ch_listen.observers_add(telm_panel)
        #
        if top == True:
            ev_listen.register_root(root)
            ev_listen.register_main_panel(the_panel)
            id = root.after(time_period, ev_listen.update_task)
            ev_listen.set_after_id(id)
            ch_listen.setupLogging(self.__opts)

        #
        # Create status panel
        #
        stat_panel = status_panel.StatusPanel(the_panel.p8(), the_panel)
        the_panel.register_panel(stat_panel)

        #
        # Get / create a status_updater singlton/observer to 
        # update all status text areas of all instanced panels.
        #
        the_updater = status_updater.StatusUpdater.getInstance()
        the_updater.observers_add(stat_panel)
        if top:
            the_updater.setupLogging(self.__opts)
        #
        # Create File Panel
        #
        f_panel    = file_panel.FilePanel(the_panel.p10(), the_panel, self.__opts)
        f_panel.set_default_upload_folder()
        the_panel.register_panel(f_panel)
        # Add observers to file listener and start listener
        f_listener = file_listener.FileListener.getInstance()
        f_listener.observers_add(f_panel)
        if top:
            f_listener.set_root(root)
            id = root.after(100, f_listener.update_task)
            f_listener.set_after_id(id)
        
        #
        # Create Stripchart panel
        #
        sc_listener = stripchart_listener.StripChartListener.getInstance()
        strip_panel  = stripchart_panel.StripChartPanel(the_panel.p7(), the_panel, self.__opts)
        root.after(100, strip_panel.refresh)
        the_panel.register_refreshable(strip_panel)
        sc_listener.observers_add(strip_panel)
        the_panel.register_panel(strip_panel)

        #
        # Create Help Panel
        #

        h_panel= help_panel.HelpPanel(the_panel.p9(), the_panel)
        the_panel.register_panel(h_panel)

        #
        # Assign commands here
        #
        cmd_panel.setCmdList(cmdl.getCommandDict().keys())
        sequencer_panel.setCmdList(cmdl.getCommandDict().keys())
        
        #
        # Connect cmd_panel to mediator command
        #
        cmdr = commander.Commander.getInstance()
        cmdr.register(cmd_panel, cmdr.cmd_send)

        #
        # Register the root main_panel so we can get the socket object handle
        #
        if top == True:
            cmdr.register_main_panel(the_panel)
        
        #
        # If enabled try and connect to ThreadedTCPSocketServer here...
        #
        if self.__opts.connect == True and top == True:
            the_panel.connectTCP()
            
        self.__window_instance += 1
        return  the_panel

    def childClosing(self):
        """
        Window is closing. 
        Remove main_panel reference so that
        main_panels is always reflective of current state.  
        """
        self.__window_instance -= 1
        self.__main_panels.pop(self.__window_instance, None)

    def id(self):
        return self.__window_instance

    def get_panel_dict(self):
        return self.__main_panels


def main():
    """
    Test of main panel instancing and destroy capability here
    """
    root = Tkinter.Tk()
    #root.option_readfile('optionDB')
    root.title('F Prime Ground Support Equipment')
    Pmw.initialise()
    mpf = MainPanelFactory()
    mpf.create(root)
    
    # This is a quick fix since something 
    # locks the main window event loop.
    w = Tkinter.Toplevel()
    w.destroy()
    
    # MAIN BODY #
    root.geometry("900x900+10+10")
    root.mainloop()


if __name__ == '__main__':
    main()
        

#!/bin/env python
#===============================================================================
# NAME: MainPanelFactory.py
#
# DESCRIPTION: This is a factory class for instancing the main GSE panel.
#                It exists as a singlton and also destroys the toplevel
#                windows as well.
#
# AUTHOR: reder
# EMAIL:  <EMAIL>
# DATE CREATED  : Jan. 11, 2015
#
# Copyright 2015, California Institute of Technology.
# ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged.
#===============================================================================
#
# Python standard modules
#

import os
import sys
import glob
import time
import socket
import logging
import exceptions
import Tkinter
import Pmw
import subprocess


from views import main_panel
from views import command_panel
from views import log_event_panel
from views import telemetry_panel
from views import seq_panel
from views import status_panel
from views import status_bar
from views import file_panel
from views import stripchart_panel
from views import help_panel

from controllers import command_loader
from controllers import commander
from controllers import event_loader
from controllers import event_listener
from controllers import channel_loader
from controllers import channel_listener
from controllers import status_bar_updater
from controllers import status_updater
from controllers import exceptions
from controllers import file_listener
from controllers import stripchart_listener

# Global logger init. below.
PRINT = logging.getLogger('output')
DEBUG = logging.getLogger('debug')

class MainPanelFactory:
    """
    This is a concrete factory method object used to create the 
    main UI panel instances for the GSE application.  It is
    also used to destroy and clean up mediator and observer
    associations.
    """
    __parsed   = None
    __instance = None


    def __init__(self, opts):
        """ 
        Private Constructor (singleton pattern) 
        """
        self.__parsed   = None
        self.__instance = None
        self.__window_instance = 0
        self.__configured_visitors = dict()
        self.__opts = opts
        #
        self.__main_panels = dict()
    def getInstance():
        """
        Return instance of singleton.
        """
        if(MainPanelFactory.__instance is None) :
            MainPanelFactory.__instance = MainPanelFactory()
        
        return MainPanelFactory.__instance


    #define static method
    getInstance = staticmethod(getInstance)


    def getOpts(self):
        """
        Return Options Parsed.
        """
        return self.__opts


    def create(self, root, top=True):
        """
        Create a main panel here.
        """
        #
        # Load and initialize commands here.
        # Read in generated command modules here and instance Command objects
        #
        cmdl = command_loader.CommandLoader.getInstance()
        #
        # Load and initialize event log messages here.
        #
        eventl = event_loader.EventLoader.getInstance()
        #
        # Load and initialize channel telemetry here.
        #
        channell = channel_loader.ChannelLoader.getInstance()
        #
        # Read all the command/event/channel telemetry, etc.
        if top:
            try:
                # add path for serializables
                sys.path.append(self.__opts.generated_path + os.sep + "serializable")
                
                sys.path.append(self.__opts.generated_path)
                generated_path1 = self.__opts.generated_path + os.sep + "commands"
                cmdl.create(generated_path1)
                generated_path2 = self.__opts.generated_path + os.sep + "events"
                eventl.create(generated_path2)
                generated_path3 = self.__opts.generated_path + os.sep + "channels"
                channell.create(generated_path3)
            
            except exceptions.GseControllerUndefinedDirectoryException, e:
                sys.stderr.write(e.getMsg())
                sys.stderr.write("\n\nPlease specify the correct dictionary location")
                sys.stderr.write("\nvia the command line or a gse.ini file.\n\n")

                gse_path = None
                if 'BUILD_ROOT' in os.environ:
                    gse_path = os.environ['BUILD_ROOT'] + os.sep + "Gse" + os.sep + "bin" + os.sep + "gse.py"
                elif './bin' in glob.glob("./*"):
                    gse_path = "./bin/gse.py"
                elif "../bin" in glob.glob("../*"):
                    gse_path = "../bin/gse.py"
                elif "./Gse" in glob.glob("./*"):
                    gse_path = "./Gse/bin/gse.py"

                if gse_path:
                    cmd = "python {} --help".format(gse_path)
                    os.system(cmd)
                
                sys.exit(-1)

        #
        the_panel = main_panel.TopPanel(root, self.__opts, self.__window_instance, top=top)
        the_panel.configureStyle()
        # Register this call with the main panel so new instances can be created.
        the_panel.register(self)

        # Hold references to main panels here
        self.__main_panels[self.__window_instance] = the_panel

        #
        # Populate each panel with widgets for the instance.
        #
        
        #
        # Create status bar and updater
        #
        stat_bar_updater = status_bar_updater.StatusBarUpdater.getInstance()
        stat_bar = status_bar.StatusBar(root, bg="lightblue")
        stat_bar_updater.observers_add(stat_bar)
        # Register with main panel
        the_panel.register_panel(stat_bar)
        # Register help balloon with top
        if top == True:
            stat_bar_updater.register_balloon(root)


        cmd_panel = command_panel.CommandPanel(the_panel.p1(), the_panel, self.__opts)
        the_panel.register_panel(cmd_panel)
        #
        logger_panel = log_event_panel.LogEventPanel(the_panel.p2(), the_panel, self.__opts)
        the_panel.register_panel(logger_panel)
        #
        telm_panel = telemetry_panel.TelemetryPanel(the_panel.p3(), the_panel, self.__opts)
        root.after(100, telm_panel.refresh())
        the_panel.register_refreshable(telm_panel)
        #
        sequencer_panel = seq_panel.SeqPanel(the_panel.p4(), the_panel)
        the_panel.register_seq_panel(sequencer_panel)
        

        #
        # Create an event_listener thread and periodic updater here.
        # This will receive messages and update whatever panels are
        # instanced.
        #
        time_period = 200
        ev_listen = event_listener.EventListener.getInstance()
        ev_listen.observers_add(logger_panel)
        if top == True:
            ev_listen.setupLogging(self.__opts)
        #
        # This will set up logging of the raw data from the socket if
        # command line flag is set.
        #
        if top == True:
            ev_listen.setupBinaryLogging(self.__opts)


        #
        # Create a channelized telemetry listener here. This uses
        # the event_listener thread so when messages are channel
        # telemetry this decodes them and sends the notify to the UI.
        #
        ch_listen = channel_listener.ChannelListener.getInstance()
        ch_listen.observers_add(telm_panel)
        #
        if top == True:
            ev_listen.register_root(root)
            ev_listen.register_main_panel(the_panel)
            id = root.after(time_period, ev_listen.update_task)
            ev_listen.set_after_id(id)
            ch_listen.setupLogging(self.__opts)

        #
        # Create status panel
        #
        stat_panel = status_panel.StatusPanel(the_panel.p8(), the_panel)
        the_panel.register_panel(stat_panel)

        #
        # Get / create a status_updater singlton/observer to 
        # update all status text areas of all instanced panels.
        #
        the_updater = status_updater.StatusUpdater.getInstance()
        the_updater.observers_add(stat_panel)
        if top:
            the_updater.setupLogging(self.__opts)
        #
        # Create File Panel
        #
        f_panel    = file_panel.FilePanel(the_panel.p10(), the_panel, self.__opts)
        f_panel.set_default_upload_folder()
        the_panel.register_panel(f_panel)
        # Add observers to file listener and start listener
        f_listener = file_listener.FileListener.getInstance()
        f_listener.observers_add(f_panel)
        if top:
            f_listener.set_root(root)
            id = root.after(100, f_listener.update_task)
            f_listener.set_after_id(id)
        
        #
        # Create Stripchart panel
        #
        sc_listener = stripchart_listener.StripChartListener.getInstance()
        strip_panel  = stripchart_panel.StripChartPanel(the_panel.p7(), the_panel, self.__opts)
        root.after(100, strip_panel.refresh)
        the_panel.register_refreshable(strip_panel)
        sc_listener.observers_add(strip_panel)
        the_panel.register_panel(strip_panel)

        #
        # Create Help Panel
        #

        h_panel= help_panel.HelpPanel(the_panel.p9(), the_panel)
        the_panel.register_panel(h_panel)

        #
        # Assign commands here
        #
        cmd_panel.setCmdList(cmdl.getCommandDict().keys())
        sequencer_panel.setCmdList(cmdl.getCommandDict().keys())
        
        #
        # Connect cmd_panel to mediator command
        #
        cmdr = commander.Commander.getInstance()
        cmdr.register(cmd_panel, cmdr.cmd_send)

        #
        # Register the root main_panel so we can get the socket object handle
        #
        if top == True:
            cmdr.register_main_panel(the_panel)
        
        #
        # If enabled try and connect to ThreadedTCPSocketServer here...
        #
        if self.__opts.connect == True and top == True:
            the_panel.connectTCP()
            
        self.__window_instance += 1
        return  the_panel

    def childClosing(self):
        """
        Window is closing. 
        Remove main_panel reference so that
        main_panels is always reflective of current state.  
        """
        self.__window_instance -= 1
        self.__main_panels.pop(self.__window_instance, None)

    def id(self):
        return self.__window_instance

    def get_panel_dict(self):
        return self.__main_panels


def main():
    """
    Test of main panel instancing and destroy capability here
    """
    root = Tkinter.Tk()
    #root.option_readfile('optionDB')
    root.title('F Prime Ground Support Equipment')
    Pmw.initialise()
    mpf = MainPanelFactory()
    mpf.create(root)
    
    # This is a quick fix since something 
    # locks the main window event loop.
    w = Tkinter.Toplevel()
    w.destroy()
    
    # MAIN BODY #
    root.geometry("900x900+10+10")
    root.mainloop()


if __name__ == '__main__':
    main()
        

#!/bin/env python #=============================================================================== # NAME: MainPanelFactory.py # # DESCRIPTION: This is a factory class for instancing the main GSE panel. #                It exists as a singlton and also destroys the toplevel #                windows as well. # # AUTHOR: reder # EMAIL:  <EMAIL> # DATE CREATED  : Jan. 11, 2015 # # Copyright 2015, California Institute of Technology. # ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged. #=============================================================================== # # Python standard modules # # Global logger init. below. This is a concrete factory method object used to create the      main UI panel instances for the GSE application.  It is     also used to destroy and clean up mediator and observer     associations. Private Constructor (singleton pattern) # Return instance of singleton. #define static method Return Options Parsed. Create a main panel here. # # Load and initialize commands here. # Read in generated command modules here and instance Command objects # # # Load and initialize event log messages here. # # # Load and initialize channel telemetry here. # # # Read all the command/event/channel telemetry, etc. # add path for serializables # # Register this call with the main panel so new instances can be created. # Hold references to main panels here # # Populate each panel with widgets for the instance. # # # Create status bar and updater # # Register with main panel # Register help balloon with top # # # # # Create an event_listener thread and periodic updater here. # This will receive messages and update whatever panels are # instanced. # # # This will set up logging of the raw data from the socket if # command line flag is set. # # # Create a channelized telemetry listener here. This uses # the event_listener thread so when messages are channel # telemetry this decodes them and sends the notify to the UI. # # # # Create status panel # # # Get / create a status_updater singlton/observer to # update all status text areas of all instanced panels. # # # Create File Panel # # Add observers to file listener and start listener # # Create Stripchart panel # # # Create Help Panel # # # Assign commands here # # # Connect cmd_panel to mediator command # # # Register the root main_panel so we can get the socket object handle # # # If enabled try and connect to ThreadedTCPSocketServer here... # Window is closing.          Remove main_panel reference so that         main_panels is always reflective of current state. Test of main panel instancing and destroy capability here #root.option_readfile('optionDB') # This is a quick fix since something # locks the main window event loop. # MAIN BODY #