Ejemplo n.º 1
0
    def on_point_toggle(self, item: QtWidgets.QTreeWidgetItem,
                        column: int) -> None:
        """ Callback for toggling point selection

        Adds/removes points to background removal queue

        Args:
            item (QtWidgets.QTreeWidgetItme):
                toggled widget item
            column (int):
                mandatory unused argument in signal
        """
        if item.childCount() == 0:
            # a bit inefficient here (e.g dynamic programming could help)
            treepath = ''
            node = item
            while node is not None:
                treepath = '/' + node.text(0) + treepath
                node = node.parent()
            # remove prepended '/'
            treepath = treepath[1:]

            index = self.pointPlotSelect.findText(treepath)
            if index < 0 and item.checkState(0):
                self.pointPlotSelect.addItem(treepath)
            elif index >= 0 and not item.checkState(0):
                self.pointPlotSelect.removeItem(index)

        else:
            for child in [
                    item.child(index) for index in range(item.childCount())
            ]:
                child.setCheckState(0, item.checkState(0))
Ejemplo n.º 2
0
    def _update_checkboxes(self, item: QTreeWidgetItem, column: int):
        if column != 0:
            return

        new_check_state = item.checkState(0)
        self._set_check_state_to_tree(item, new_check_state)

        while True:
            item = item.parent()
            if item is None:
                break

            has_checked_children = False
            has_partially_checked_children = False
            has_unchecked_children = False
            for i in range(item.childCount()):
                state = item.child(i).checkState(0)
                if state == Qt.Checked:
                    has_checked_children = True
                elif state == Qt.PartiallyChecked:
                    has_partially_checked_children = True
                else:
                    has_unchecked_children = True

            if not has_partially_checked_children and \
                    not has_unchecked_children:
                new_state = Qt.Checked
            elif has_checked_children or has_partially_checked_children:
                new_state = Qt.PartiallyChecked
            else:
                new_state = Qt.Unchecked
            item.setCheckState(0, new_state)

        self._update_selection_label()
Ejemplo n.º 3
0
    def _update_checkboxes(self, item: QTreeWidgetItem, column: int):
        if column != 0:
            return

        new_check_state = item.checkState(0)
        self._set_check_state_to_tree(item, new_check_state)

        while True:
            item = item.parent()
            if item is None:
                break

            has_checked_children = False
            has_partially_checked_children = False
            has_unchecked_children = False
            for i in range(item.childCount()):
                state = item.child(i).checkState(0)
                if state == Qt.Checked:
                    has_checked_children = True
                elif state == Qt.PartiallyChecked:
                    has_partially_checked_children = True
                else:
                    has_unchecked_children = True

            if not has_partially_checked_children and not has_unchecked_children:
                new_state = Qt.Checked
            elif has_checked_children or has_partially_checked_children:
                new_state = Qt.PartiallyChecked
            else:
                new_state = Qt.Unchecked
            item.setCheckState(0, new_state)

        self._update_selection_label()
Ejemplo n.º 4
0
    def move_item(self, item: QTreeWidgetItem, favorite: bool):
        """ Move an time to or from the favorites tree. """

        if favorite:
            tree = self.tab2.options
            self.settings.user_options['favorites'].remove(item.data(0, DISPLAY_NAME_SLOT))
        else:
            tree = self.tab2.favorites
            self.settings.user_options['favorites'].append(item.data(0, DISPLAY_NAME_SLOT))

        self.tab2.enable_favorites(bool(self.settings.user_options['favorites']))
        tree.blockSignals(True)
        tree.addTopLevelItem(item)

        self.tab2.options.update_size()
        self.tab2.favorites.update_size()

        self.file_handler.save_settings(self.settings.settings_data)

        if item.checkState(0) == Qt.Checked:
            item.setExpanded(True)
        else:
            item.setExpanded(False)

        tree.blockSignals(False)
Ejemplo n.º 5
0
    def parameter_updater(self, item: QTreeWidgetItem, col=None, save=True):
        """Handles updating the options for a parameter."""
        if 'Custom' != self.tab1.profile_dropdown.currentText():
            self.tab1.profile_dropdown.addItem('Custom')
            self.tab1.profile_dropdown.setCurrentText('Custom')
            self.settings.user_options['current_profile'] = ''

        if item.data(0, LEVEL_SLOT) == 0:
            if item.data(0, DATA_SLOT) in self.settings.need_parameters:
                result = self.alert_message('Warning!', 'This parameter needs an option!', 'There are no options!\n'
                                                                                           'Would you make one?', True)
                if result == QMessageBox.Yes:
                    success = self.add_option(item)

                    if not success:
                        item.treeWidget().blockSignals(True)
                        item.setCheckState(0, Qt.Unchecked)
                        item.treeWidget().blockSignals(False)
                        item.treeWidget().check_dependency(item)
                else:
                    item.treeWidget().blockSignals(True)
                    item.setCheckState(0, Qt.Unchecked)
                    item.treeWidget().blockSignals(False)
                    item.treeWidget().check_dependency(item)

            if item.checkState(0) == Qt.Checked:
                self.settings[item.data(0, DATA_SLOT)]['state'] = True
                if item.data(0, DATA_SLOT) == 'Download location':
                    for i in range(item.childCount()):
                        self.parameter_updater(item.child(i), save=False)

            else:
                self.settings[item.data(0, DATA_SLOT)]['state'] = False
                if item.data(0, DATA_SLOT) == 'Download location':
                    self.tab2.download_lineedit.setText(path_shortener(self.local_dl_path))
                    self.tab2.download_lineedit.setToolTip(self.local_dl_path)

        elif item.data(0, LEVEL_SLOT) == 1:
            # Settings['Settings'][Name of setting]['active option']] = index of child
            self.settings[item.parent().data(0, DATA_SLOT)]['active option'] = item.data(0, INDEX_SLOT)
            if item.parent().data(0, DATA_SLOT) == 'Download location':
                if item.checkState(0) == Qt.Checked:
                    self.tab2.download_lineedit.setText(item.data(0, DISPLAY_NAME_SLOT))
                    self.tab2.download_lineedit.setToolTip(item.data(0, DATA_SLOT))

        if save:
            self.file_handler.save_settings(self.settings.settings_data)
Ejemplo n.º 6
0
 def resizer(self, item: QTreeWidgetItem):
     # print('Child count', item.childCount())
     if item.checkState(0):
         if self.height() + 15 * item.childCount() < ParameterTree.max_size:
             self.setFixedHeight(self.height() + 15 * item.childCount())
         # print('Expanding')
     else:
         self.update_size()
Ejemplo n.º 7
0
 def resizer(self, item: QTreeWidgetItem):
     """Handles resize changes when an parameters options are expanded/collapsed."""
     # print('Child count', item.childCount())
     if item.checkState(0):
         if self.height() + 15 * item.childCount() < ParameterTree.max_size:
             self.setFixedHeight(self.height() + 15 * item.childCount())
         # print('Expanding')
     else:
         self.update_size()
Ejemplo n.º 8
0
    def check_dependency(self, item: QTreeWidgetItem):
        """
        Looks for mentioned dependents, and enables/disables those depending on checkstate.

        :param item: changed item from QTreeWidget (paramTree)
        :type item: QTreeWidget
        """

        if item.data(0, 33) == 0 and item.data(0, 37):
            for i in item.data(0, 37):
                if item.checkState(0) == Qt.Unchecked:
                    self.blockSignals(True)
                    i.setDisabled(True)
                    i.setExpanded(False)
                    self.blockSignals(False)
                    i.setCheckState(0, Qt.Unchecked)
                else:
                    self.blockSignals(True)
                    i.setDisabled(False)
                    self.blockSignals(False)
class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(500, 300)
        self.label = QLabel('No Click')                         # 1

        self.tree = QTreeWidget(self)                           # 2
        self.tree.setColumnCount(2)
        self.tree.setHeaderLabels(['Install Components', 'Test'])
        self.tree.itemClicked.connect(self.change_func)

        self.preview = QTreeWidgetItem(self.tree)               # 3
        self.preview.setText(0, 'Preview')

        # self.preview = QTreeWidgetItem()
        # self.preview.setText(0, 'Preview')
        # self.tree.addTopLevelItem(self.preview)

        self.qt5112 = QTreeWidgetItem()                         # 4
        self.qt5112.setText(0, 'Qt 5.11.2 snapshot')
        self.qt5112.setCheckState(0, Qt.Unchecked)
        self.preview.addChild(self.qt5112)

        choice_list = ['macOS', 'Android x86',
                       'Android ARMv7', 'Sources', 'iOS']
        self.item_list = []
        for i, c in enumerate(choice_list):                     # 5
            item = QTreeWidgetItem(self.qt5112)
            item.setText(0, c)
            item.setCheckState(0, Qt.Unchecked)
            self.item_list.append(item)

        self.test_item = QTreeWidgetItem(self.qt5112)           # 6
        self.test_item.setText(0, 'test1')
        self.test_item.setText(1, 'test2')

        self.tree.expandAll()                                   # 7

        self.h_layout = QHBoxLayout()
        self.h_layout.addWidget(self.tree)
        self.h_layout.addWidget(self.label)
        self.setLayout(self.h_layout)

    def change_func(self, item, column):
        self.label.setText(item.text(column))                   # 8

        print(item.text(column))
        print(column)
        if item == self.qt5112:                                 # 9
            if self.qt5112.checkState(0) == Qt.Checked:
                [x.setCheckState(0, Qt.Checked) for x in self.item_list]
            else:
                [x.setCheckState(0, Qt.Unchecked) for x in self.item_list]
        else:                                                   # 10
            check_count = 0
            for x in self.item_list:
                if x.checkState(0) == Qt.Checked:
                    check_count += 1

            if check_count == 5:
                self.qt5112.setCheckState(0, Qt.Checked)
            elif 0 < check_count < 5:
                self.qt5112.setCheckState(0, Qt.PartiallyChecked)
            else:
                self.qt5112.setCheckState(0, Qt.Unchecked)
Ejemplo n.º 10
0
 def expand_options(self, item: QTreeWidgetItem):
     """Handles if the options should show, depends on checkstate."""
     if item.checkState(0) == Qt.Checked:
         item.setExpanded(True)
     else:
         item.setExpanded(False)
Ejemplo n.º 11
0
class TempReaderApp(QMainWindow, Ui_MainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
        self.initUI()

        logFile = "Logs" + os.sep + "TempReaderApp.log"
        logging.basicConfig(
            level=logging.DEBUG,
            format=
            '%(asctime)s - %(funcName)s - Line %(lineno)d - %(levelname)s: %(message)s',
            datefmt='%m-%d-%Y %I:%M:%S %p',
            filename=logFile,
            filemode='a')

        handler = RotatingFileHandler(logFile,
                                      maxBytes=5 * 1024 * 1024,
                                      backupCount=1,
                                      encoding=None,
                                      delay=0)
        logging.getLogger().addHandler(handler)
        logging.debug("Temperature app initialized")

    def initUI(self):
        font = QFont()
        font.setPointSize(12)
        self.center()
        self.setFixedSize(self.size())
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.setWindowIcon(QtGui.QIcon("Icons" + os.sep + "Thermometer.png"))
        self.webView.setEnabled(False)
        self.webViewTable.setEnabled(False)
        self.plotTabLbl.setText("Select file to load.")
        self.plotTabLbl.setVisible(True)
        self.tableTabLbl.setText("Select file to load.")
        self.tableTabLbl.setVisible(True)
        self.loadBtn.clicked.connect(self.ProcessData)
        self.resetBtn.clicked.connect(self.Reset)
        self.createPDFBtn.clicked.connect(self.CreatePDF)
        self.exitBtn.clicked.connect(self.Exit)
        self.imageGLbl.setPixmap(
            QtGui.QPixmap("Icons" + os.sep + "whitegear.png"))
        self.imageFLbl.setPixmap(QtGui.QPixmap("Icons" + os.sep + "file.png"))
        self.imageCLbl.setPixmap(
            QtGui.QPixmap("Icons" + os.sep + "scatterplot.png"))

        self.browser = QTreeWidgetItem(self.treeWidget)
        self.browser.setFlags(self.browser.flags() | Qt.ItemIsUserCheckable)
        self.browser.setText(0, "Open Browser")
        self.browser.setCheckState(0, Qt.Unchecked)
        self.browser.setFont(0, font)

        self.sav_img = QTreeWidgetItem(self.treeWidget)
        self.sav_img.setFlags(self.sav_img.flags() | Qt.ItemIsUserCheckable)
        self.sav_img.setText(0, "Save Images")
        self.sav_img.setCheckState(0, Qt.Unchecked)
        self.sav_img.setFont(0, font)

        self.webViewTable.page().mainFrame().setScrollBarPolicy(
            Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.webViewTable.page().mainFrame().setScrollBarPolicy(
            Qt.Vertical, Qt.ScrollBarAlwaysOff)
        self.webViewTable.setEnabled(False)
        self.treeWidget.setVerticalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOff)
        self.treeWidget.setStyleSheet("""
        QTreeWidget:item:disabled {
            color: #A0A0A0;
        }
        """)
        self.tabWidget.setCurrentIndex(0)

        self.miniBtn.clicked.connect(self.miniScreen)

    def center(self):
        qr = self.frameGeometry()
        cp = QtWidgets.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def miniScreen(self):
        self.setWindowState(Qt.WindowMinimized)

    def LoadFile(self):
        logging.debug("Loading temperature file")
        self.CleanPlot()
        self.fname = QFileDialog.getOpenFileName(self, 'Select file', '/home',
                                                 'Temp File (8500_RCTT.json)')
        self.fileEdit.setText(self.fname[0])

        if not self.fname[0]:
            logging.warning("Temperature file selection cancelled")
            return None

        logging.info("Filename: {0}".format(self.fname[0]))
        return self.fname[0]

    def ProcessData(self):
        file = self.LoadFile()
        print("test")
        self.tableTabLbl.setText("Loading file, please wait.")
        self.tableTabLbl.setVisible(True)
        self.plotTabLbl.setText("Loading file, please wait.")
        self.plotTabLbl.setVisible(True)
        QApplication.processEvents()

        if not file:
            logging.debug("File not selected")
            return
        logging.debug("Processing data")

        days, high, low, temps, status, sn, times = self.ReadData()

        if not all([days, high, low, temps, status, sn, times]):
            logging.error(
                "Could not process data from temperature file, list is None")
            return None

        self.CreatePlot(days, temps, high, low, status, sn, times)

    def ReadData(self):
        logging.debug("Begin reading temperature data")
        temps = []
        days = []
        times = []
        status = []
        sn = []
        high = []
        low = []

        try:
            with open(self.fname[0]) as file:
                data = json.load(file)
            for item in data["Readings"]:
                temps.append(item["AvgTemp"])
                days.append("{0}-{1}-{2}".format(item["Date"][5:7],
                                                 item["Date"][8:],
                                                 item["Date"][0:4]))
                high.append(item["HighRange"])
                low.append(item["LowRange"])
                times.append(item["Time"])
                status.append(item["Status"])
                sn.append(item["SN"])
            return days, high, low, temps, status, sn, times
        except Exception as ex:
            MessageBox("Error opening file {0}".format(ex))
            logging.error("Exception occurred reading data: {0}".format(ex))
            return None, None, None, None, None, None, None

    def CleanPlot(self):
        logging.debug("clean plots on the UI")
        self.webView.setVisible(False)
        self.webViewTable.setVisible(False)
        self.webView.setEnabled(False)
        self.webViewTable.setEnabled(False)
        self.plotTabLbl.setText("Select file to load.")
        self.plotTabLbl.setVisible(True)
        self.tableTabLbl.setText("Select file to load.")
        self.tableTabLbl.setVisible(True)

    def CreatePlot(self, days, temps, high, low, status, sn, times):
        logging.debug("Creating plot of temperature data")
        degree = u"\u00b0"
        # upper = [high[0]] * len(days)
        # lower = [low[0]] * len(days)

        self.openbrowser = True if self.browser.checkState(0) == 2 else False
        self.saveFiles = True if self.sav_img.checkState(0) == 2 else False

        # image = 'png'
        img_plot_filename = 'img_TempReadingsPlot.png'
        img_table_filename = 'img_TempReadingsTable.png'

        # output to static HTML file
        output_file("temp_plot.html")
        tools = ["box_select", "hover", "reset"]
        # create a new plot
        p = figure(plot_height=700,
                   plot_width=1000,
                   tools=tools,
                   x_axis_label='Days',
                   x_minor_ticks=len(days),
                   y_axis_label='Temperature ({0}C)'.format(degree),
                   x_axis_type="datetime",
                   toolbar_location="right",
                   title="All Temperature Readings")
        p_filtered = figure(plot_height=700,
                            plot_width=1000,
                            tools=tools,
                            x_axis_label='Days',
                            x_minor_ticks=len(days),
                            y_axis_label='Temperature ({0}C)'.format(degree),
                            x_axis_type="datetime",
                            toolbar_location="right",
                            title="Out of Limit Temperature Readings")

        from datetime import datetime
        daysF = None
        try:
            daysF = [
                datetime(int(x[6:]), int(x[0:2]), int(x[3:5])) for x in days
            ]
        except Exception as ex:
            logging.warning(
                "Could not convert to date time object: {0}".format(ex))
            MessageBox("Error encountered processing data: {0}".format(ex))

        source = ColumnDataSource(
            data={
                'Day': daysF,  # python datetime object as X axis
                'Temp': temps,
                'Day_str': days,  # string of datetime for display in tooltip
                'High': high,
                'Low': low,
                'Status': status
            })

        # p.line(days, upper, legend="Upper Limit", line_width=3)
        # p.line(days, lower, legend="Lower Limit", line_width=3)
        filter_points = []
        for i, item in enumerate(temps):
            if item < low[i] or item > high[i]:
                filter_points.append(i)
        view = CDSView(source=source, filters=[IndexFilter(filter_points)])
        p_filtered.circle('Day',
                          'Temp',
                          source=source,
                          legend="Readings",
                          line_width=3,
                          hover_color="green",
                          alpha=0.4,
                          size=11,
                          view=view)
        # p.annulus(x=days, y=temps, color="#7FC97F",
        #              inner_radius=0.2, outer_radius=0.5)

        p_filtered.title.align = "center"
        p_filtered.title.text_color = "navy"
        p_filtered.title.text_font_size = "20px"
        p_filtered.title.text_font_style = "bold"
        p_filtered.xaxis[0].ticker.desired_num_ticks = len(days)
        p_filtered.legend.visible = False
        p_filtered.select_one(HoverTool).tooltips = [('Date', '@Day_str'),
                                                     ('Temp', '@Temp'),
                                                     ('High', '@High'),
                                                     ('Low', '@Low'),
                                                     ('Status', '@Status')]

        p.circle('Day',
                 'Temp',
                 source=source,
                 legend="Readings",
                 line_width=3,
                 hover_color="green",
                 alpha=0.4,
                 size=11)
        # p.annulus(x=days, y=temps, color="#7FC97F",
        #              inner_radius=0.2, outer_radius=0.5)

        p.title.align = "center"
        p.title.text_color = "navy"
        p.title.text_font_size = "20px"
        p.title.text_font_style = "bold"
        p.xaxis[0].ticker.desired_num_ticks = len(days)
        p.legend.visible = False
        p.select_one(HoverTool).tooltips = [('Date', '@Day_str'),
                                            ('Temp', '@Temp'),
                                            ('High', '@High'), ('Low', '@Low'),
                                            ('Status', '@Status')]

        if filter_points:
            save(column(p, p_filtered))
        else:
            save(column(p))

        try:
            shutil.copy2(os.path.join('temp_plot.html'),
                         os.path.join("Plots" + os.sep + "plot.html"))
        except Exception as ex:
            logging.warning("Could not move files: {0}".format(ex))
            MessageBox("Error encountered processing data: {0}".format(ex))

        self.createHTML(days, temps, high, low, times, status, sn)

        if self.openbrowser:
            import webbrowser
            webbrowser.open(os.path.join("Plots" + os.sep + "plot.html"))
            webbrowser.open(os.path.join("Plots" + os.sep + "HTMLTable.html"))

        if self.saveFiles:
            export_png(p, filename=img_plot_filename)
            try:
                shutil.move(
                    os.path.join(img_plot_filename),
                    os.path.join("Images" + os.sep + img_plot_filename))
            except Exception as ex:
                logging.warning("Could not move files: {0}".format(ex))
                MessageBox("Error encountered processing data: {0}".format(ex))

        self.ShowPlots(r"Plots\plot.html", r"Plots\HTMLTable.html")

    def createHTML(self, days, temps, high, low, times, status, sn):
        strTable = """
                        <html>
                        <head>
                        <style>
                        table{
                                width: 100%;
                                border-collapse: collapse;
                                font-family: Arial, serif;
                            }
                            
                            th{
                                height: 5px;
                                text-align: center;
                                background-color: #003366;;
                                color: white;
                                border: 1px solid #008CBA;
                            }
                            
                            td{
                                height: 5px;
                                text-align: center;
                                border: 1px solid #008CBA;
                                font-size: 13px;
                            }
                            </style>
                            </head>
                            <div style=overflow - x: auto;>
                            <table>
                            <tr>
                            <th>Date</th>
                            <th>Time</th>
                            <th>Temp</th>
                            <th>High</th>
                            <th>Low</th>
                            <th>Status</th>
                            <th>SN</th>
                            </tr>
                            
                            """
        endTable = "</table></div></html>"

        for i in range(len(days)):
            if temps[i] <= high[i] and temps[i] >= low[i]:
                strRW = "<tr><td>" + str(days[i]) + "</td><td>" + str(times[i]) + "</td><td>" + str(temps[i]) \
                        + "</td><td>" + str(high[i])+ "</td><td>" + str(low[i]) + "</td><td>" + str(status[i]) \
                        + "</td><td>" + str(sn[i]) + "</td></tr>"
            else:
                strRW = "<tr style=color:red><td>" + str(days[i]) + "</td><td>" + str(times[i]) + "</td><td>" + str(temps[i]) \
                        + "</td><td>" + str(high[i]) + "</td><td>" + str(low[i]) + "</td><td>" + str(status[i]) \
                        + "</td><td>" + str(sn[i]) + "</td></tr>"
            strTable = strTable + strRW
        strTable = strTable + endTable

        with open("Plots" + os.sep + "HTMLTable.html", 'w') as html:
            html.write(strTable)
        return html

    def ShowPlots(self, html, table):
        logging.debug("Showing plot")
        self.webView.load(
            QUrl(os.path.join("file:///" + os.path.abspath(html))))
        self.webViewTable.load(
            QUrl(os.path.join("file:///" + os.path.abspath(table))))
        self.webView.setEnabled(True)
        self.webViewTable.setEnabled(False)
        self.plotTabLbl.setVisible(False)
        self.tableTabLbl.setVisible(False)
        self.webViewTable.show()
        self.webView.show()
        logging.debug("End Showing plot")

    def CreatePDF(self):
        try:
            directory = self.directory = QFileDialog.getExistingDirectory(
                self, 'Select directory',
                os.path.dirname(os.path.realpath(__file__)),
                QFileDialog.ShowDirsOnly)
            self.pdfEdit.setText(self.directory)

            # TODO check if files exists
            plotFilename = "img_TempReadingsPlot.png"
            if not os.path.isfile(directory + os.sep + plotFilename):
                logging.warning("Files are missing")
                msg = MessageBox("Image files are missing.")
                return
            pdf = MyPDF()
            pdf.alias_nb_pages()
            pdf.set_display_mode(zoom='real', layout='default')
            pdf.add_page("L")
            pdf.set_font('Arial', 'B', 12)
            pdf.set_title("Reagent Carousel Temperature Report")
            pdf.set_author("Rick Roll")
            # pdf.text(70.0, 5.0, "Reagent Carousel Temperature Report")
            pdf.image(directory + os.sep + plotFilename,
                      x=45,
                      y=None,
                      w=0,
                      h=160)
            pdf.set_x(60)
            h = """
            
                        <html>
                        <head>
                            <table>
                            <tr>
                            <th width="14%">Date</th>
                            <th width="14%">Time</th>
                            <th width="14%">Temp</th>
                            <th width="14%">High</th>
                            <th width="14%">Low</th>
                            <th width="14%">Status</th>
                            <th width="14%">SN</th>
                            </tr>
                            
                            <tr><td>09-12-2016</td><td>07:10:52 AM</td><td>8.7</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr style=color:red><td>09-13-2016</td><td>07:12:15 AM</td><td>1.2</td><td>15.0</td><td>2.0</td><td>Fail</td><td>16FMP00032</td></tr><tr><td>09-14-2016</td><td>08:08:02 AM</td><td>6.1</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-15-2016</td><td>08:14:23 AM</td><td>8.0</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-16-2016</td><td>01:43:56 PM</td><td>8.1</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-17-2016</td><td>01:45:04 PM</td><td>9.2</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-18-2016</td><td>03:17:04 PM</td><td>9.5</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-19-2016</td><td>03:40:05 PM</td><td>9.6</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-20-2016</td><td>03:40:46 PM</td><td>9.7</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-21-2016</td><td>03:42:26 PM</td><td>9.8</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-22-2016</td><td>03:43:22 PM</td><td>9.9</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-23-2016</td><td>03:45:20 PM</td><td>10.0</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-24-2016</td><td>03:47:49 PM</td><td>10.1</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-25-2016</td><td>03:48:26 PM</td><td>10.2</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-26-2016</td><td>10:13:56 AM</td><td>10.3</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-27-2016</td><td>11:40:18 AM</td><td>10.4</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-28-2016</td><td>11:41:44 AM</td><td>10.5</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-29-2016</td><td>11:43:48 AM</td><td>10.5</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>09-30-2016</td><td>01:45:21 PM</td><td>10.5</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr style=color:red><td>10-01-2016</td><td>02:00:36 PM</td><td>15.9</td><td>15.0</td><td>2.0</td><td>Fail</td><td>16FMP00032</td></tr><tr><td>10-02-2016</td><td>02:01:11 PM</td><td>10.6</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-03-2016</td><td>02:01:46 PM</td><td>10.5</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-04-2016</td><td>02:02:11 PM</td><td>10.6</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-05-2016</td><td>02:02:42 PM</td><td>10.4</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-06-2016</td><td>02:03:14 PM</td><td>10.5</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-07-2016</td><td>02:03:52 PM</td><td>10.5</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-08-2016</td><td>02:04:32 PM</td><td>10.6</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-09-2016</td><td>02:04:58 PM</td><td>13.5</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-10-2016</td><td>02:45:23 PM</td><td>10.6</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-11-2016</td><td>09:45:16 AM</td><td>11.0</td><td>15.0</td><td>2.0</td><td>Pass</td><td>16FMP00032</td></tr><tr><td>10-12-2016</td><td>09:47:09 AM</td><td>11.0</td><td>15.0</td><td>8.0</td><td>Pass</td><td>16FMP00032</td></tr></table></div></html>
            """
            pdf.write_html(h)
            outputFile = "Reports" + os.sep + 'TempReadingsReport.pdf'
            pdf.output(outputFile, "F")
            pdf.close()
            print("open file")
            subprocess.Popen([outputFile], shell=True)
        except Exception as ex:
            logging.error("Error occurred while generating PDF {0}".format(ex))
            errorMessage = MessageBox("Error encountered: {0}".format(ex))
            errorMessage.showDialog()

    def Reset(self):
        self.CleanPlot()
        self.fileEdit.setText('')
        self.pdfEdit.setText('')
        self.loadBtn.setEnabled(True)

    def Exit(self):
        sys.exit(0)
Ejemplo n.º 12
0
def load(filename, widget):
    """Loads snippets from a file, displaying them in a list.
    
    The user can then choose:
    - overwrite builtin snippets or not
    - overwrite own snippets with same title or not
    - select and view snippets contents.
    
    """
    try:
        d = ET.parse(filename)
        elements = list(d.findall('snippet'))
        if not elements:
            raise ValueError(_("No snippets found."))
    except Exception as e:
        QMessageBox.critical(
            widget, app.caption(_("Error")),
            _("Can't read from source:\n\n{url}\n\n{error}").format(
                url=filename, error=e))
        return

    dlg = widgets.dialog.Dialog(widget)
    dlg.setWindowModality(Qt.WindowModal)
    dlg.setWindowTitle(app.caption(_("dialog title", "Import Snippets")))
    tree = QTreeWidget(headerHidden=True, rootIsDecorated=False)
    dlg.setMainWidget(tree)
    userguide.addButton(dlg.buttonBox(), "snippet_import_export")

    allnames = frozenset(snippets.names())
    builtins = frozenset(builtin.builtin_snippets)
    titles = dict(
        (snippets.title(n), n) for n in allnames if n not in builtins)

    new = QTreeWidgetItem(tree, [_("New Snippets")])
    updated = QTreeWidgetItem(tree, [_("Updated Snippets")])
    unchanged = QTreeWidgetItem(tree, [_("Unchanged Snippets")])

    new.setFlags(Qt.ItemIsEnabled)
    updated.setFlags(Qt.ItemIsEnabled)
    unchanged.setFlags(Qt.ItemIsEnabled)

    new.setExpanded(True)
    updated.setExpanded(True)

    items = []
    for snip in elements:
        item = QTreeWidgetItem()

        item.body = snip.find('body').text
        item.title = snip.find('title').text
        item.shortcuts = list(e.text
                              for e in snip.findall('shortcuts/shortcut'))

        title = item.title or snippets.maketitle(
            snippets.parse(item.body).text)
        item.setText(0, title)

        name = snip.get('id')
        name = name if name in builtins else None

        # determine if new, updated or unchanged
        if not name:
            name = titles.get(title)
        item.name = name

        if not name or name not in allnames:
            new.addChild(item)
            items.append(item)
            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
            item.setCheckState(0, Qt.Checked)
        elif name:
            if (item.body != snippets.text(name)
                    or title != snippets.title(name)
                    or (item.shortcuts and item.shortcuts !=
                        [s.toString() for s in model.shortcuts(name) or ()])):
                updated.addChild(item)
                items.append(item)
                item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
                item.setCheckState(0, Qt.Checked)
            else:
                unchanged.addChild(item)
                item.setFlags(Qt.ItemIsEnabled)
    # count:
    for i in new, updated, unchanged:
        i.setText(0, i.text(0) + " ({0})".format(i.childCount()))
    for i in new, updated:
        if i.childCount():
            i.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
            i.setCheckState(0, Qt.Checked)

    def changed(item):
        if item in (new, updated):
            for i in range(item.childCount()):
                c = item.child(i)
                c.setCheckState(0, item.checkState(0))

    tree.itemChanged.connect(changed)

    importShortcuts = QTreeWidgetItem([_("Import Keyboard Shortcuts")])
    if items:
        tree.addTopLevelItem(importShortcuts)
        importShortcuts.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
        importShortcuts.setCheckState(0, Qt.Checked)
        dlg.setMessage(_("Choose which snippets you want to import:"))
    else:
        dlg.setMessage(_("There are no new or updated snippets in the file."))
        unchanged.setExpanded(True)

    tree.setWhatsThis(
        _("<p>Here the snippets from {filename} are displayed.</p>\n"
          "<p>If there are new or updated snippets, you can select or deselect "
          "them one by one, or all at once, using the checkbox of the group. "
          "Then click OK to import all the selected snippets.</p>\n"
          "<p>Existing, unchanged snippets can't be imported.</p>\n").format(
              filename=os.path.basename(filename)))

    qutil.saveDialogSize(dlg, "snippettool/import/size", QSize(400, 300))
    if not dlg.exec_() or not items:
        return
    ac = model.collection()
    m = model.model()
    with qutil.busyCursor():
        for i in items:
            if i.checkState(0) == Qt.Checked:
                index = m.saveSnippet(i.name, i.body, i.title)
                if i.shortcuts and importShortcuts.checkState(0):
                    shortcuts = list(map(QKeySequence.fromString, i.shortcuts))
                    ac.setShortcuts(m.name(index), shortcuts)
        widget.updateColumnSizes()
Ejemplo n.º 13
0
def load(filename, widget):
    """Loads snippets from a file, displaying them in a list.

    The user can then choose:
    - overwrite builtin snippets or not
    - overwrite own snippets with same title or not
    - select and view snippets contents.

    """
    try:
        d = ET.parse(filename)
        elements = list(d.findall('snippet'))
        if not elements:
            raise ValueError(_("No snippets found."))
    except Exception as e:
        QMessageBox.critical(widget, app.caption(_("Error")),
        _("Can't read from source:\n\n{url}\n\n{error}").format(
            url=filename, error=e))
        return


    dlg = widgets.dialog.Dialog(widget)
    dlg.setWindowModality(Qt.WindowModal)
    dlg.setWindowTitle(app.caption(_("dialog title", "Import Snippets")))
    tree = QTreeWidget(headerHidden=True, rootIsDecorated=False)
    dlg.setMainWidget(tree)
    userguide.addButton(dlg.buttonBox(), "snippet_import_export")

    allnames = frozenset(snippets.names())
    builtins = frozenset(builtin.builtin_snippets)
    titles = dict((snippets.title(n), n) for n in allnames if n not in builtins)

    new = QTreeWidgetItem(tree, [_("New Snippets")])
    updated = QTreeWidgetItem(tree, [_("Updated Snippets")])
    unchanged = QTreeWidgetItem(tree, [_("Unchanged Snippets")])

    new.setFlags(Qt.ItemIsEnabled)
    updated.setFlags(Qt.ItemIsEnabled)
    unchanged.setFlags(Qt.ItemIsEnabled)

    new.setExpanded(True)
    updated.setExpanded(True)

    items = []
    for snip in elements:
        item = QTreeWidgetItem()

        item.body = snip.find('body').text
        item.title = snip.find('title').text
        item.shortcuts = list(e.text for e in snip.findall('shortcuts/shortcut'))

        title = item.title or snippets.maketitle(snippets.parse(item.body).text)
        item.setText(0, title)

        name = snip.get('id')
        name = name if name in builtins else None


        # determine if new, updated or unchanged
        if not name:
            name = titles.get(title)
        item.name = name

        if not name or name not in allnames:
            new.addChild(item)
            items.append(item)
            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
            item.setCheckState(0, Qt.Checked)
        elif name:
            if (item.body != snippets.text(name)
                or title != snippets.title(name)
                or (item.shortcuts and item.shortcuts !=
                    [s.toString() for s in model.shortcuts(name) or ()])):
                updated.addChild(item)
                items.append(item)
                item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
                item.setCheckState(0, Qt.Checked)
            else:
                unchanged.addChild(item)
                item.setFlags(Qt.ItemIsEnabled)
    # count:
    for i in new, updated, unchanged:
        i.setText(0, i.text(0) + " ({0})".format(i.childCount()))
    for i in new, updated:
        if i.childCount():
            i.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
            i.setCheckState(0, Qt.Checked)

    def changed(item):
        if item in (new, updated):
            for i in range(item.childCount()):
                c = item.child(i)
                c.setCheckState(0, item.checkState(0))

    tree.itemChanged.connect(changed)

    importShortcuts = QTreeWidgetItem([_("Import Keyboard Shortcuts")])
    if items:
        tree.addTopLevelItem(importShortcuts)
        importShortcuts.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
        importShortcuts.setCheckState(0, Qt.Checked)
        dlg.setMessage(_("Choose which snippets you want to import:"))
    else:
        dlg.setMessage(_("There are no new or updated snippets in the file."))
        unchanged.setExpanded(True)

    tree.setWhatsThis(_(
        "<p>Here the snippets from {filename} are displayed.</p>\n"
        "<p>If there are new or updated snippets, you can select or deselect "
        "them one by one, or all at once, using the checkbox of the group. "
        "Then click OK to import all the selected snippets.</p>\n"
        "<p>Existing, unchanged snippets can't be imported.</p>\n"
        ).format(filename=os.path.basename(filename)))

    qutil.saveDialogSize(dlg, "snippettool/import/size", QSize(400, 300))
    if not dlg.exec_() or not items:
        return
    ac = model.collection()
    m = model.model()
    with qutil.busyCursor():
        for i in items:
            if i.checkState(0) == Qt.Checked:
                index = m.saveSnippet(i.name, i.body, i.title)
                if i.shortcuts and importShortcuts.checkState(0):
                    shortcuts = list(map(QKeySequence.fromString, i.shortcuts))
                    ac.setShortcuts(m.name(index), shortcuts)
        widget.updateColumnSizes()
Ejemplo n.º 14
0
class OptionTreeWidget(QTreeWidget):  # type: ignore
    """A Widget to manage different user options."""
    GRP_CR = "CommitReport"
    OPT_CR_MR = "Merge reports"
    OPT_CR_RORDER = "Report Order"
    OPT_CR_CMAP = "Commit map"
    OPT_CR_PT = "Play time"

    OPT_SCF = "Show CF graph"
    OPT_SDF = "Show DF graph"

    def __init__(self, parent) -> None:
        super(OptionTreeWidget, self).__init__(parent)
        self.headerItem().setText(0, "Options")
        self.headerItem().setText(1, "Value")
        self.header().setSectionResizeMode(0, QHeaderView.Stretch)
        self.header().setSectionResizeMode(1, QHeaderView.Interactive)
        self.header().setCascadingSectionResizes(False)
        self.header().setDefaultSectionSize(100)
        self.header().setMinimumSectionSize(26)
        self.header().setStretchLastSection(False)

        self.itemDoubleClicked.connect(self._handle_item_double_click)

        self.__scf = QTreeWidgetItem(self)
        self.__scf.setCheckState(1, Qt.Unchecked)
        self.__scf.setText(0, self.OPT_SCF)

        self.__sdf = QTreeWidgetItem(self)
        self.__sdf.setText(0, self.OPT_SDF)
        self.__sdf.setCheckState(1, Qt.Unchecked)

        grp = QTreeWidgetItem(self)
        grp.setText(0, self.GRP_CR)

        self.__mr = QTreeWidgetItem(grp)
        self.__mr.setCheckState(1, Qt.Unchecked)
        self.__mr.setText(0, self.OPT_CR_MR)

        self.__cm = QTreeWidgetItem(grp)
        self.__cm.setText(0, self.OPT_CR_CMAP)

        # Add QBox item so select order function
        drop_item = QTreeWidgetItem(grp)
        self.__combo_box = QComboBox()
        self.__combo_box.addItem("---")
        self.__combo_box.addItem("Linear History")
        self.setItemWidget(drop_item, 1, self.__combo_box)
        drop_item.setText(0, self.OPT_CR_RORDER)

        play_time_item = QTreeWidgetItem(grp)
        play_time_item.setText(0, self.OPT_CR_PT)
        self.__pt_lineedit = QLineEdit()
        valid = QIntValidator()
        valid.bottom = 10
        valid.top = 50000
        self.__pt_lineedit.setValidator(valid)
        self.setItemWidget(play_time_item, 1, self.__pt_lineedit)
        self.__pt_lineedit.insert(str(5000))

    @property
    def merge_report_checkstate(self):
        """Check state of merge report option."""
        return self.__mr.checkState(1)

    @property
    def show_cf_checkstate(self):
        """Check state of show cf plot option."""
        return self.__scf.checkState(1)

    @property
    def show_df_checkstate(self):
        """Check state of show df plot option."""
        return self.__sdf.checkState(1)

    @property
    def report_order(self):
        """Get current combo box selection."""
        return self.__combo_box.currentText()

    @property
    def play_time(self):
        """Get current play time."""
        return int(self.__pt_lineedit.text())

    def connect_cb_cic(self, func):
        """Register a callback for the combo box currentIndexChanged signal."""
        self.__combo_box.currentIndexChanged.connect(func)

    def _handle_item_double_click(self, item, col):
        if item is self.__cm and col == 1:
            path = self._get_file()
            self.__cm.setText(1, path)

    def _get_file(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "Load CommitReport file",
            "",
            "All Files (*)",
            options=options
        )
        return file_path
Ejemplo n.º 15
0
    def update_todo(self, list_item: QtWidgets.QTreeWidgetItem):
        todo_item: TodoItem = list_item.data(0, QtCore.Qt.UserRole)

        if list_item.checkState(0) == QtCore.Qt.Checked:
            todo_item.complete()
            self.updater_thread.start()