Ejemplo n.º 1
0
class MainWindow(QMainWindow):
    def __init__(self, app, translator, parent=None):
        super(MainWindow, self).__init__(parent)

        self._app = app
        self._translator = translator
        app.installTranslator(translator)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self._setup_ui()

    def _setup_ui(self):
        self._hioki_tab = HiokiTab(self.ui.tab)
        self._agilent_tab = AgilentTab(self.ui.tab_2)
        self._normal_tab = NormalTab(self.ui.tab_3)

    def openFile(self):
        '''
        print(__file__) # /Users/kakalin/csv/gui/mainwindow.py
        print (os.path.dirname(__file__)) # /Users/kakalin/csv/gui
        print (os.path.abspath(__file__)) # /Users/kakalin/csv/gui/mainwindow.py
        print (os.path.abspath(os.path.dirname(__file__))) # /Users/kakalin/csv/gui
        print (os.path.dirname(os.path.abspath(__file__))) # /Users/kakalin/csv/gui
        '''

        dir = os.path.dirname(__file__)

        file_name = QFileDialog.getOpenFileName(self, 'Open file', dir)
        print(file_name)
Ejemplo n.º 2
0
    def __init__ (self, app, translator, parent=None):
        super(MainWindow, self).__init__(parent)

        self._app = app
        self._translator = translator
        app.installTranslator(translator)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self._setup_ui()
Ejemplo n.º 3
0
 def __init__(self):
     super(MainWindow, self).__init__()
     self.ui = Ui_MainWindow()
     self.ui.setupUi(self)
     self.cc = ConfigurationController(self)
     self.gc = GameController(self.cc, self.updateTable)
     self.createConnections()
     header = self.ui.tableWidget.horizontalHeader()
     header.setSectionResizeMode(QHeaderView.Stretch)
     header = self.ui.tableWidget.verticalHeader()
     header.setSectionResizeMode(QHeaderView.Stretch)
     self.imgImp = ImageImports()
     self.ui.logoLabel.setPixmap(
         QtGui.QPixmap(self.imgImp.logo).scaledToHeight(200))
     self.updateTable()
Ejemplo n.º 4
0
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.connectActions()

        self.loopProcessor = loopLoader.loopLoader()
        self.logProcessor = logProcessing.logProcess()
        self.runProcessor = Runner.allanandPlots()

        self.filename  = None
        self.filetuple = None

        self.plot_spaceOff = plotSpace.plotSpace()
        self.plot_spaceAllan = plotSpace.plotSpace()
        self.plot_spaceHist = plotSpace.plotSpace()

        self.ui.plotSpace.addWidget(self.plot_spaceOff)
        self.ui.plotSpace_3.addWidget(self.plot_spaceAllan)
        self.ui.plotSpace_2.addWidget(self.plot_spaceHist)

        self.type = 0

        self.sizeOff = 0

        self.numberOFTicks = 0

        self.exceeds = 0

        self.modified = 0
Ejemplo n.º 5
0
    def __init__(self):

        # Initializing window and UI
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowTitle("Time Calculation App")

        # Initializing Results Section
        headers = [
            'Machine', 'Planet', 'Labor (Hrs)', 'Machine Time (Hrs)',
            'Setup (Hrs)', 'Test Run (Hrs)', 'Coating (Hrs)', 'Quantity',
            'Yield', 'Scrap', ''
        ]
        self.results = TableView(headers, self, 0, len(headers))
        self.results.setParent(self.ui.resultsContainer)
        # self.results.setFixedWidth(1265)
        self.results.setFixedWidth(self.ui.resultsContainer.width())
        self.results.setFixedHeight(self.ui.resultsContainer.height())

        # Initialize variables needed
        self.machines = [
            Machine(), Machine(), Machine()
        ]  # TODO: restructure to have planets w workorders in machines
        self.techID = None
        self.theme = 1

        # Initialize pie chart widgets and set theme
        self.initPieCharts()
        self.toggleTheme()

        # Connect Signals and Slots
        self.ui.addWorkOrderButton.clicked.connect(
            lambda: self.showWOInitDialog())
        self.ui.planetConfigButton.clicked.connect(
            lambda: self.showPlanetConfigDialog())
        self.ui.randomButton.clicked.connect(
            lambda: self.loadRandomWorkOrders())
        self.ui.clearButton.clicked.connect(lambda: self.reInit())
        self.ui.themeButton.clicked.connect(lambda: self.toggleTheme())
        self.themeChanged.connect(lambda: self.results.setBG())
        self.ui.actionSave.triggered.connect(self.browseForFile_save)
        self.ui.actionLoad.triggered.connect(self.browseForFile_load)
        self.ui.techIDbutton.toggled.connect(self.setTechID)
        self.connectMachineSignals()
Ejemplo n.º 6
0
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Dialog Open
        self.dialog_open = DialogOpen()
        self.dialog_open.ui.buttonBox.button(
            QDialogButtonBox.Ok).clicked.connect(self.load)

        # Connect MainWindow view/controller to model
        self.model = Model()

        # Connect push buttons to slot functions
        self.ui.pbShowDialogOpen.clicked.connect(self.show_dialog_open)
        self.ui.pbExportFolder.clicked.connect(self.on_pbExportFolder_click)
        self.ui.pbExportTurns.clicked.connect(self.export_turns)
        self.ui.pbExportRoutes.clicked.connect(self.export_routes)
        self.ui.pbExportLinksAndTurnsByOD.clicked.connect(
            self.export_links_and_turns_by_od)
        self.ui.pbEstimateOD.clicked.connect(self.estimate_od)

        # Set numeric validators on objective function weight line inputs.
        double_validator = QDoubleValidator(bottom=0)
        double_validator.setNotation(QDoubleValidator.StandardNotation)

        self.ui.leWeightGEH.setValidator(double_validator)
        self.ui.leWeightODSSE.setValidator(double_validator)
        self.ui.leWeightRouteRatio.setValidator(double_validator)

        # set default weights
        self.ui.leWeightGEH.setText("1")
        self.ui.leWeightODSSE.setText("0")
        self.ui.leWeightRouteRatio.setText("1")

        # Setup graphics view
        self.schematic_scene = schematic_scene.SchematicScene()
        self.ui.gvSchematic.setScene(self.schematic_scene)
        self.ui.gvSchematic.setRenderHints(QPainter.Antialiasing)

        # Set table behaviors
        self.ui.tblOD.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.ui.tblOD.setSelectionMode(QAbstractItemView.SingleSelection)
Ejemplo n.º 7
0
class MainWindow(QMainWindow):
    def __init__(self, app, translator, parent=None):
        super(MainWindow, self).__init__(parent)

        self._app = app
        self._translator = translator
        app.installTranslator(translator)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self._setup_ui()

    def _setup_ui(self):
        ''' '''
        self._tab = AnalysisTab(self.ui.tab)

    def openFile(self):
        dir = os.path.dirname(__file__)
        file_name, _ = QFileDialog.getOpenFileName(self, 'Open file', dir)
Ejemplo n.º 8
0
    def __init__(self, app, translators, parent=None):
        super(Mainwindow, self).__init__(parent)
        self._language = menubar_actions.LANGUAGE_IDS["English"]
        self._current_selected_model = None
        self._current_available_datasets = None
        self._current_selected_dataset = None
        self.api = FMIApi()
        self._settings = Settings()
        self._csvexport = CsvExport(self)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self._set_up_ui()
        self._app = app
        self._translators = translators
        self.update_checker = CheckUpdatesOnStartup(self._settings)

        app_icon = QIcon()
        app_icon.addFile('icon.ico')
        app.setWindowIcon(app_icon)
Ejemplo n.º 9
0
class MainWindow(QMainWindow):
    def __init__ (self, app, translator, parent=None):
        super(MainWindow, self).__init__(parent)

        self._app = app
        self._translator = translator
        app.installTranslator(translator)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self._setup_ui()
    
    def _setup_ui(self):
        """ """
        self._uart = SerialTab(self.ui.tab)
        self._modbus = ModbusTab(self.ui.tab_2)

    def openFile(self):
        dir = os.path.dirname(__file__)

        file_name = QFileDialog.getOpenFileName(self, 'Open file', dir)
        print(file_name)
Ejemplo n.º 10
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.cc = ConfigurationController(self)
        self.gc = GameController(self.cc, self.updateTable)
        self.createConnections()
        header = self.ui.tableWidget.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.Stretch)
        header = self.ui.tableWidget.verticalHeader()
        header.setSectionResizeMode(QHeaderView.Stretch)
        self.imgImp = ImageImports()
        self.ui.logoLabel.setPixmap(
            QtGui.QPixmap(self.imgImp.logo).scaledToHeight(200))
        self.updateTable()

    def createConnections(self):
        self.ui.fightModeAButton.pressed.connect(self.setFightModeA)
        self.ui.fightModeBButton.pressed.connect(self.setFightModeB)
        self.ui.fightModeCButton.pressed.connect(self.setFightModeC)
        self.ui.fightModeDButton.pressed.connect(self.setFightModeD)
        self.ui.fightModeEButton.pressed.connect(self.setFightModeE)
        self.ui.fightModeFButton.pressed.connect(self.setFightModeF)

        self.ui.toggleControlledDamageButton.pressed.connect(
            self.toggleControlledDamage)
        self.ui.toggleSkillsButton.pressed.connect(self.toggleSkills)
        self.ui.changePartySkillButton.pressed.connect(self.changeSkills)
        self.ui.toggleUltButton.pressed.connect(self.toggleUlt)
        self.ui.changeHeroSkillButton.pressed.connect(self.changeUlt)
        self.ui.toggleSummonsButton.pressed.connect(self.toggleSummons)

        self.ui.toggleRunButton.pressed.connect(self.toggleRun)

    def toggleRun(self):
        if all(not thread.isAlive() for thread in threads):
            t = Run(ConCon=self.cc, GameCon=self.gc)
            t.setDaemon(True)
            threads.append(t)
            t.start()
        self.cc.toggleRun()
        self.updateTable()

    def setFightModeA(self):
        self.cc.setFightModeA()
        self.updateTable()

    def setFightModeB(self):
        self.cc.setFightModeB()
        self.updateTable()

    def setFightModeC(self):
        self.cc.setFightModeC()
        self.updateTable()

    def setFightModeD(self):
        self.cc.setFightModeD()
        self.updateTable()

    def setFightModeE(self):
        self.cc.setFightModeE()
        self.updateTable()

    def setFightModeF(self):
        self.cc.setFightModeF()
        self.updateTable()

    def toggleControlledDamage(self):
        self.cc.toggleControlledDamage()
        self.updateTable()

    def toggleSkills(self):
        self.cc.toggleSkills()
        self.updateTable()

    def toggleUlt(self):
        self.cc.toggleUlt()
        self.updateTable()

    def toggleSummons(self):
        self.cc.toggleSummons()
        self.updateTable()

    def changeSkills(self):
        self.cc.changeSkills()
        self.updateTable()

    def changeUlt(self):
        self.cc.changeUlt()
        self.updateTable()

    def updateTable(self):
        self.ui.tableWidget.setItem(0, 0, QTableWidgetItem("Enable Skills"))
        self.ui.tableWidget.setItem(
            0, 1, QTableWidgetItem(str(self.cc.configs.enableSkills)))
        self.ui.tableWidget.setItem(0, 2,
                                    QTableWidgetItem("Party Skill Selected"))
        self.ui.tableWidget.setItem(
            0, 3, QTableWidgetItem(str(self.cc.configs.ptSkillSelected)))
        self.ui.tableWidget.setItem(0, 4, QTableWidgetItem("Enable Ult"))
        self.ui.tableWidget.setItem(
            0, 5, QTableWidgetItem(str(self.cc.configs.enableUlt)))
        self.ui.tableWidget.setItem(0, 6,
                                    QTableWidgetItem("Hero Skill Selected"))
        self.ui.tableWidget.setItem(
            0, 7, QTableWidgetItem(str(self.cc.configs.heroSkillSelected)))
        self.ui.tableWidget.setItem(1, 0,
                                    QTableWidgetItem("Controlled Damage"))
        self.ui.tableWidget.setItem(
            1, 1, QTableWidgetItem(str(self.cc.configs.controlledDamage)))
        self.ui.tableWidget.setItem(1, 2, QTableWidgetItem("Summon Bosses"))
        self.ui.tableWidget.setItem(
            1, 3, QTableWidgetItem(str(self.cc.configs.summonBosses)))
        self.ui.tableWidget.setItem(1, 4, QTableWidgetItem("Run Status"))
        self.ui.tableWidget.setItem(1, 5,
                                    QTableWidgetItem(str(self.cc.configs.run)))
        self.ui.tableWidget.setItem(1, 6, QTableWidgetItem("Boss Kills"))
        self.ui.tableWidget.setItem(
            1, 7, QTableWidgetItem(str(self.gc.stats.killCount)))
        self.ui.tableWidget.setItem(2, 0, QTableWidgetItem("Cell (2,0)"))
        self.ui.tableWidget.setItem(2, 1, QTableWidgetItem("Cell (2,1)"))
        self.ui.tableWidget.setItem(2, 2, QTableWidgetItem("Cell (2,2)"))
        self.ui.tableWidget.setItem(2, 3, QTableWidgetItem("Cell (2,3)"))
        self.ui.tableWidget.setItem(2, 4, QTableWidgetItem("Cell (2,4)"))
        self.ui.tableWidget.setItem(2, 5, QTableWidgetItem("Cell (2,5)"))
        self.ui.tableWidget.setItem(2, 6, QTableWidgetItem("Cell (2,6)"))
        self.ui.tableWidget.setItem(2, 7, QTableWidgetItem("Cell (2,7)"))
        self.ui.tableWidget.setItem(3, 0, QTableWidgetItem("Cell (3,0)"))
        self.ui.tableWidget.setItem(3, 1, QTableWidgetItem("Cell (3,1)"))
        self.ui.tableWidget.setItem(3, 2, QTableWidgetItem("Cell (3,2)"))
        self.ui.tableWidget.setItem(3, 3, QTableWidgetItem("Cell (3,3)"))
        self.ui.tableWidget.setItem(3, 4, QTableWidgetItem("Cell (3,4)"))
        self.ui.tableWidget.setItem(3, 5, QTableWidgetItem("Cell (3,5)"))
        self.ui.tableWidget.setItem(3, 6, QTableWidgetItem("Cell (3,6)"))
        self.ui.tableWidget.setItem(3, 7, QTableWidgetItem("Cell (3,7)"))
Ejemplo n.º 11
0
 def __init__(self):
     super(MainWindow, self).__init__()
     self.ui = Ui_MainWindow()
     self.ui.setupUi(self)
Ejemplo n.º 12
0
class Mainwindow(QMainWindow):
    # signals
    setLanguageSignal = pyqtSignal(name="setLanguage")
    entrySelectedSignal = pyqtSignal(dict, name="entrySelected")

    def __init__(self, app, translators, parent=None):
        super(Mainwindow, self).__init__(parent)
        self._language = menubar_actions.LANGUAGE_IDS["English"]
        self._current_selected_model = None
        self._current_available_datasets = None
        self._current_selected_dataset = None
        self.api = FMIApi()
        self._settings = Settings()
        self._csvexport = CsvExport(self)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self._set_up_ui()
        self._app = app
        self._translators = translators
        self.update_checker = CheckUpdatesOnStartup(self._settings)

        app_icon = QIcon()
        app_icon.addFile('icon.ico')
        app.setWindowIcon(app_icon)

    def show(self):
        """ Override so that we can show possible settings dialogs right after startup """
        super(Mainwindow, self).show()
        self._settings.load_qsettings(self)

    def set_language(self, language):
        """ Set the language of the UI """
        self._language = language
        self._app.installTranslator(self._translators[language])
        if self._current_available_datasets is not None:
            self._set_available_datasets_from_catalogue(
                self._current_available_datasets)

    def changeEvent(self, event):
        if event.type() == QEvent.LanguageChange:
            self.ui.retranslateUi(self)
        super(Mainwindow, self).changeEvent(event)

    def _set_up_station_comboboxes(self):
        """ Set station names for combobox. Configure completion."""
        self.ui.stationComboBox.clear()
        stations = self.api.get_stations()
        completer_strings = []
        for s in stations:
            self.ui.stationComboBox.addItem(s["Name"])
            completer_strings.append(s["Name"])
        self.comboboxCompleter = QCompleter(completer_strings, self)
        self.comboboxCompleter.setCompletionMode(0)
        self.ui.stationComboBox.setCompleter(self.comboboxCompleter)

        # Select Lammi as a first station but do not run the selection logic on first run
        self.ui.stationComboBox.setCurrentIndex(
            self.api.get_index_of_station("Hämeenlinna Lammi Pappila"))
        self._current_selected_model = self.api.get_stations()[
            self.api.get_index_of_station("Hämeenlinna Lammi Pappila")]
        self.ui.stationComboBox.currentIndexChanged.connect(
            self._select_place_from_combobox)

    def _background_fmicatalogue_error(self, err):
        """
        Handle errors which happened in fmi catalogue retrieval background thread. This is a
        error callback function provided for BackgroundTask class on construction.
        :param err:
        :return:
        """
        if err.error_code == 'NODATASETS':
            self.show_error_alerts(Messages.no_datasets_found())
        elif err.error_code == 'METADATA_RETRIEVAL':
            self.show_error_alerts(Messages.fmicatalogue_error())
        else:
            self.show_error_alerts(Messages.unknown_error() + str(err))

        self._current_available_datasets = None
        self._current_selected_dataset = None
        self.ui.dataSelectionCombobox.clear()
        self._set_ui_controls_status()

    def _set_ui_controls_status(self):
        active = self._current_selected_dataset is not None
        self.ui.downloadButton.setEnabled(active)
        self.ui.endDatetimeEdit.setEnabled(active)
        self.ui.startDatetimeEdit.setEnabled(active)

    def _set_up_ui(self):
        # language change signal
        self.setLanguageSignal.connect(
            lambda: menubar_actions.select_language(self, self._settings))

        self._set_up_station_comboboxes()
        self.catalogue_task = BackgroundTask()
        self.catalogue_task.start(self.api.get_catalogue_of_station,
                                  self._current_selected_model['FMISID'],
                                  self._set_available_datasets_from_catalogue,
                                  self._background_fmicatalogue_error)

        # When dataset is selected
        self.ui.dataSelectionCombobox.currentIndexChanged.connect(
            self._select_dataset_from_combobox)

        # wire download buttons to actions
        self.ui.downloadButton.clicked.connect(self._download)

        # wire date fields to their actions
        self.ui.endDatetimeEdit.dateChanged.connect(self._date_edited)
        self.ui.startDatetimeEdit.dateChanged.connect(self._date_edited)

        # statusbar
        self.statusBar().setStyleSheet("color: red;")

        # menubar actions
        self.ui.actionSet_api_key.triggered.connect(
            lambda: menubar_actions.set_apikey(self, self._settings))
        self.ui.actionExit.triggered.connect(menubar_actions.quit)
        self.ui.actionAbout.triggered.connect(menubar_actions.about)
        self.ui.actionSet_language.triggered.connect(
            lambda: menubar_actions.select_language(self, self._settings))
        self.ui.actionView_instructions.triggered.connect(
            menubar_actions.open_manual)
        self.ui.actionCheck_updates.triggered.connect(
            lambda: menubar_actions.check_updates(self._settings))

    @pyqtSlot(int, name='selectPlace')
    def _select_place_from_combobox(self, place_index):
        self.ui.stationComboBox.setCurrentIndex(place_index)
        self._current_selected_model = self.api.get_stations()[place_index]

        # Fetch catalog information of the current station and set datasets on completion
        self.catalogue_task.start(self.api.get_catalogue_of_station,
                                  self._current_selected_model['FMISID'],
                                  self._set_available_datasets_from_catalogue,
                                  self._background_fmicatalogue_error)

    def _set_available_datasets_from_catalogue(self, available_datasets):
        """
        Catalogue fetch completed, update contents of dataset combobox with fetched.
        :param available_datasets:
        :return:
        """
        self._current_available_datasets = available_datasets
        self.ui.dataSelectionCombobox.clear()
        for q in available_datasets:
            self.ui.dataSelectionCombobox.addItem(q["name"][self._language])
        self.ui.dataSelectionCombobox.setCurrentIndex(0)
        self._current_selected_dataset = self._current_available_datasets[0]
        self._set_ui_controls_status()
        self._set_time_field_limits()

    @pyqtSlot(int, name='selectDataset')
    def _select_dataset_from_combobox(self, dataset_index):
        """
        When new dataset is selected, update time data.
        :param dataset_index:
        :return:
        """
        if self._current_available_datasets is not None:
            self._current_selected_dataset = self._current_available_datasets[
                dataset_index]
            self.ui.availableFromContent.setText(
                datetime.datetime.strftime(
                    self._current_selected_dataset["starttime"], '%d.%m.%Y'))
            self._set_time_field_limits()

    def _set_time_field_limits(self):
        # minimum date
        self.ui.startDatetimeEdit.clearMinimumDate()
        min_date = QDate(self._current_selected_dataset["starttime"])
        self.ui.startDatetimeEdit.setMinimumDate(min_date)

        self.ui.endDatetimeEdit.clearMinimumDate()
        min_date = QDate(self._current_selected_dataset["starttime"])
        self.ui.endDatetimeEdit.setMinimumDate(min_date)

        # maximum date
        self.ui.startDatetimeEdit.clearMaximumDate()
        if self._current_selected_dataset["endtime"] is not None:
            max_date = QDate(self._current_selected_dataset["endtime"])
        else:
            max_date = QDate(datetime.datetime.now().year,
                             datetime.datetime.now().month,
                             datetime.datetime.now().day)
        self.ui.startDatetimeEdit.setMaximumDate(max_date)

        self.ui.endDatetimeEdit.clearMaximumDate()
        if self._current_selected_dataset["endtime"] is not None:
            max_date = QDate(self._current_selected_dataset["endtime"])
        else:
            max_date = QDate(datetime.datetime.now().year,
                             datetime.datetime.now().month,
                             datetime.datetime.now().day)
        self.ui.endDatetimeEdit.setMaximumDate(max_date)

        new_date = QDate(self.ui.startDatetimeEdit.date().year(),
                         self.ui.startDatetimeEdit.date().month(),
                         self.ui.startDatetimeEdit.date().day() + 1)
        self.ui.endDatetimeEdit.setDate(new_date)

        if self.ui.startDatetimeEdit.date(
        ) < self.ui.startDatetimeEdit.minimumDate():
            self.ui.startDatetimeEdit.setDate(
                self.ui.startDatetimeEdit.minimumDate())

    def _choose_place_to_save_data(self, dataframe):
        paths = QStandardPaths.standardLocations(0)
        if len(paths) > 0:
            path = paths[0]
        else:
            path = ""
        filename = QFileDialog.getSaveFileName(
            self, Messages.save_weatherdata_csv(), path + "/weather_data.csv",
            "Comma separated values CSV (*.csv);;All files (*)")
        if filename[0] != "":
            self._save_to_csv(dataframe, filename[0])

    def _get_date_time_from_ui(self, dateEdit, onlyDate=True):
        if onlyDate:
            return QDateTime(dateEdit.date()).toPyDateTime()
        else:
            return QDateTime(dateEdit.dateTime()).toPyDateTime()

    @pyqtSlot(name='editRealtimeDate')
    def _date_edited(self):
        """
        Date fields were edited. Check their content for invalid date ranges.
        :return:
        """
        if self.ui.startDatetimeEdit.date() == self.ui.endDatetimeEdit.date():
            self.ui.startDatetimeEdit.setStyleSheet(
                "background-color: #FC9DB7;")
            self.ui.endDatetimeEdit.setStyleSheet("background-color: #FC9DB7;")
            self.statusBar().showMessage(Messages.start_end_date_warning(),
                                         5000)
            self.ui.downloadButton.setEnabled(False)
        else:
            self.ui.startDatetimeEdit.setStyleSheet("background-color: white;")
            self.ui.endDatetimeEdit.setStyleSheet("background-color: white;")
            self.ui.downloadButton.setEnabled(True)

            if self.ui.endDatetimeEdit.date() < self.ui.startDatetimeEdit.date(
            ):
                self.ui.endDatetimeEdit.setStyleSheet(
                    "background-color: #FC9DB7;")
                self.statusBar().showMessage(Messages.end_date_warning(), 5000)
                self.ui.downloadButton.setEnabled(False)
            else:
                self.ui.endDatetimeEdit.setStyleSheet(
                    "background-color: white;")
                self.statusBar().showMessage("", 50)
                self.ui.downloadButton.setEnabled(True)

    def _download(self):
        """ Download weather data"""
        params = {
            "request":
            self._current_selected_dataset["request"],
            "storedquery_id":
            self._current_selected_dataset["storedquery_id"],
            "fmisid":
            self._current_selected_model["FMISID"],
            "starttime":
            self._get_date_time_from_ui(self.ui.startDatetimeEdit,
                                        onlyDate=False),
            "endtime":
            self._get_date_time_from_ui(self.ui.endDatetimeEdit,
                                        onlyDate=False),
            "max_hours_range":
            self._current_selected_dataset["max_hours_range"]
        }

        download = DownloadProgress(self)
        download.finishedSignal.connect(self._csvexport.save_data_to_csv)
        download.begin_download(params, self.api.get_data)

    def show_error_alerts(self, message):
        msgbox = QMessageBox()
        msgbox.information(self, "ERROR", message)
        msgbox.show()
Ejemplo n.º 13
0
class MainWindow(QMainWindow):
    """Main window presented to the user when the program first starts."""
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Dialog Open
        self.dialog_open = DialogOpen()
        self.dialog_open.ui.buttonBox.button(
            QDialogButtonBox.Ok).clicked.connect(self.load)

        # Connect MainWindow view/controller to model
        self.model = Model()

        # Connect push buttons to slot functions
        self.ui.pbShowDialogOpen.clicked.connect(self.show_dialog_open)
        self.ui.pbExportFolder.clicked.connect(self.on_pbExportFolder_click)
        self.ui.pbExportTurns.clicked.connect(self.export_turns)
        self.ui.pbExportRoutes.clicked.connect(self.export_routes)
        self.ui.pbExportLinksAndTurnsByOD.clicked.connect(
            self.export_links_and_turns_by_od)
        self.ui.pbEstimateOD.clicked.connect(self.estimate_od)

        # Set numeric validators on objective function weight line inputs.
        double_validator = QDoubleValidator(bottom=0)
        double_validator.setNotation(QDoubleValidator.StandardNotation)

        self.ui.leWeightGEH.setValidator(double_validator)
        self.ui.leWeightODSSE.setValidator(double_validator)
        self.ui.leWeightRouteRatio.setValidator(double_validator)

        # set default weights
        self.ui.leWeightGEH.setText("1")
        self.ui.leWeightODSSE.setText("0")
        self.ui.leWeightRouteRatio.setText("1")

        # Setup graphics view
        self.schematic_scene = schematic_scene.SchematicScene()
        self.ui.gvSchematic.setScene(self.schematic_scene)
        self.ui.gvSchematic.setRenderHints(QPainter.Antialiasing)

        # Set table behaviors
        self.ui.tblOD.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.ui.tblOD.setSelectionMode(QAbstractItemView.SingleSelection)

    def show_dialog_open(self) -> None:
        self.dialog_open.store_data()
        self.dialog_open.show()

    def load(self) -> None:
        """Load nodes, links, etc from user inputs."""
        file_paths = self.dialog_open.get_data()

        load_successful = self.model.load(node_file=file_paths.nodes,
                                          links_file=file_paths.links,
                                          od_seed_file=file_paths.seed_od,
                                          turns_file=file_paths.turns,
                                          od_routes_file=file_paths.routes)
        if load_successful:
            self.schematic_scene.load_network(self.model.get_node_xy(),
                                              self.model.get_link_end_ids())

            # Set scene rectangle to something larger than the network.
            # This helps with panning & zooming near the edges of the network.
            init_rect = self.schematic_scene.sceneRect()
            self.schematic_scene.setSceneRect(init_rect.x() - 100000,
                                              init_rect.y() - 100000,
                                              init_rect.width() + 200000,
                                              init_rect.height() + 200000)

            self.ui.gvSchematic.fitInView(init_rect, Qt.KeepAspectRatio)

            # Flip y coordinates to make y coordinates increasing from bottom to top.
            self.ui.gvSchematic.scale(1, -1)

            routes = self.model.get_route_list()
            self.od_table_model = od_tablemodel.ODTableModel(routes)
            self.ui.tblOD.setModel(self.od_table_model)
            self.ui.tblOD.selectionModel().selectionChanged.connect(
                self.on_od_table_selection)

            self.schematic_scene.load_routes(routes)

    def on_pbExportFolder_click(self) -> None:
        """Open a standard file dialog for selecting the export folder."""
        export_folder = QFileDialog.getExistingDirectory(
            self,
            "Select Export Folder",
            "",
            options=QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)

        self.ui.leExportFolder.setText(export_folder)

    def export_turns(self) -> None:
        """Export turns to csv."""
        self.model.export_turns(self.ui.leExportFolder.text())

    def export_routes(self) -> None:
        """Export nodes on each route."""
        self.model.export_route_list(self.ui.leExportFolder.text())

    def export_links_and_turns_by_od(self) -> None:
        """Export links and turns along each OD pair."""
        self.model.export_node_sequence(self.ui.leExportFolder.text())

    def estimate_od(self) -> None:
        """Run OD matrix estimation."""

        self.model.estimate_od(
            weight_total_geh=float(self.ui.leWeightGEH.text()),
            weight_odsse=float(self.ui.leWeightODSSE.text()),
            weight_route_ratio=float(self.ui.leWeightRouteRatio.text()))

        self.model.export_od(self.ui.leExportFolder.text())
        self.model.export_od_by_route(self.ui.leExportFolder.text())

    def on_od_table_selection(self, selected, deselected) -> None:
        """Function called when an item in the OD Table is selected.

        Parameters
        ----------
        selected : QItemSelection
            Currently selected item from the selectionModel.
        deselected : QItemSelection
            Items from the selectionModel that were previously selected, but 
            are no longer selected.
        """
        # boolean flag to indicate if the table selection affects schematic_scene
        should_update_scene = False

        if len(deselected.indexes()) > 0:
            route = self.od_table_model.get_route_at_index(
                deselected.indexes()[0])
            self.schematic_scene.color_route(route, is_selected=False)
            should_update_scene = True

        if len(selected.indexes()) > 0:
            # Get route for first selected OD pair
            route = self.od_table_model.get_route_at_index(
                selected.indexes()[0])
            self.schematic_scene.color_route(route, is_selected=True)
            should_update_scene = True

        if should_update_scene:
            self.schematic_scene.update()
Ejemplo n.º 14
0
class MainWindow(QMainWindow):

    themeChanged = Signal(int)

    def __init__(self):

        # Initializing window and UI
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowTitle("Time Calculation App")

        # Initializing Results Section
        headers = [
            'Machine', 'Planet', 'Labor (Hrs)', 'Machine Time (Hrs)',
            'Setup (Hrs)', 'Test Run (Hrs)', 'Coating (Hrs)', 'Quantity',
            'Yield', 'Scrap', ''
        ]
        self.results = TableView(headers, self, 0, len(headers))
        self.results.setParent(self.ui.resultsContainer)
        # self.results.setFixedWidth(1265)
        self.results.setFixedWidth(self.ui.resultsContainer.width())
        self.results.setFixedHeight(self.ui.resultsContainer.height())

        # Initialize variables needed
        self.machines = [
            Machine(), Machine(), Machine()
        ]  # TODO: restructure to have planets w workorders in machines
        self.techID = None
        self.theme = 1

        # Initialize pie chart widgets and set theme
        self.initPieCharts()
        self.toggleTheme()

        # Connect Signals and Slots
        self.ui.addWorkOrderButton.clicked.connect(
            lambda: self.showWOInitDialog())
        self.ui.planetConfigButton.clicked.connect(
            lambda: self.showPlanetConfigDialog())
        self.ui.randomButton.clicked.connect(
            lambda: self.loadRandomWorkOrders())
        self.ui.clearButton.clicked.connect(lambda: self.reInit())
        self.ui.themeButton.clicked.connect(lambda: self.toggleTheme())
        self.themeChanged.connect(lambda: self.results.setBG())
        self.ui.actionSave.triggered.connect(self.browseForFile_save)
        self.ui.actionLoad.triggered.connect(self.browseForFile_load)
        self.ui.techIDbutton.toggled.connect(self.setTechID)
        self.connectMachineSignals()

    @Slot(bool)
    def setTechID(self, checked):
        """
        If checked, sets the techID if valid and disables text field.
        Otherwise, re-enable the text field.
        """
        txtField = self.ui.techID
        if checked:
            txt = txtField.text()
            try:
                self.techID = int(txt)
                txtField.setReadOnly(True)
                palette = QPalette()
                palette.setColor(QPalette.Button, Qt.darkGreen)
                palette.setColor(QPalette.ButtonText, Qt.white)
                palette.setColor(QPalette.Base, QColor(100, 143, 100))
                txtField.setPalette(palette)
                self.ui.techIDbutton.setPalette(palette)
            except:
                title = "Error"
                message = "Technician ID must be an integer number."
                buttons = QMessageBox.Ok
                message = QMessageBox(QMessageBox.Warning,
                                      title,
                                      message,
                                      buttons=buttons,
                                      flags=Qt.Dialog)
                message.exec_()
                self.ui.techIDbutton.setChecked(False)
                self.techID = None
                return
        else:
            self.techID = None
            txtField.setReadOnly(False)
            palette = QPalette()
            if self.theme is 0:
                palette.setColor(QPalette.Button, QColor(180, 180, 180))
                palette.setColor(QPalette.ButtonText, Qt.black)
                palette.setColor(QPalette.Base, QColor(140, 140, 140))
            else:
                palette.setColor(QPalette.Button, QColor(53, 53, 53))
                palette.setColor(QPalette.Base, QColor(25, 25, 25))
            txtField.setPalette(palette)
            self.ui.techIDbutton.setPalette(palette)

    def initPieCharts(self):
        """
        Initializes pie chart widgets in 3 tabs.

        Not static: needs the self variable, but it is hidden as a string.
        Uses QtCharts, Planet, and QPainter imports.
        """
        for i in range(1, 2):  # Tab number: i
            for j in range(1, 6):  # Planet number: j

                # Generate the necessary widgets' names
                pieNum = "pie" + str(j)
                infoSect = "self.ui.infoP" + str(j)
                planetBox = "self.ui.planet" + str(j) + "Box"
                widName = pieNum + "Container"
                selfSeries = "self.ui." + pieNum + "series"
                if i in [2, 3]:
                    selfSeries += "_" + str(i)
                    widName += "_" + str(i)
                    infoSect += "_" + str(i)
                    planetBox += "_" + str(i)

                # Initialize commonly used custom strs
                selfChart = "self.ui." + pieNum + "chart"
                selfChartView = selfChart + "View"

                # Store custom lines to execute (a list is easier to maintain and edit)
                codeList = [
                    selfChart + " = QtCharts.QChart()",
                    selfChart + ".setTheme(QtCharts.QChart.ChartThemeLight)",
                    selfSeries + " = Planet(" + selfChart + ", self, " +
                    infoSect + ", " + planetBox + ")", selfSeries +
                    ".planetEnabled.connect(self.checkPlanetStatuses)",
                    'self.themeChanged.connect(lambda theme, self=self: ' +
                    selfSeries + '.changeTheme(theme))', selfSeries +
                    ".notEnoughSpaceForWO.connect(self.noSpaceLeftFor)",
                    selfChart + ".addSeries(" + selfSeries + ")",
                    selfChart + ".setBackgroundVisible(False)",
                    selfChart + ".legend().hide()", selfChartView +
                    " = QtCharts.QChartView(" + selfChart + ")",
                    selfChartView + ".setRenderHint(QPainter.Antialiasing)",
                    selfChartView + ".setParent(self.ui." + widName + ")",
                    selfChartView + ".resize(340, 340)",
                    selfChartView + ".move(-52, -52)"
                ]

                # Convert list to string, placing newlines between each command
                code = '\n'.join(codeList)

                # Execute custom code
                exec(code)

    @Slot(WorkOrder)
    def noSpaceLeftFor(self, workOrder: WorkOrder):
        """
        Gives user the option to change workorder's planet, or discard the order.
        """
        title = "Error: No Space Left On Planet"
        message = "There isn't enough space left on the selected planet to add this order.\n" \
                  "An option could be placed here to change the work order's planet, but this hasn't been implemented "\
                  "yet, so the only option at the moment is to discard it. If this is necessary functionality and " \
                  "needs to be implemented, please let me know."
        buttons = QMessageBox.Discard
        message = QMessageBox(QMessageBox.Warning,
                              title,
                              message,
                              buttons=buttons,
                              flags=Qt.Dialog)
        message.exec_()
        self.deleteWorkOrder(workOrder)

    def deleteWorkOrder(self, workOrder):
        """
        Pretty self-explanatory name lol
        """
        self.results.removeRow(workOrder.rowNum)
        self.results.updateRowsFrom(workOrder.rowNum)
        exec("self.ui.pie" + str(workOrder.planetNum) +
             "series.deleteSlice(workOrder.slice)")

    @Slot(QtCharts.QPieSlice)
    def ensureSingleWorkOrder_p(self, mySlice):
        """
        For signals coming from planets, when a slice was just selected.
        Ensures there is only one Work Order selected per machine: the one given.
        Then selects the Work Order's row in the results section.
        """
        wo = mySlice.order
        if not mySlice.selected:
            self.deselectAllSlicesInTab(wo.machineNum,
                                        mySlice=mySlice,
                                        planetNum=wo.planetNum)
            rowPos = wo.rowNum
            self.results.selectRow(rowPos)
        else:
            pie = "self.ui.pie" + str(wo.planetNum) + "series"
            exec(pie + ".clickSlice(mySlice)")

    @Slot(int, int)
    def ensureSingleWorkOrder_r(self, row, col):
        """
        For signals coming from the results section, when a cell of a row is selected.
        Ensures there is only one Work Order selected per machine: the one given.
        Then selects the corresponding slice in the pie charts
        """
        wo = self.results.rowNumToWOMapping[row]
        self.deselectAllSlicesInTab(wo.machineNum,
                                    mySlice=wo.slice,
                                    planetNum=wo.planetNum)

    def deselectAllSlicesInTab(self, tab, mySlice=None, planetNum=None):
        """
        Optional param is the one slice you do want selected.
        Note: Not static. Uses self, but it is hidden as string.
        """
        for j in range(1, 6):  # Planet number: j
            pie = "self.ui.pie" + str(j) + "series"

            if tab in [2, 3]:
                pie += "_" + str(tab)

            exec(pie + ".deselectAll()")

            if mySlice and j == planetNum:
                exec(pie + ".clickSlice(mySlice)")

    @Slot()
    def browseForFile_save(self) -> None:
        """
        Opens a file dialog when the user clicks on the "Save As..." option to choose a file to save to.
        """
        if self.techID:
            fileDialog = QFileDialog()
            fileDialog.setFileMode(QFileDialog.AnyFile)
            fileDialog.setDirectory(os.getcwd())
            fileDialog.setDefaultSuffix(".proj")
            fileDialog.setNameFilter("Project (*.proj)")
            fileDialog.fileSelected.connect(lambda url: self.saveFile(url))
            fileDialog.exec_()
        else:
            title = "Error"
            message = "Must set Technician ID to save project."
            buttons = QMessageBox.Ok
            message = QMessageBox(QMessageBox.Warning,
                                  title,
                                  message,
                                  buttons=buttons,
                                  flags=Qt.Dialog)
            message.exec_()

    @Slot()
    def browseForFile_load(self) -> None:
        """
        Opens a file dialog when the user clicks on the "Save As..." option to choose a file to save to.
        """

        fileDialog = QFileDialog()
        fileDialog.setFileMode(QFileDialog.ExistingFile)
        fileDialog.setDirectory(os.getcwd())
        fileDialog.setNameFilter("Project (*.proj)")
        fileDialog.fileSelected.connect(lambda url: self.loadFile(url))
        fileDialog.exec_()

    def saveFile(self, path):
        """
        Saves data to file, at location "path".
        """
        # Create dictionary first. All we really care about is the work orders, so we'll just save the list of them.
        d = {'techID': self.techID}
        for tab, machine in enumerate(self.machines):
            if tab == 0:  # TODO: change
                d[tab] = {}
                d[tab]['workOrders'] = {}
                for wo in machine.workOrders:
                    d[tab]['workOrders'][wo.name] = [
                        wo.pieces, wo.side, wo.planetNum, wo.yld
                    ]
                d[tab]['startTime'] = machine.startTime
                d[tab]['endTime'] = machine.endTime
                d[tab]['loadTime'] = machine.loadTime
                d[tab]['unloadTime'] = machine.unloadTime
                d[tab]['cdn'] = machine.cdn
                d[tab]['testRun'] = machine.testRun
                d[tab]['coatingRun'] = machine.coatingRun
                d[tab]['loadingRun'] = machine.loadingRun
                d[tab]['setupRun'] = machine.setupRun

                # Storing planets' sum values.
                d[tab]['planets'] = {}

                for planet in range(1, 6):
                    pie = 'self.ui.pie' + str(planet) + 'series'
                    if tab in (1, 2):
                        pie += '_' + str(tab + 1)
                    exec('tmp = ' + pie + '.enabled', locals())
                    if locals()['tmp']:
                        exec('sum = ' + pie + '.sum()', locals())
                        d[tab]['planets'][planet] = locals()['sum']
                    else:
                        d[tab]['planets'][planet] = None

        # Now save to file.
        with open(path, 'wb') as f:
            pickle.dump(d, f)

    def loadFile(self, path):
        """
         Attempts to load the file at path
        """
        error = False
        if path[-5:] == '.proj':
            try:
                # Load dictionary from file
                with open(path, 'rb') as f:
                    p = pickle.Unpickler(f)
                    d = p.load()

                if not p:
                    # file is empty
                    error = True  # Checks if file is empty

                else:
                    self.techID = d['techID']
                    self.ui.techID.setText(str(self.techID))
                    self.ui.techIDbutton.setChecked(True)

                    for tab in range(0, 1):  # TODO: Change
                        machine = self.machines[tab]

                        # Load all values
                        startTime = d[tab]['startTime']
                        endTime = d[tab]['endTime']
                        loadTime = d[tab]['loadTime']
                        unloadTime = d[tab]['unloadTime']
                        cdn = d[tab]['cdn']
                        testRun = d[tab]['testRun']
                        coatingRun = d[tab]['coatingRun']
                        loadingRun = d[tab]['loadingRun']
                        setupRun = d[tab]['setupRun']

                        # Check if they exist
                        if startTime:
                            machine.startTime = startTime

                            time = QTime().fromString(startTime)
                            tmp = 'self.ui.startTime'
                            but = 'self.ui.stButton'
                            if tab in (1, 2):
                                tmp += '_' + str(tab + 1)
                                but += '_' + str(tab + 1)
                            exec(tmp + '.setTime(time)')
                            exec(but + '.setChecked(True)')

                        if endTime:
                            machine.endTime = endTime

                            time = QTime().fromString(endTime)
                            tmp = 'self.ui.endTime'
                            but = 'self.ui.etButton'
                            if tab in (1, 2):
                                tmp += '_' + str(tab + 1)
                                but += '_' + str(tab + 1)
                            exec(tmp + '.setTime(time)')
                            exec(but + '.setChecked(True)')

                        if loadTime:
                            machine.loadTime = loadTime

                            time = QTime().fromString(loadTime)
                            tmp = 'self.ui.loadTime'
                            but = 'self.ui.ltButton'
                            if tab in (1, 2):
                                tmp += '_' + str(tab + 1)
                                but += '_' + str(tab + 1)
                            exec(tmp + '.setTime(time)')
                            exec(but + '.setChecked(True)')

                        if unloadTime:
                            machine.unloadTime = unloadTime

                            time = QTime().fromString(unloadTime)
                            tmp = 'self.ui.unloadTime'
                            but = 'self.ui.utButton'
                            if tab in (1, 2):
                                tmp += '_' + str(tab + 1)
                                but += '_' + str(tab + 1)
                            exec(tmp + '.setTime(time)')
                            exec(but + '.setChecked(True)')

                        if cdn:  # If there's the cdn, the other 4 are there too
                            machine.cdn = cdn
                            machine.testRun = testRun
                            machine.coatingRun = coatingRun
                            machine.loadingRun = loadingRun
                            machine.setupRun = setupRun

                            cdnBox = 'self.ui.cdn'
                            testBox = 'self.ui.testRun'
                            coatBox = 'self.ui.coatRun'
                            loadBox = 'self.ui.loadingRun'
                            setupBox = 'self.ui.setupTestRun'
                            vButton = 'self.ui.validateButton'

                            if tab in (1, 2):
                                cdnBox += '_' + str(tab + 1)
                                testBox += '_' + str(tab + 1)
                                coatBox += '_' + str(tab + 1)
                                loadBox += '_' + str(tab + 1)
                                setupBox += '_' + str(tab + 1)
                                vButton += '_' + str(tab + 1)

                            codeList = [
                                cdnBox + '.setText(str(cdn))',
                                testBox + '.setText(str(testRun))',
                                coatBox + '.setText(str(coatingRun))',
                                loadBox + '.setText(str(loadingRun))',
                                setupBox + '.setText(str(setupRun))',
                                vButton + '.setChecked(True)'
                            ]

                            code = '\n'.join(codeList)
                            exec(code)

                        # Initialize planets
                        for planetNum in d[tab]['planets']:
                            sum = d[tab]['planets'][planetNum]
                            if sum:
                                pie = 'self.ui.pie' + str(planetNum) + 'series'
                                if tab in (1, 2):
                                    pie += '_' + str(tab + 1)
                                exec(pie + '.setEnabled(sum)')

                        sortedWOList = []
                        for woName in d[tab]['workOrders']:
                            params = d[tab]['workOrders'][woName]

                            wo = WorkOrder()
                            wo.name = woName
                            wo.machineNum = tab + 1
                            wo.pieces = params[0]
                            wo.side = params[1]
                            wo.planetNum = params[2]
                            if params[3]:
                                wo.setYield(params[3])

                            sortedWOList.append(wo)
                        sortedWOList.sort(
                            key=lambda workOrder: int(workOrder.name[4:]))

                        unsuccessful = []
                        for wo in sortedWOList:
                            success = self.addToPlanets(wo)
                            if success:
                                self.results.addRowFor(wo)
                                self.machines[wo.machineNum -
                                              1].workOrders.append(wo)
                            else:
                                unsuccessful.append(wo)
                        if unsuccessful:
                            for wo in unsuccessful:
                                print(wo.name)
            except Exception as e:
                raise e
        else:
            # not a proj file
            error = True

        if error:
            title = "Error Loading Project"
            message = "Could not load the selected file successfully."
            buttons = QMessageBox.Ok
            message = QMessageBox(QMessageBox.Warning,
                                  title,
                                  message,
                                  buttons=buttons,
                                  flags=Qt.Dialog)
            message.exec_()

    @Slot(bool)
    def checkPlanetStatuses(self, enabled):
        """
        If a planet is switched to enabled, this unlocks the save as button.
        Otherwise if a planet is switched to disabled, this does a application-wide check to see
        if any other planets are currently enabled. If not, disables the save as button.
        """
        if enabled:
            if not self.ui.actionSave.isEnabled():
                self.ui.actionSave.setEnabled(True)
        else:
            if self.ui.actionSave.isEnabled():
                atLeastOneEnabled = False
                for machine in range(
                        1, 2
                ):  # 3 tabs TODO: Change 1 to 3 when other tabs are implemented
                    for planet in range(1, 6):  # 5 planets
                        pie = "self.ui.pie" + str(planet) + "series"
                        if machine in [2, 3]:
                            pie += "_" + str(machine)
                        if exec(pie + '.enabled'):
                            atLeastOneEnabled = True
                            break
                    if atLeastOneEnabled:
                        break
                if not atLeastOneEnabled:
                    self.ui.actionSave.setEnabled(False)

    def startTimeCheck(self, checked, machine, timeBox, button):
        """
        If the button next to the time is clicked (checked), this handles what to do with the data and gui.
        If it is unchecked, the data is deleted and the timeObject is enabled.
        """
        if checked:
            machine.startTime = timeBox.time().toString()
            timeBox.setReadOnly(True)
            palette = QPalette()
            palette.setColor(QPalette.Button, Qt.darkGreen)
            palette.setColor(QPalette.ButtonText, Qt.white)
            button.setPalette(palette)
            timeBox.setPalette(palette)

        else:
            machine.startTime = None
            timeBox.setReadOnly(False)
            palette = QPalette()
            if self.theme is 0:
                palette.setColor(QPalette.Button, QColor(180, 180, 180))
                palette.setColor(QPalette.ButtonText, Qt.black)
            else:
                palette.setColor(QPalette.Button, QColor(53, 53, 53))
            button.setPalette(palette)
            timeBox.setPalette(palette)

        self.updateResults(machine)

    def endTimeCheck(self, checked, machine, timeBox, button):
        """
        If the button next to the time is clicked (checked), this handles what to do with the data and gui.
        If it is unchecked, the data is deleted and the timeObject is enabled.
        """
        if checked:
            machine.endTime = timeBox.time().toString()
            timeBox.setReadOnly(True)
            palette = QPalette()
            palette.setColor(QPalette.Button, Qt.darkGreen)
            palette.setColor(QPalette.ButtonText, Qt.white)
            button.setPalette(palette)
            timeBox.setPalette(palette)
        else:
            machine.endTime = None
            timeBox.setReadOnly(False)
            palette = QPalette()
            if self.theme is 0:
                palette.setColor(QPalette.Button, QColor(180, 180, 180))
                palette.setColor(QPalette.ButtonText, Qt.black)
            else:
                palette.setColor(QPalette.Button, QColor(53, 53, 53))
            button.setPalette(palette)
            timeBox.setPalette(palette)

        self.updateResults(machine)

    def loadTimeCheck(self, checked, machine, timeBox, button):
        """
        If the button next to the time is clicked (checked), this handles what to do with the data and gui.
        If it is unchecked, the data is deleted and the timeObject is enabled.
        """
        if checked:
            machine.loadTime = timeBox.time().toString()
            timeBox.setReadOnly(True)
            palette = QPalette()
            palette.setColor(QPalette.Button, Qt.darkGreen)
            palette.setColor(QPalette.ButtonText, Qt.white)
            button.setPalette(palette)
            timeBox.setPalette(palette)
        else:
            machine.loadTime = None
            timeBox.setReadOnly(False)
            palette = QPalette()
            if self.theme is 0:
                palette.setColor(QPalette.Button, QColor(180, 180, 180))
                palette.setColor(QPalette.ButtonText, Qt.black)
            else:
                palette.setColor(QPalette.Button, QColor(53, 53, 53))
            button.setPalette(palette)
            timeBox.setPalette(palette)

        self.updateResults(machine)

    def unloadTimeCheck(self, checked, machine, timeBox, button):
        """
        If the button next to the time is clicked (checked), this handles what to do with the data and gui.
        If it is unchecked, the data is deleted and the timeObject is enabled.
        """
        if checked:
            machine.unloadTime = timeBox.time().toString()
            timeBox.setReadOnly(True)
            palette = QPalette()
            palette.setColor(QPalette.Button, Qt.darkGreen)
            palette.setColor(QPalette.ButtonText, Qt.white)
            button.setPalette(palette)
            timeBox.setPalette(palette)
        else:
            machine.unloadTime = None
            timeBox.setReadOnly(False)
            palette = QPalette()
            if self.theme is 0:
                palette.setColor(QPalette.Button, QColor(180, 180, 180))
                palette.setColor(QPalette.ButtonText, Qt.black)
            else:
                palette.setColor(QPalette.Button, QColor(53, 53, 53))
            button.setPalette(palette)
            timeBox.setPalette(palette)

        self.updateResults(machine)

    def validateData(self, checked, tab):
        """
        If checked, loads data from all text fields around validate button, and disables them. Also changes button text.
        Otherwise, enables all fields, clears data, and changes button text back.
        """
        cdnBox = "self.ui.cdn"
        testBox = "self.ui.testRun"
        coatBox = "self.ui.coatRun"
        loadBox = "self.ui.loadingRun"
        setupBox = "self.ui.setupTestRun"
        vButton = "self.ui.validateButton"
        machine = "self.machines[" + str(tab - 1) + "]"
        if tab in (2, 3):
            cdnBox += "_" + str(tab)
            testBox += "_" + str(tab)
            coatBox += "_" + str(tab)
            loadBox += "_" + str(tab)
            setupBox += "_" + str(tab)
            vButton += "_" + str(tab)

        if checked:
            codeList = [
                'cdn = ' + cdnBox + '.text()',
                'testRun = ' + testBox + '.text()',
                'coatingRun = ' + coatBox + '.text()',
                'loadingRun = ' + loadBox + '.text()',
                'setupRun = ' + setupBox + '.text()',
                'locals()["valid"] = self.checkValidity(cdn, testRun, coatingRun, loadingRun, setupRun)'
            ]
            code = '\n'.join(codeList)
            exec(code)

            if locals()["valid"]:
                codeList = [
                    machine + '.cdn = int(' + cdnBox + '.text())',
                    machine + '.testRun = float(' + testBox + '.text())',
                    machine + '.coatingRun = float(' + coatBox + '.text())',
                    machine + '.loadingRun = float(' + loadBox + '.text())',
                    machine + '.setupRun = float(' + setupBox + '.text())',
                    cdnBox + '.setReadOnly(True)', testBox +
                    '.setReadOnly(True)', coatBox + '.setReadOnly(True)',
                    loadBox + '.setReadOnly(True)',
                    setupBox + '.setReadOnly(True)',
                    vButton + '.setText("Unlock")', 'palette = QPalette()',
                    'palette.setColor(QPalette.Button, Qt.darkGreen)',
                    'palette.setColor(QPalette.ButtonText, Qt.white)',
                    'palette.setColor(QPalette.Base, QColor(100, 143, 100))',
                    vButton + '.setPalette(palette)', cdnBox +
                    '.setPalette(palette)', testBox + '.setPalette(palette)',
                    coatBox + '.setPalette(palette)', loadBox +
                    '.setPalette(palette)', setupBox + '.setPalette(palette)'
                ]
            else:
                codeList = [vButton + '.setChecked(False)']
        else:
            palette = QPalette()
            if self.theme is 0:
                palette.setColor(QPalette.Button, QColor(180, 180, 180))
                palette.setColor(QPalette.ButtonText, Qt.black)
                palette.setColor(QPalette.Base, QColor(140, 140, 140))
            else:
                palette.setColor(QPalette.Button, QColor(53, 53, 53))
                palette.setColor(QPalette.Base, QColor(25, 25, 25))

            codeList = [
                machine + '.cdn = None', machine + '.testRun = None',
                machine + '.coatingRun = None', machine + '.loadingRun = None',
                machine + '.setupRun = None', cdnBox + '.setReadOnly(False)',
                testBox + '.setReadOnly(False)', coatBox +
                '.setReadOnly(False)', loadBox + '.setReadOnly(False)',
                setupBox + '.setReadOnly(False)', vButton + '.setText("Lock")',
                vButton + '.setPalette(palette)', cdnBox +
                '.setPalette(palette)', testBox + '.setPalette(palette)',
                coatBox + '.setPalette(palette)', loadBox +
                '.setPalette(palette)', setupBox + '.setPalette(palette)'
            ]

        code = '\n'.join(codeList)
        exec(code)

        self.updateResults(self.machines[tab - 1])

    def checkValidity(self, cdn, testRun, coatingRun, loadingRun, setupRun):
        """
        Checks if all inputs are valid types.
        """
        try:
            int(cdn)
            float(testRun)
            float(coatingRun)
            float(loadingRun)
            float(setupRun)
            return True
        except:
            title = "Error"
            message = "At least one of the text fields does not have a numerical entry."
            buttons = QMessageBox.Ok
            message = QMessageBox(QMessageBox.Warning,
                                  title,
                                  message,
                                  buttons=buttons,
                                  flags=Qt.Dialog)
            message.exec_()
            return False

    def updateResults(self, machine):
        """
        When a button is pressed in a machine, this function makes sure
        to update its work orders with the correct values.
        """
        for workOrder in machine.workOrders:
            self.results.updateRowInfo(workOrder)

    def connectMachineSignals(self):
        """
        Connects all time and textbox signals for each machine.
        Note: Not static. Uses self variable, but hidden as string.
        """
        for tab in range(
                1, 2):  # TODO: Change 2 to 4 when other tabs are implemented.
            # Instantiate button names
            stButton = "self.ui.stButton"
            stBox = "self.ui.startTime"
            etButton = "self.ui.etButton"
            etBox = "self.ui.endTime"
            ltButton = "self.ui.ltButton"
            ltBox = "self.ui.loadTime"
            utButton = "self.ui.utButton"
            utBox = "self.ui.unloadTime"
            vButton = "self.ui.validateButton"
            machine = "self.machines[" + str(tab - 1) + "]"
            if tab in (2, 3):
                stButton += "_" + str(tab)
                etButton += "_" + str(tab)
                ltButton += "_" + str(tab)
                utButton += "_" + str(tab)
                vButton += "_" + str(tab)

            # List of code to run
            codeList = [
                stButton +
                ".toggled.connect(lambda checked, self=self: self.startTimeCheck(checked, "
                + machine + ", " + stBox + ", " + stButton + "))", etButton +
                ".toggled.connect(lambda checked, self=self: self.endTimeCheck(checked, "
                + machine + ", " + etBox + ", " + etButton + "))", ltButton +
                ".toggled.connect(lambda checked, self=self: self.loadTimeCheck(checked, "
                + machine + ", " + ltBox + ", " + ltButton + "))", utButton +
                ".toggled.connect(lambda checked, self=self: self.unloadTimeCheck(checked, "
                + machine + ", " + utBox + ", " + utButton + "))", vButton +
                ".toggled.connect(lambda checked, self=self: self.validateData(checked, "
                + str(tab) + "))"
            ]

            code = '\n'.join(codeList)
            exec(code)

    def showWOInitDialog(self, wo=None):
        """
        Shows the Work Order Dialog and does some extra action handling
        """
        if not wo:
            wo = WorkOrder()
        woDialog = WorkOrderDialog(self, wo)
        result = woDialog.exec_()
        if result == QDialog.Rejected:
            return
        else:
            success = self.addToPlanets(wo)
            if not success:
                self.showWOInitDialog(wo)
                return
            self.results.addRowFor(wo)
            self.machines[wo.machineNum - 1].workOrders.append(wo)

    def updateWorkOrder(self, workOrder: WorkOrder):
        """
        Updates visual information about workOrder.
        """
        workOrder.slice.setValue(workOrder.pieces)
        workOrder.slice.parent().updateHeader()
        if workOrder.slice.selected:
            workOrder.slice.parent().clickSlice(workOrder.slice)
            workOrder.slice.parent().clickSlice(workOrder.slice)
        self.results.updateRowInfo(workOrder)

    def addToPlanets(self, workOrder: WorkOrder):
        """
        Adds a new work order to its planet
        """
        pie = "self.ui.pie" + str(workOrder.planetNum) + "series"
        if workOrder.machineNum in (2, 3):
            pie += "_" + str(workOrder.machineNum)
        exec('success = ' + pie + '.addSlice(workOrder)', locals())
        return locals()['success']

    def showPlanetConfigDialog(self):
        """
        Shows the planet configuration dialog
        """
        pcd = PlanetConfigDialog(self)
        pcd.exec_()

    def reInit(self, alreadyWarned=False):
        """
        Clears all info
        """
        result = None
        if not alreadyWarned:
            title = "Warning"
            message = "This will clear all work orders, and cannot be undone. Continue?"
            buttons = QMessageBox.Ok | QMessageBox.Cancel
            message = QMessageBox(QMessageBox.Warning,
                                  title,
                                  message,
                                  buttons=buttons,
                                  flags=Qt.Dialog)
            result = message.exec_()

        if alreadyWarned or result == QMessageBox.Ok:
            for num, machine in enumerate(self.machines):
                for workOrder in machine.workOrders:
                    self.deleteWorkOrder(workOrder)
                if num is 0:  # TODO: Remove when other tabs are implemented
                    for planetNum in range(1, 6):
                        planet = 'self.ui.pie' + str(planetNum) + 'series'
                        if num in (1, 2):
                            planet += '_' + str(num + 1)
                        exec(planet + '.setDisabled()')
                machine.workOrders.clear()

    def toggleTheme(self):
        """
        Changes between light and dark theme. 0 is light, 1 is dark
        """
        qApp = QApplication.instance()
        if self.theme is 0:
            qApp.setStyle("Fusion")

            dark_palette = QPalette()
            dark_palette.setColor(QPalette.Window, QColor(53, 53, 53))
            dark_palette.setColor(QPalette.WindowText, Qt.white)
            dark_palette.setColor(QPalette.Base, QColor(25, 25, 25))
            dark_palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
            dark_palette.setColor(QPalette.ToolTipBase, Qt.white)
            dark_palette.setColor(QPalette.ToolTipText, Qt.white)
            dark_palette.setColor(QPalette.Text, Qt.white)
            dark_palette.setColor(QPalette.Button, QColor(53, 53, 53))
            dark_palette.setColor(QPalette.ButtonText, Qt.white)
            dark_palette.setColor(QPalette.BrightText, Qt.red)
            dark_palette.setColor(QPalette.Link, QColor(42, 130, 218))
            dark_palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
            dark_palette.setColor(QPalette.HighlightedText, Qt.black)
            dark_palette.setColor(QPalette.Disabled, QPalette.Text,
                                  QColor(190, 190, 190))
            dark_palette.setColor(QPalette.Disabled, QPalette.ButtonText,
                                  Qt.darkGray)
            qApp.setPalette(dark_palette)
            qApp.setStyleSheet(
                "QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }"
            )
            self.theme = 1
            self.ui.themeButton.setText("Dark Mode")
            self.themeChanged.emit(self.theme)
        else:
            qApp.setStyle("Fusion")

            palette = QPalette()
            palette.setColor(QPalette.Window, QColor(180, 180, 180))
            palette.setColor(QPalette.WindowText, Qt.black)
            palette.setColor(QPalette.Base, QColor(140, 140, 140))
            palette.setColor(QPalette.AlternateBase, QColor(180, 180, 180))
            palette.setColor(QPalette.ToolTipBase, Qt.black)
            palette.setColor(QPalette.ToolTipText, Qt.black)
            palette.setColor(QPalette.Text, Qt.black)
            palette.setColor(QPalette.Button, QColor(180, 180, 180))
            palette.setColor(QPalette.ButtonText, Qt.black)
            palette.setColor(QPalette.BrightText, Qt.red)
            palette.setColor(QPalette.Link, QColor(42, 130, 218))
            palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
            palette.setColor(QPalette.HighlightedText, Qt.white)
            palette.setColor(QPalette.Disabled, QPalette.Text,
                             QColor(60, 60, 60))
            palette.setColor(QPalette.Disabled, QPalette.ButtonText,
                             Qt.darkGray)
            qApp.setPalette(palette)
            qApp.setStyleSheet(
                "QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }"
            )
            self.theme = 0
            self.ui.themeButton.setText("Light Mode")
            self.themeChanged.emit(self.theme)

    def loadRandomWorkOrders(self):
        """
        Iteratively creates random work orders. Loads data into
        planets 1-4 and the table at the bottom, ***only in Tab 1***.

        Not static: needs the self variable, but it is hidden as a string.
        """
        title = "Warning"
        message = "Running the demo will clear all current work orders. Continue?"
        buttons = QMessageBox.Ok | QMessageBox.Cancel
        message = QMessageBox(QMessageBox.Warning,
                              title,
                              message,
                              buttons=buttons,
                              flags=Qt.Dialog)
        result = message.exec_()

        if result == QMessageBox.Ok:
            self.reInit(True)
            c = 1
            for i in range(1, 5):  # The first 4 planets
                # Get current pie's name, initialize that pieSeries
                curPie = "self.ui.pie" + str(i) + "series"
                exec(curPie + ".setEnabled(100)")

                # Randomly generate some WorkOrders for this pie, add them
                # as slices to pie, and add data to results.
                for j in range(1, 5):
                    # Random num of pcs and side choice
                    numPcs = randrange(1, 26)
                    side = randrange(1, 3)

                    # Set name, create WorkOrder
                    name = "WO #" + str(c)
                    c += 1

                    tmpWO = WorkOrder()
                    tmpWO.name = name
                    tmpWO.pieces = numPcs
                    tmpWO.side = side
                    tmpWO.planetNum = i
                    tmpWO.machineNum = 1

                    # Create slice for WorkOrder, add it to mapping, add it to results
                    exec(curPie + ".addSlice(tmpWO)")
                    self.results.addRowFor(tmpWO)
                    self.machines[0].workOrders.append(tmpWO)
Ejemplo n.º 15
0
class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.connectActions()

        self.loopProcessor = loopLoader.loopLoader()
        self.logProcessor = logProcessing.logProcess()
        self.runProcessor = Runner.allanandPlots()

        self.filename  = None
        self.filetuple = None

        self.plot_spaceOff = plotSpace.plotSpace()
        self.plot_spaceAllan = plotSpace.plotSpace()
        self.plot_spaceHist = plotSpace.plotSpace()

        self.ui.plotSpace.addWidget(self.plot_spaceOff)
        self.ui.plotSpace_3.addWidget(self.plot_spaceAllan)
        self.ui.plotSpace_2.addWidget(self.plot_spaceHist)

        self.type = 0

        self.sizeOff = 0

        self.numberOFTicks = 0

        self.exceeds = 0

        self.modified = 0



    def connectActions(self):
        self.ui.actionNtpStatus.connect(PySide.QtCore.SIGNAL("triggered()"), self.aboutBox)

        self.ui.actionLoopstats.connect(PySide.QtCore.SIGNAL("triggered()"), self.fileLoopstats)
        self.ui.actionLoadLopstats.connect(PySide.QtCore.SIGNAL("triggered()"), self.fileLoopstats)

        self.ui.actionLoadRun.connect(PySide.QtCore.SIGNAL("triggered()"), self.fileRun)
        self.ui.actionRun_File.connect(PySide.QtCore.SIGNAL("triggered()"), self.fileRun)

        self.ui.actionLoadLog.connect(PySide.QtCore.SIGNAL("triggered()"), self.fileLog)
        self.ui.actionLog_File.connect(PySide.QtCore.SIGNAL("triggered()"), self.fileLog)

        self.ui.actionPlot.connect(PySide.QtCore.SIGNAL("triggered()"), self.generatePlot)

        self.ui.actionSave.connect(PySide.QtCore.SIGNAL("triggered()"), self.plotSave)

        self.connect(self.ui.actionExit, QtCore.SIGNAL('triggered()'), self.close)

    def aboutBox(self):

        QMessageBox.about(self, "About NTPStats 2012",
            """<b>Google Summer of Code 2012.</b> v %s
            <p>Copyright &copy; 2012 Google and NTP.
            All rights reserved in accordance with
            GPL v2.
            <p>This programs plots the Allan Deviation and Offsets for\
             logs of NTP Runs.
             <p> Developed by Thiago de Freitas Oliveira Araujo
            <p>Python %s -  PySide version %s - Qt version %s on\
            %s""" % (__version__, platform.python_version(),\
                         PySide.__version__,  PySide.QtCore.__version__,
                         platform.system()))

    def closeEvent(self, event):

        reply = QtGui.QMessageBox.question(self, 'Leave NTPStats',
            "Are you sure to quit?", QtGui.QMessageBox.No |
                                     QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    def fileLoopstats(self):

        if self.ui.tabWidget.currentIndex():
            self.oktoLoad()
            return
        else:
            dir = (os.path.dirname(self.filename)
                   if self.filename is not None else ".")
            self.filetuple = QFileDialog.getOpenFileName(self,\
                "Open Loopstats File", dir,\
                "Data (*.dat *.txt)\nAll Files (*.*)")
            self.filename = self.filetuple[0]
            fname = self.filename

            if fname:
                self.loopProcessor.processLoopStats(fname)
                self.loadFile(fname)
                self.updateStatus('New Loopstats file opened.')
                [self.loopProcessor.timeS, self.loopProcessor.av, self.loopProcessor.error] = self.loopProcessor.Allan.allanDevMills(self.loopProcessor.offsets)
                self.type = 1

                self.sizeOff = len(self.loopProcessor.offsets)
                if(self.sizeOff%84 != 0):
                    self.exceeds = self.sizeOff%84


                self.numberOFTicks = scipy.ceil((float)(self.sizeOff)/84)
                self.ui.spinBox.setRange(1,self.numberOFTicks)



    def fileRun(self):

        if self.ui.tabWidget.currentIndex():
            self.oktoLoad()
            return
        else:
            dir = (os.path.dirname(self.filename)
                   if self.filename is not None else ".")
            self.filetuple = QFileDialog.getOpenFileName(self,\
                "Open Generated Times File", dir,\
                "Data (*.dat *.txt)\nAll Files (*.*)")
            self.filename = self.filetuple[0]
            fname = self.filename

            dir = (os.path.dirname(self.filename)
                   if self.filename is not None else ".")
            self.filetuple = QFileDialog.getOpenFileName(self,\
                "Open Generated Offsets File", dir,\
                "Data (*.dat *.txt)\nAll Files (*.*)")
            self.filename = self.filetuple[0]
            fname2 = self.filename

            if fname:
                self.runProcessor.processOffsets(fname, fname2)
                self.loadFile(fname)
                self.updateStatus('New Run Statistics File opened.')
                [self.runProcessor.timeS, self.runProcessor.av, self.runProcessor.error] = self.runProcessor.Allan.allanDevMills(self.runProcessor.offsets)
                self.type = 2
                self.sizeOff = len(self.runProcessor.offsets)
                if(self.sizeOff%84 != 0):
                    self.exceeds = self.sizeOff%84

                self.numberOFTicks = scipy.ceil((float)(self.sizeOff)/84)
                self.ui.spinBox.setRange(1,self.numberOFTicks)

    def fileLog(self):

        if self.ui.tabWidget.currentIndex():
            self.oktoLoad()
            return
        else:
            dir = (os.path.dirname(self.filename)
                   if self.filename is not None else ".")
            self.filetuple = QFileDialog.getOpenFileName(self,\
                "Open Log File", dir,\
                "Data (*.log)\nAll Files (*.*)")
            self.filename = self.filetuple[0]
            fname = self.filename

            if fname:
                self.logProcessor.processLog(fname)
                self.loadFile(fname)
                self.updateStatus('New Log file opened.')
                [self.logProcessor.timeS, self.logProcessor.av, self.logProcessor.error] = self.logProcessor.Allan.allanDevMills(self.logProcessor.offsets)
                self.type = 3
                self.sizeOff = len(self.logProcessor.offsets)
                if(self.sizeOff%84 != 0):
                    self.exceeds = self.sizeOff%84
                self.numberOFTicks = scipy.ceil((float)(self.sizeOff)/84)
                self.ui.spinBox.setRange(1,self.numberOFTicks)


    def oktoPlot(self):

        reply = QMessageBox.warning(self,
            "Warning",
            '''\nPlotting is only possible at a Plot tab!''', QMessageBox.Ok)
        return True

    def oktoLoad(self):

        reply = QMessageBox.warning(self,
            "Warning",
            '''\nLoading is only possible at the Contents Tab!''', QMessageBox.Ok)
        return True

    def oktoSavePlot(self):

        reply = QMessageBox.warning(self,
            "Warning",
            '''\nPlot Save is only possible at a Plot tab!''', QMessageBox.Ok)
        return True

    def loadFile(self, fname=None):
        fl = open(fname)
        text = fl.read()
        self.ui.textEdit.setPlainText(text)


    def plotSave(self):

        if not (self.ui.tabWidget.currentIndex()):
            self.oktoSavePlot()
            return
        elif self.ui.tabWidget.currentIndex()==1:
            nameSave = self.ui.nametoSave.text()
            self.plot_spaceOff.save_plot(nameSave)

        elif self.ui.tabWidget.currentIndex()==2:
            nameSave = self.ui.nametoSave_3.text()
            self.plot_spaceAllan.save_plot(nameSave)

        elif self.ui.tabWidget.currentIndex()==3:
            nameSave = self.ui.nametoSave_2.text()
            self.plot_spaceHist.save_plot(nameSave)


    def updateStatus(self, message):

        if self.filename is not None:
            fileN = os.path.basename(self.filename)
            self.setWindowTitle(unicode("Statistics File - " +\
                                        fileN + "[*]") )
            self.statusBar().showMessage(message, 5000)


    def generatePlot(self):

        if not (self.ui.tabWidget.currentIndex()):
            self.oktoPlot()
            return

        elif self.ui.tabWidget.currentIndex()==1: #Offsets

            if(self.type == 1): # LOOPSTATS

                if not self.modified:

                    self.loopProcessor.seconds = np.asarray(self.loopProcessor.seconds)
                    self.loopProcessor.day = np.asarray(self.loopProcessor.day)
                    self.loopProcessor.seconds += (self.loopProcessor.day - self.loopProcessor.day[0]) * 86400
                    self.loopProcessor.seconds /= 3600
                    self.modified = 1

                if self.ui.radioButton.isChecked():

                    if self.ui.radioButton_2.isChecked():
                        if not self.exceeds:
                            range_min = (self.ui.spinBox.value()-1)*84
                            range_max = range_min + 84
                            self.plot_spaceOff.plotMinusLeastSquares(1, self.loopProcessor.offsets[range_min:range_max], self.loopProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.loopProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.loopProcessor.secondsPure[range_max])
                            self.ui.textEdit_2.setText(smallText)
                        else:

                            range_min = (self.ui.spinBox.value()-1)*84

                            range_max = (self.ui.spinBox.value()*84)

                            if(self.ui.spinBox.value() == self.numberOFTicks):
                                range_max = range_min + self.exceeds

                            self.plot_spaceOff.plotMinusLeastSquares(1, self.loopProcessor.offsets[range_min:range_max], self.loopProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.loopProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.loopProcessor.secondsPure[range_max-1])
                            self.ui.textEdit_2.setText(smallText)
                    else:
                        if not self.exceeds:
                            range_min = (self.ui.spinBox.value()-1)*84
                            range_max = range_min + 84
                            self.plot_spaceOff.update_plot(1, self.loopProcessor.offsets[range_min:range_max], self.loopProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.loopProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.loopProcessor.secondsPure[range_max])
                            self.ui.textEdit_2.setText(smallText)
                        else:

                            range_min = (self.ui.spinBox.value()-1)*84

                            range_max = (self.ui.spinBox.value()*84)

                            if(self.ui.spinBox.value() == self.numberOFTicks):
                                range_max = range_min + self.exceeds

                            self.plot_spaceOff.update_plot(1, self.loopProcessor.offsets[range_min:range_max], self.loopProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.loopProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.loopProcessor.secondsPure[range_max-1])
                            self.ui.textEdit_2.setText(smallText)


                else:
                    if self.ui.radioButton_2.isChecked():
                        self.plot_spaceOff.plotMinusLeastSquares(1, self.loopProcessor.offsets, self.loopProcessor.seconds, av=None, error=None, timeS=None, tickCorrect=0)
                        smallText = "Initial Time:" + "\n" + ctime(self.loopProcessor.secondsPure[0]) + "\n" +\
                                    "Final Time:" + "\n" + ctime(self.loopProcessor.secondsPure[-1])
                        self.ui.textEdit_2.setText(smallText)
                    else:
                        self.plot_spaceOff.update_plot(1, self.loopProcessor.offsets, self.loopProcessor.seconds, av=None, error=None, timeS=None, tickCorrect=0)
                        smallText = "Initial Time:" + "\n" + ctime(self.loopProcessor.secondsPure[0]) + "\n" +\
                                    "Final Time:" + "\n" + ctime(self.loopProcessor.secondsPure[-1])
                        self.ui.textEdit_2.setText(smallText)
####
                ####

            elif(self.type == 2): #RUN

                if self.ui.radioButton.isChecked():

                    if self.ui.radioButton_2.isChecked():
                        if not self.exceeds:
                            range_min = (self.ui.spinBox.value()-1)*84
                            range_max = range_min + 84
                            self.plot_spaceOff.plotMinusLeastSquares(1, self.runProcessor.offsets[range_min:range_max], self.runProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.runProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.runProcessor.secondsPure[range_max])
                            self.ui.textEdit_2.setText(smallText)
                        else:

                            range_min = (self.ui.spinBox.value()-1)*84

                            range_max = (self.ui.spinBox.value()*84)

                            if(self.ui.spinBox.value() == self.numberOFTicks):
                                range_max = range_min + self.exceeds

                            self.plot_spaceOff.plotMinusLeastSquares(1, self.runProcessor.offsets[range_min:range_max], self.runProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.runProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.runProcessor.secondsPure[range_max-1])
                            self.ui.textEdit_2.setText(smallText)
                    else:
                        if not self.exceeds:
                            range_min = (self.ui.spinBox.value()-1)*84
                            range_max = range_min + 84
                            self.plot_spaceOff.update_plot(1, self.runProcessor.offsets[range_min:range_max], self.runProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.runProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.runProcessor.secondsPure[range_max])
                            self.ui.textEdit_2.setText(smallText)
                        else:

                            range_min = (self.ui.spinBox.value()-1)*84

                            range_max = (self.ui.spinBox.value()*84)

                            if(self.ui.spinBox.value() == self.numberOFTicks):
                                range_max = range_min + self.exceeds

                            self.plot_spaceOff.update_plot(1, self.runProcessor.offsets[range_min:range_max], self.runProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.runProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.runProcessor.secondsPure[range_max-1])
                            self.ui.textEdit_2.setText(smallText)


                else:
                    if self.ui.radioButton_2.isChecked():
                        self.plot_spaceOff.plotMinusLeastSquares(1, self.runProcessor.offsets, self.runProcessor.seconds, av=None, error=None, timeS=None, tickCorrect=0)
                        smallText = "Initial Time:" + "\n" + ctime(self.runProcessor.secondsPure[0]) + "\n" +\
                                    "Final Time:" + "\n" + ctime(self.runProcessor.secondsPure[-1])
                        self.ui.textEdit_2.setText(smallText)
                    else:
                        self.plot_spaceOff.update_plot(1, self.runProcessor.offsets, self.runProcessor.seconds, av=None, error=None, timeS=None, tickCorrect=0)
                        smallText = "Initial Time:" + "\n" + ctime(self.runProcessor.secondsPure[0]) + "\n" +\
                                    "Final Time:" + "\n" + ctime(self.runProcessor.secondsPure[-1])
                        self.ui.textEdit_2.setText(smallText)

            elif(self.type == 3): #LOG

                self.ui.textEdit_2.clear()

                if self.ui.radioButton.isChecked():

                    if self.ui.radioButton_2.isChecked():
                        if not self.exceeds:
                            range_min = (self.ui.spinBox.value()-1)*84
                            range_max = range_min + 84
                            self.plot_spaceOff.plotMinusLeastSquares(1, self.logProcessor.offsets[range_min:range_max], self.logProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.logProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.logProcessor.secondsPure[range_max])
                            self.ui.textEdit_2.setText(smallText)
                        else:

                            range_min = (self.ui.spinBox.value()-1)*84

                            range_max = (self.ui.spinBox.value()*84)

                            if(self.ui.spinBox.value() == self.numberOFTicks):
                                range_max = range_min + self.exceeds

                            self.plot_spaceOff.plotMinusLeastSquares(1, self.logProcessor.offsets[range_min:range_max], self.logProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.logProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.logProcessor.secondsPure[range_max-1])
                            self.ui.textEdit_2.setText(smallText)
                    else:
                        if not self.exceeds:
                            range_min = (self.ui.spinBox.value()-1)*84
                            range_max = range_min + 84
                            self.plot_spaceOff.update_plot(1, self.logProcessor.offsets[range_min:range_max], self.logProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.logProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.logProcessor.secondsPure[range_max])
                            self.ui.textEdit_2.setText(smallText)
                        else:

                            range_min = (self.ui.spinBox.value()-1)*84

                            range_max = (self.ui.spinBox.value()*84)

                            if(self.ui.spinBox.value() == self.numberOFTicks):
                                range_max = range_min + self.exceeds

                            self.plot_spaceOff.update_plot(1, self.logProcessor.offsets[range_min:range_max], self.logProcessor.seconds[range_min:range_max], av=None, error=None, timeS=None, tickCorrect=1)
                            smallText = "Initial Time:" + "\n" + ctime(self.logProcessor.secondsPure[range_min]) + "\n" +\
                                        "Final Time:" + "\n" + ctime(self.logProcessor.secondsPure[range_max-1])
                            self.ui.textEdit_2.setText(smallText)


                else:
                    if self.ui.radioButton_2.isChecked():
                        self.plot_spaceOff.plotMinusLeastSquares(1, self.logProcessor.offsets, self.logProcessor.seconds, av=None, error=None, timeS=None, tickCorrect=0)
                        smallText = "Initial Time:" + "\n" + ctime(self.logProcessor.secondsPure[0]) + "\n" +\
                                    "Final Time:" + "\n" + ctime(self.logProcessor.secondsPure[-1])
                        self.ui.textEdit_2.setText(smallText)
                    else:
                        self.plot_spaceOff.update_plot(1, self.logProcessor.offsets, self.logProcessor.seconds, av=None, error=None, timeS=None, tickCorrect=0)
                        smallText = "Initial Time:" + "\n" + ctime(self.logProcessor.secondsPure[0]) + "\n" +\
                                    "Final Time:" + "\n" + ctime(self.logProcessor.secondsPure[-1])
                        self.ui.textEdit_2.setText(smallText)




        elif self.ui.tabWidget.currentIndex()==2: # Allan Deviations

            if(self.type ==1): # LOOPSTATS

                if self.ui.radioButton_3.isChecked():
                    self.plot_spaceAllan.plotAllanPPM(2, off=None, sec=None, av=self.loopProcessor.av, error=self.loopProcessor.error, timeS=self.loopProcessor.timeS, tickCorrect=0)
                    smallText = 'tau' + "\t" + "Adev" + "\n"
                    smallText += "-------------------------\n"
                    for i in range(0,len(self.loopProcessor.timeS)):
                        smallText += str(self.loopProcessor.timeS[i]) + "\t" + str(self.loopProcessor.av[i]*1e6)  + "\n"
                    self.ui.textEdit_3.setText(smallText)
                else:
                    self.plot_spaceAllan.update_plot(2, off=None, sec=None, av=self.loopProcessor.av, error=self.loopProcessor.error, timeS=self.loopProcessor.timeS, tickCorrect=0)
                    smallText = 'tau' + "\t" + "Adev" + "\n"
                    smallText += "-------------------------\n"
                    for i in range(0,len(self.loopProcessor.timeS)):
                        smallText += str(self.loopProcessor.timeS[i]) + "\t" + str(self.loopProcessor.av[i])  + "\n"
                    self.ui.textEdit_3.setText(smallText)

            elif(self.type == 2): #RUN

                if self.ui.radioButton_3.isChecked():
                    self.plot_spaceAllan.plotAllanPPM(2, off=None, sec=None, av=self.runProcessor.av, error=self.runProcessor.error, timeS=self.runProcessor.timeS, tickCorrect=0)
                    smallText = 'tau' + "\t" + "Adev" + "\n"
                    smallText += "-------------------------\n"
                    for i in range(0,len(self.runProcessor.timeS)):
                        smallText += str(self.runProcessor.timeS[i]) + "\t" + str(self.runProcessor.av[i]*1e6)  + "\n"
                    self.ui.textEdit_3.setText(smallText)
                else:
                    self.plot_spaceAllan.update_plot(2, off=None, sec=None, av=self.runProcessor.av, error=self.runProcessor.error, timeS=self.runProcessor.timeS, tickCorrect=0)
                    smallText = 'tau' + "\t" + "Adev" + "\n"
                    smallText += "-------------------------\n"
                    for i in range(0,len(self.runProcessor.timeS)):
                        smallText += str(self.runProcessor.timeS[i]) + "\t" + str(self.runProcessor.av[i])  + "\n"
                    self.ui.textEdit_3.setText(smallText)

            elif(self.type==3): # LOG

                if self.ui.radioButton_3.isChecked():
                    self.plot_spaceAllan.plotAllanPPM(2, off=None, sec=None, av=self.logProcessor.av, error=self.logProcessor.error, timeS=self.logProcessor.timeS, tickCorrect=0)
                    smallText = 'tau' + "\t" + "Adev" + "\n"
                    smallText += "-------------------------\n"
                    for i in range(0,len(self.logProcessor.timeS)):
                        smallText += str(self.logProcessor.timeS[i]) + "\t" + str(self.logProcessor.av[i]*1e6)  + "\n"
                    self.ui.textEdit_3.setText(smallText)
                else:
                    self.plot_spaceAllan.update_plot(2, off=None, sec=None, av=self.logProcessor.av, error=self.logProcessor.error, timeS=self.logProcessor.timeS, tickCorrect=0)
                    smallText = 'tau' + "\t" + "Adev" + "\n"
                    smallText += "-------------------------\n"
                    for i in range(0,len(self.logProcessor.timeS)):
                        smallText += str(self.logProcessor.timeS[i]) + "\t" + str(self.logProcessor.av[i])  + "\n"
                    self.ui.textEdit_3.setText(smallText)

        elif self.ui.tabWidget.currentIndex()==3: #Histograms

            if(self.type == 1): # LOOPSTATS
                self.plot_spaceHist.update_plot(3, self.loopProcessor.offsets, sec=None, av=None, error=None, timeS=None, tickCorrect=0)

            elif(self.type == 2): #RUN
                self.plot_spaceHist.update_plot(3, self.runProcessor.offsets, sec=None, av=None, error=None, timeS=None, tickCorrect=0)

            elif(self.type == 3): # LOG
                self.plot_spaceHist.update_plot(3, self.logProcessor.offsets, sec=None, av=None, error=None, timeS=None, tickCorrect=0)