Пример #1
0
class DBDD(QMainWindow, Ui_MainWindow):
    def __init__(self, dbpath, parent=None):
        """Creates a new instance of DBDD.
        @param dbpath Path to the dbdd database backend.
        @param parent Qt Parent."""
        super(DBDD, self).__init__(parent)
        self.setupUi(self)
        self._setupAttributes()
        self._updateStats()

    def _setupAttributes(self):
        """Sets up all private attributes."""
        self._db = DatabaseBackend(dbpath)
        self._trainFilter = TrainFilter(self)
        self._overviewModel = OverviewModel(self._db, self.treeOverview)
        self._overviewModel.setFilter(self._trainFilter)
        self.treeOverview.setModel(self._overviewModel)
        self._setupStatsTimer()
        self._connectSignals()
        self._populateProductFilter()
        self._populateConnectionsFilter()

    def _setupStatsTimer(self):
        """Sets up the timer that is used to refresh the statistics."""
        self._statsTimer = QTimer(self)
        self._statsTimer.setInterval(10 * 1000)  # update every 10 seconds
        self._statsTimer.timeout.connect(self._updateStats)
        self._statsTimer.start()

    def _connectSignals(self):
        """Sets up all signal/slot connections."""
        self._trainFilter.filterChanged.connect(self._updateStats)
        self.buttonAddConnection.clicked.connect(self.showAddConnectionDialog)
        self.checkBoxConnectionFilter.toggled.connect(self._updateFilter)
        self.checkBoxDateFilter.toggled.connect(self._updateFilter)
        self.checkBoxTimeFilter.toggled.connect(self._updateFilter)
        self.checkBoxProductFilter.toggled.connect(self._updateFilter)
        self.checkBoxDelayFilter.toggled.connect(self._updateFilter)
        self.comboBoxConnections.currentIndexChanged.connect(self._updateFilter)
        self.comboBoxProducts.currentIndexChanged.connect(self._updateFilter)
        self.timeEditFrom.timeChanged.connect(self._updateFilter)
        self.timeEditTo.timeChanged.connect(self._updateFilter)
        self.dateEditFrom.dateChanged.connect(self._updateFilter)
        self.dateEditTo.dateChanged.connect(self._updateFilter)
        self.spinBoxDelay.valueChanged.connect(self._updateFilter)
        self.action_Create_Report.triggered.connect(self.showReportDialog)
        self.buttonCreateReport.clicked.connect(self.showReportDialog)

    def generateReport(self, connections):
        """Generates a report for the given connections."""
        gen = ReportGenerator(self._db, connections)
        gen.doit()

    def showReportDialog(self):
        """Shows a dialog that lets the user generate a report."""
        d = DialogCreateReport(self._db, self)
        ret = d.exec_()
        if ret == DialogCreateReport.Accepted:
            cons = d.getSelectedConnections()
            if len(cons) > 0:
                self.generateReport(cons)
            else:
                msg = QMessageBox()
                msg.setText(self.tr("No connections selected"))
                msg.setIcon(QMessageBox.Critical)
                msg.exec_()

    def showAddConnectionDialog(self):
        """Shows a dialog which lets the user add new connections."""
        d = DialogAddConnection(self)
        ret = d.exec_()
        if ret == DialogAddConnection.Accepted:
            self._db.addConnection(d.startStation(), d.endStation())
            self._populateConnectionsFilter()
            self._connectionsModel.reset()

    def _updateFilter(self):
        """Updates the TrainFilter.
        Since the OverviewModel uses a reference of this TrainFilter, all
        changes here will automatically take effect in the OverviewModel."""
        fil = None
        if self.checkBoxConnectionFilter.checkState() == Qt.Checked:
            fil = self.comboBoxConnections.itemData(self.comboBoxConnections.currentIndex())
        self._trainFilter.setConnectionFilter(fil)

        fil = None
        if self.checkBoxDateFilter.checkState() == Qt.Checked:
            f, t = self.dateEditFrom.date(), self.dateEditTo.date()
            fil = (
                (".".join([str(f.day()), str(f.month()), str(f.year())])),
                (".".join([str(t.day()), str(t.month()), str(t.year())])),
            )
        self._trainFilter.setDateFilter(fil)

        fil = None
        if self.checkBoxTimeFilter.checkState() == Qt.Checked:
            f, t = self.timeEditFrom.time(), self.timeEditTo.time()
            f = strptime(":".join([str(f.hour()), str(f.minute())]), "%H:%M")
            t = strptime(":".join([str(t.hour()), str(t.minute())]), "%H:%M")
            fil = (f, t)
        self._trainFilter.setTimeFilter(fil)

        fil = None
        if self.checkBoxProductFilter.checkState() == Qt.Checked:
            fil = self.comboBoxProducts.currentText()
        self._trainFilter.setProductFilter(fil)

        fil = None
        if self.checkBoxDelayFilter.checkState() == Qt.Checked:
            fil = self.spinBoxDelay.value()
        self._trainFilter.setDelayFilter(fil)

    def _updateStats(self):
        """Queries the DatabaseBackend, creates statistics and displays them.
        """
        trains = self._db.getTrains()
        totalOnTime = 0
        totalDelayed = 0
        totalDelay = 0
        totalLogged = 0
        for t in trains:
            totalLogged += 1
            if not t.delay() is None:
                totalDelay += t.delay()
                totalDelayed += 1
            else:
                totalOnTime += 1
        if totalLogged > 0:
            self.labelTotalLogged.setText(str(totalLogged))
            self.labelTotalOnTime.setText(str(totalOnTime))
            self.labelTotalDelayed.setText(str(totalDelayed))
            self.labelOnTimePercentage.setText(str(100.0 - float(totalDelayed) / float(totalLogged) * 100.0) + "%")
            self.labelTotalDelay.setText(str(totalDelay))

            self._updateFilteredStats()

    def _updateFilteredStats(self):
        """Updates the stats for the currently selected connection."""
        self.labelTotalLoggedConnection.setText("")
        self.labelTotalOnTimeConnection.setText("")
        self.labelTotalDelayedConnection.setText("")
        self.labelOnTimePercentageConnection.setText("")
        self.labelTotalDelayConnection.setText("")
        self.labelConnection.setText("")
        con = self._trainFilter.connectionFilter()
        if not con is None:
            self.labelConnection.setText("{0} -> {1}".format(con[0], con[1]))
        else:
            self.labelConnection.setText("All Connections")
        trains = self._db.getTrainsFiltered(self._trainFilter)
        totalOnTime = 0
        totalDelayed = 0
        totalDelay = 0
        totalLogged = 0
        for t in trains:
            totalLogged += 1
            if not t.delay() is None:
                totalDelay += t.delay()
                totalDelayed += 1
            else:
                totalOnTime += 1
        if totalLogged > 0:
            self.labelTotalLoggedConnection.setText(str(totalLogged))
            self.labelTotalOnTimeConnection.setText(str(totalOnTime))
            self.labelTotalDelayedConnection.setText(str(totalDelayed))
            self.labelOnTimePercentageConnection.setText(
                str(100.0 - float(totalDelayed) / float(totalLogged) * 100.0) + "%"
            )
            self.labelTotalDelayConnection.setText(str(totalDelay))

    def _populateConnectionsFilter(self):
        """Retrieves all connections from the database and populates the
        connections combobox."""
        self.comboBoxConnections.clear()
        for c in self._db.getConnections():
            self.comboBoxConnections.addItem(c[0] + " -> " + c[1], c)

    def _populateProductFilter(self):
        """Retrieves all product strings from the database and populates the
        product combobox."""
        products = {}
        for t in self._db.getTrains():
            products[t.product()] = True

        for p in products.keys():
            self.comboBoxProducts.addItem(p)