Esempio n. 1
0
    def __init__(self, szprefix, no_warn=False, parent=None):
        """Filler 2 class constructor."""
        QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # check single instance
        try:
            self.single_instance = SingleInstance(LOCKFILE)
        except IOError:
            logger.error('another instance of Filler 2 is running, exiting...')
            self.criticalError(
                _translate(
                    "MainWindow",
                    "Cannot acquire a single instance lock. There is "
                    "another Filler 2 program running on the system."))

        # parse local SZARP configuration
        try:
            self.parser = IPKParser(szprefix)
        except IOError as err:
            logger.error("cannot read SZARP configuration")
            logger.error(str(err))
            self.criticalError(
                _translate("MainWindow", "Cannot read SZARP configuration") +
                " (%s)." % err.bad_path)
            sys.exit(1)
        except ValueError as err:
            logger.error(str(err))
            self.criticalError(
                _translate("MainWindow", "Non-valid SZARP database prefix."))
            sys.exit(1)

        logger.info("editing database of prefix '%s'", self.parser.ipk_prefix)

        # verify SZARP prefix versus hostname
        if no_warn == False:
            try:
                process = subprocess.Popen(["/bin/hostname", "-s"],
                                           stdout=subprocess.PIPE)
                out, err = process.communicate()
                if err == None:
                    hostname = out[:-1]

                if hostname != self.parser.ipk_prefix:
                    self.warningBox(
                        _translate(
                            "MainWindow",
                            "Warning! Database prefix differs from hostname, "
                            "you are probably modifying non-local database."))
            except OSError:
                pass

        ### initialize Qt4 widgets ##

        # name of the local configuration
        self.ui.titleLabel.setText(self.parser.getTitle())

        # list of parameter sets
        self.ui.listOfSets.addItem(
            _translate("MainWindow", "--- Choose a set of parameters ---"))
        self.ui.listOfSets.addItems(self.parser.getSets())
        self.ui.listOfSets.model().setData(
            self.ui.listOfSets.model().index(0, 0), QVariant(0),
            Qt.UserRole - 1)
        self.ui.listOfSets.setEnabled(True)

        # parameter's type combobox
        self.dialog_factory = ValueDialogFactory()

        for name, icon, desc in self.dialog_factory.get_dialogs():
            self.ui.valueType.addItem(icon, desc, QVariant((name, desc)))

        self.ui.valueType.model().setData(
            self.ui.valueType.model().index(0, 0), QVariant(0),
            Qt.UserRole - 1)

        # date interval variables
        self.fromDate = None
        self.toDate = None

        # table of changes
        base = 64
        self.ui.changesTable.setColumnCount(6)
        self.ui.changesTable.setColumnWidth(0,
                                            6 * base - 24)  # param's draw_name
        self.ui.changesTable.setColumnWidth(1, 3 * base)  # "from" date
        self.ui.changesTable.setColumnWidth(2, 3 * base)  # "to" date
        self.ui.changesTable.setColumnWidth(3, 3 * base)  # param's value type
        self.ui.changesTable.setColumnWidth(4,
                                            base - 20)  # remove entry button
        self.ui.changesTable.setColumnHidden(5, True)  # param's full name

        self.ui.changesTable.horizontalHeader().setVisible(False)
        self.ui.changesTable.setRowCount(0)
Esempio n. 2
0
    def __init__(self, szprefix, no_warn=False, parent=None):
        """Filler 2 class constructor."""
        QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # check single instance
        try:
            self.single_instance = SingleInstance(LOCKFILE)
        except IOError:
            logger.error("another instance of Filler 2 is running, exiting...")
            self.criticalError(
                _translate(
                    "MainWindow",
                    "Cannot acquire a single instance lock. There is "
                    "another Filler 2 program running on the system.",
                )
            )

            # parse local SZARP configuration
        try:
            self.parser = IPKParser(szprefix)
        except IOError as err:
            logger.error("cannot read SZARP configuration")
            logger.error(str(err))
            self.criticalError(_translate("MainWindow", "Cannot read SZARP configuration") + " (%s)." % err.bad_path)
            sys.exit(1)
        except ValueError as err:
            logger.error(str(err))
            self.criticalError(_translate("MainWindow", "Non-valid SZARP database prefix."))
            sys.exit(1)

        logger.info("editing database of prefix '%s'", self.parser.ipk_prefix)

        # verify SZARP prefix versus hostname
        if no_warn == False:
            try:
                process = subprocess.Popen(["/bin/hostname", "-s"], stdout=subprocess.PIPE)
                out, err = process.communicate()
                if err == None:
                    hostname = out[:-1]

                if hostname != self.parser.ipk_prefix:
                    self.warningBox(
                        _translate(
                            "MainWindow",
                            "Warning! Database prefix differs from hostname, "
                            "you are probably modifying non-local database.",
                        )
                    )
            except OSError:
                pass

                ### initialize Qt4 widgets ##

                # name of the local configuration
        self.ui.titleLabel.setText(self.parser.getTitle())

        # list of parameter sets
        self.ui.listOfSets.addItem(_translate("MainWindow", "--- Choose a set of parameters ---"))
        self.ui.listOfSets.addItems(self.parser.getSets())
        self.ui.listOfSets.model().setData(self.ui.listOfSets.model().index(0, 0), QVariant(0), Qt.UserRole - 1)
        self.ui.listOfSets.setEnabled(True)

        # parameter's type combobox
        self.dialog_factory = ValueDialogFactory()

        for name, icon, desc in self.dialog_factory.get_dialogs():
            self.ui.valueType.addItem(icon, desc, QVariant((name, desc)))

        self.ui.valueType.model().setData(self.ui.valueType.model().index(0, 0), QVariant(0), Qt.UserRole - 1)

        # date interval variables
        self.fromDate = None
        self.toDate = None

        # table of changes
        base = 64
        self.ui.changesTable.setColumnCount(6)
        self.ui.changesTable.setColumnWidth(0, 6 * base - 24)  # param's draw_name
        self.ui.changesTable.setColumnWidth(1, 3 * base)  # "from" date
        self.ui.changesTable.setColumnWidth(2, 3 * base)  # "to" date
        self.ui.changesTable.setColumnWidth(3, 3 * base)  # param's value type
        self.ui.changesTable.setColumnWidth(4, base - 20)  # remove entry button
        self.ui.changesTable.setColumnHidden(5, True)  # param's full name

        self.ui.changesTable.horizontalHeader().setVisible(False)
        self.ui.changesTable.setRowCount(0)
Esempio n. 3
0
class Filler2(QMainWindow):
    """SZARP Filler 2 application's main window (pyQt4)."""
    def __init__(self, szprefix, no_warn=False, parent=None):
        """Filler 2 class constructor."""
        QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # check single instance
        try:
            self.single_instance = SingleInstance(LOCKFILE)
        except IOError:
            logger.error('another instance of Filler 2 is running, exiting...')
            self.criticalError(
                _translate(
                    "MainWindow",
                    "Cannot acquire a single instance lock. There is "
                    "another Filler 2 program running on the system."))

        # parse local SZARP configuration
        try:
            self.parser = IPKParser(szprefix)
        except IOError as err:
            logger.error("cannot read SZARP configuration")
            logger.error(str(err))
            self.criticalError(
                _translate("MainWindow", "Cannot read SZARP configuration") +
                " (%s)." % err.bad_path)
            sys.exit(1)
        except ValueError as err:
            logger.error(str(err))
            self.criticalError(
                _translate("MainWindow", "Non-valid SZARP database prefix."))
            sys.exit(1)

        logger.info("editing database of prefix '%s'", self.parser.ipk_prefix)

        # verify SZARP prefix versus hostname
        if no_warn == False:
            try:
                process = subprocess.Popen(["/bin/hostname", "-s"],
                                           stdout=subprocess.PIPE)
                out, err = process.communicate()
                if err == None:
                    hostname = out[:-1]

                if hostname != self.parser.ipk_prefix:
                    self.warningBox(
                        _translate(
                            "MainWindow",
                            "Warning! Database prefix differs from hostname, "
                            "you are probably modifying non-local database."))
            except OSError:
                pass

        ### initialize Qt4 widgets ##

        # name of the local configuration
        self.ui.titleLabel.setText(self.parser.getTitle())

        # list of parameter sets
        self.ui.listOfSets.addItem(
            _translate("MainWindow", "--- Choose a set of parameters ---"))
        self.ui.listOfSets.addItems(self.parser.getSets())
        self.ui.listOfSets.model().setData(
            self.ui.listOfSets.model().index(0, 0), QVariant(0),
            Qt.UserRole - 1)
        self.ui.listOfSets.setEnabled(True)

        # parameter's type combobox
        self.dialog_factory = ValueDialogFactory()

        for name, icon, desc in self.dialog_factory.get_dialogs():
            self.ui.valueType.addItem(icon, desc, QVariant((name, desc)))

        self.ui.valueType.model().setData(
            self.ui.valueType.model().index(0, 0), QVariant(0),
            Qt.UserRole - 1)

        # date interval variables
        self.fromDate = None
        self.toDate = None

        # table of changes
        base = 64
        self.ui.changesTable.setColumnCount(6)
        self.ui.changesTable.setColumnWidth(0,
                                            6 * base - 24)  # param's draw_name
        self.ui.changesTable.setColumnWidth(1, 3 * base)  # "from" date
        self.ui.changesTable.setColumnWidth(2, 3 * base)  # "to" date
        self.ui.changesTable.setColumnWidth(3, 3 * base)  # param's value type
        self.ui.changesTable.setColumnWidth(4,
                                            base - 20)  # remove entry button
        self.ui.changesTable.setColumnHidden(5, True)  # param's full name

        self.ui.changesTable.horizontalHeader().setVisible(False)
        self.ui.changesTable.setRowCount(0)

    # end of __init__()

    def criticalError(self, msg, title=None):
        """Display critical error dialog and terminate.

		Arguments:
			msg - text message to be displayed.
			title - optional dialog title.
		"""
        if title is None:
            title = "SZARP Filler 2 - " + \
             _translate("MainWindow", "Critical Error")
        QMessageBox.critical(self, title, msg)
        sys.exit(1)

    # end of criticalError()

    def warningBox(self, msg, title=None):
        """Display warning dialog.

		Arguments:
			msg - text message to be displayed.
			title - optional dialog title.
		"""
        if title is None:
            title = "SZARP Filler 2 - " + _translate("MainWindow", "Warning")
        QMessageBox.warning(self, title, msg)

    # end of warningBox()

    def infoBox(self, msg, title=None):
        """Display information dialog.

		Arguments:
			msg - text message to be displayed.
			title - optional dialog title.
		"""
        if title is None:
            title = "SZARP Filler 2 - " + _translate("MainWindow",
                                                     "Information")
        QMessageBox.information(self, title, msg)

    # end of infoBox()

    def questionBox(self, msg, title=None):
        """Display question dialog.

		Arguments:
			msg - text message to be displayed.
			title - optional dialog title.

		Returns:
			QMessageBox.Yes | QMessageBox.No - user's answer.
		"""
        if title is None:
            title = "SZARP Filler 2 - " + _translate("MainWindow", "Question")
        return QMessageBox.question(self, title, msg,
                                    QMessageBox.Yes | QMessageBox.No,
                                    QMessageBox.Yes)

    # end of questionBox()

    def onSetChosen(self, text):
        """Slot for signal activated(QString) from 'listOfSets' (QComboBox).

		Arguments:
			text - name of the chosen set.
		"""
        self.ui.paramList.clear()
        self.ui.paramList.addItem(
            _translate("MainWindow", "--- Choose a parameter ---"))
        self.ui.paramList.model().setData(
            self.ui.paramList.model().index(0, 0), QVariant(0),
            Qt.UserRole - 1)

        # insert a list of parameters from given set
        for p in self.parser.getParams(unicode(text)):
            self.ui.paramList.addItem(p.draw_name, p)

        # activate/reset other ui elements
        self.ui.paramList.setEnabled(True)
        self.ui.paramList.setFocus()
        self.ui.valueType.setCurrentIndex(0)
        self.ui.valueType.setEnabled(False)
        self.ui.addButton.setEnabled(False)

    # end of onSetChosen()

    def onParamChosen(self, index):
        """Slot for signal activated(QString) from 'paramList' (QComboBox).

		Arguments:
			text - name of chosen parameter (not used).
		"""
        # activate other ui elements
        self.ui.fromDate.setEnabled(True)
        self.ui.toDate.setEnabled(True)
        self.ui.valueType.setEnabled(True)
        self.type_dialog = None
        self.validateInput()

    # end of onParamChosen()

    def onFromDate(self):
        """Slot for signal clicked() from 'fromDate' (QPushButton). Displays dialog
		for choosing date and time.
		"""
        if self.fromDate is None:
            if self.toDate is None:
                dlg = DatetimeDialog_impl()
            else:
                dlg = DatetimeDialog_impl(
                    start_date=(self.toDate - datetime.timedelta(minutes=10)))
        else:
            if self.toDate is None or self.fromDate < self.toDate:
                dlg = DatetimeDialog_impl(start_date=self.fromDate)
            else:
                dlg = DatetimeDialog_impl(
                    start_date=(self.toDate - datetime.timedelta(minutes=10)))

        # execute DatetimeDialog
        if dlg.exec_():
            self.fromDate = dlg.getValue()
            self.ui.fromDate.setText(
                _translate("MainWindow", "From:") + " " +
                self.fromDate.strftime('%Y-%m-%d %H:%M'))
            self.validateInput()

    # end of onFromDate()

    def onToDate(self):
        """Slot for signal clicked() from 'toDate' (QPushButton). Displays dialog
		for choosing date and time.
		"""
        if self.toDate is None:
            if self.fromDate is None:
                dlg = DatetimeDialog_impl()
            else:
                dlg = DatetimeDialog_impl(
                    start_date=(self.fromDate +
                                datetime.timedelta(minutes=10)))
        else:
            if self.fromDate is None or self.toDate > self.fromDate:
                dlg = DatetimeDialog_impl(start_date=self.toDate)
            else:
                dlg = DatetimeDialog_impl(
                    start_date=(self.fromDate +
                                datetime.timedelta(minutes=10)))

        # execute DatetimeDialog
        if dlg.exec_():
            self.toDate = dlg.getValue()
            self.ui.toDate.setText(
                _translate("MainWindow", "To:") + " " +
                self.toDate.strftime('%Y-%m-%d %H:%M'))
            self.validateInput()

    # end of onToDate()

    def onTypeChosen(self, index):
        """Slot for signal activated() from 'valueType' (QComboBox). Constructs
		appropriate dialog from factory and collects chosen plot parameters.
		"""
        # fetch dialog and parameter data
        dlg_name = self.ui.valueType.itemData(index).toPyObject()[0]
        param_info = self.ui.paramList.itemData(
            self.ui.paramList.currentIndex()).toPyObject()

        dlg = self.dialog_factory.construct(str(dlg_name),
                                            param_info.prec,
                                            param_info.lswmsw,
                                            parent=self)

        # reset type items' texts
        for i in range(self.ui.valueType.count()):
            desc = self.ui.valueType.itemData(i).toPyObject()[1]
            self.ui.valueType.setItemText(i, desc)

        if dlg.exec_():
            self.type_dialog = dlg
            self.ui.valueType.setItemText(index, dlg.get_value_desc())
        else:
            self.ui.valueType.setCurrentIndex(0)
            self.type_dialog = None
        self.validateInput()

    # end of onTypeChosen()

    def validateInput(self):
        """Check whether all needed data is filled and valid. If do, "Add"
		button is activated.
		"""
        if  self.ui.paramList.currentIndex() != 0 and \
         self.fromDate is not None and \
         self.toDate is not None and \
         self.ui.valueType.currentIndex() != 0:
            self.ui.addButton.setEnabled(True)
        else:
            self.ui.addButton.setEnabled(False)

    # end of validateInput()

    def aboutQt(self):
        """Display about Qt4 dialog."""
        QMessageBox.aboutQt(self)

    def about(self):
        """Display about Filler 2 dialog."""
        AboutDialog_impl().exec_()

    def addChange(self):
        """Slot for signal clicked() from addButton (QPushButton). Adds
		change-entry to changesTable (QTableWidget)."""
        if self.fromDate >= self.toDate:
            self.warningBox(
                _translate(
                    "MainWindow",
                    "\"To\" date is earlier (or equals) \"From\" date.\nAdding change aborted."
                ))
            return

        if self.toDate >= datetime.datetime.now():
            if QMessageBox.Yes != \
              self.questionBox(_translate("MainWindow",
               "You are trying to modify future data - "
               "it will block SZARP from writing actual data in this period.\n\n"
               "Are you sure that's what you really want to do?")):
                return

        param_info = self.ui.paramList.itemData(
            self.ui.paramList.currentIndex()).toPyObject()

        self.ui.changesTable.setRowCount(self.ui.changesTable.rowCount() + 1)
        self.addRow(self.ui.changesTable.rowCount() - 1, param_info.name,
                    self.ui.paramList.currentText(), self.fromDate,
                    self.toDate, self.type_dialog, param_info.lswmsw)

        # reset type items' texts
        for i in range(self.ui.valueType.count()):
            desc = self.ui.valueType.itemData(i).toPyObject()[1]
            self.ui.valueType.setItemText(i, desc)
        self.ui.valueType.setCurrentIndex(0)

    # end of addChange()

    def addRow(self, row, fname, pname, from_date, to_date, typedlg, lswmsw):
        """Add row to changesTable (QTableWidget).

		Arguments:
			row - number of row to be set.
			fname - full parameter name
			pname - parameter's draw name
			from_date - beginning of time period
			to_date - end of time period
			value - parameter's value
			typedlg - object of input value dialog
			lswmsw - whether parametr is a combined lsw/msw
		"""
        # visible columns
        item_pname = QTableWidgetItem(unicode(pname))
        item_pname.setFlags(Qt.ItemIsEnabled)

        item_from_date = QTableWidgetItem(from_date.strftime('%Y-%m-%d %H:%M'))
        item_from_date.setFlags(Qt.ItemIsEnabled)
        item_from_date.setTextAlignment(Qt.AlignCenter)

        item_to_date = QTableWidgetItem(to_date.strftime('%Y-%m-%d %H:%M'))
        item_to_date.setFlags(Qt.ItemIsEnabled)
        item_to_date.setTextAlignment(Qt.AlignCenter)

        item_value = QTableWidgetItem(typedlg.get_value_desc())
        item_value.setFlags(Qt.ItemIsEnabled)
        item_value.setIcon(QIcon(typedlg.qicon_path))
        item_value.setTextAlignment(Qt.AlignCenter)

        # hidden column
        item_fname = QTableWidgetItem(unicode(fname))
        item_fname.setData(Qt.UserRole, QVariant((lswmsw, typedlg)))
        item_fname.setFlags(Qt.ItemIsEnabled)

        self.ui.changesTable.setItem(row, 0, item_pname)
        self.ui.changesTable.setItem(row, 1, item_from_date)
        self.ui.changesTable.setItem(row, 2, item_to_date)
        self.ui.changesTable.setItem(row, 3, item_value)
        self.ui.changesTable.setItem(row, 5, item_fname)

        # "remove" button widget
        rm_button = QPushButton(QIcon.fromTheme("window-close"), "")
        rm_button.setToolTip(_translate("MainWindow", "Remove entry"))
        rm_button.row_id = row
        QObject.connect(rm_button, SIGNAL("clicked()"), self.removeChange)
        self.ui.changesTable.setCellWidget(row, 4, rm_button)

    # end of addRow()

    def removeChange(self):
        """Slot for signal clicked() from rm_button (QPushButton). Removes
		entry from changesTable (QTableWidget).
		"""
        if QMessageBox.Yes != \
          self.questionBox(_translate("MainWindow", "Remove change?")):
            return

        row = self.sender().row_id
        self.ui.changesTable.removeRow(row)

        # update row_id for every row
        for i in range(row, self.ui.changesTable.rowCount()):
            self.ui.changesTable.cellWidget(i, 4).row_id -= 1

    # end of removeChange()

    def clearChanges(self):
        """Slot for action 'actionClear'. Removes all entries from
		changesTable (QTableWidget).
		"""
        txt = _translate("MainWindow",
                         "Are you sure you want to clear all changes?")

        if QMessageBox.Yes == self.questionBox(txt):
            self.ui.changesTable.setRowCount(0)

    # end of clearChanges()

    def commitChanges(self):
        """Slot for action 'actionSaveData'. Commits all scheduled changes
		to local szbase.
		"""
        if self.ui.changesTable.rowCount() == 0:
            self.warningBox(_translate("MainWindow", "No changes to commit."))
            return

        # list and confirm
        txt = _translate("MainWindow",
                         "Following parameters will be modified:") + "\n\n"

        for i in range(0, self.ui.changesTable.rowCount()):
            txt.append("   * %s\n\n" \
              % (self.ui.changesTable.item(i,0).text()))

        txt.append(_translate("MainWindow", "Commit changes?"))

        if QMessageBox.Yes == self.questionBox(txt):
            # construct list of changes to be committed
            logger.info("committing scheduled changes...")
            changes_list = []

            for i in range(0, self.ui.changesTable.rowCount()):

                start_date = datetime.datetime.strptime(
                    str(self.ui.changesTable.item(i, 1).text()),
                    '%Y-%m-%d %H:%M')

                end_date = datetime.datetime.strptime(
                    str(self.ui.changesTable.item(i, 2).text()),
                    '%Y-%m-%d %H:%M')

                lswmsw, typedlg = \
                 self.ui.changesTable.item(i,5).data(Qt.UserRole).toPyObject()

                # generate list of 10-minute probes in given interval
                dsec = int((end_date - start_date).total_seconds())
                dts = [start_date + datetime.timedelta(minutes=x) \
                  for x in range(0, dsec / 60 + 1, 10)]
                # generate probes' values
                dvals = typedlg.generate(dts)

                rmrk = typedlg.get_remark()

                changes_list.append(
                    SzChangeInfo(draw_name=unicode(
                        self.ui.changesTable.item(i, 0).text()),
                                 name=unicode(
                                     self.ui.changesTable.item(i, 5).text()),
                                 dvalues=dvals,
                                 lswmsw=lswmsw,
                                 remark=rmrk))

            # do the job (in a new thread)
            szbw = SzbWriter(changes_list, self.parser)
            szbp = SzbProgressWin(szbw, parent=self)

            # reset all GUI elements
            self.ui.changesTable.setRowCount(0)
            self.fromDate = None
            self.toDate = None
            self.ui.listOfSets.setCurrentIndex(0)
            self.ui.paramList.clear()
            self.ui.paramList.setEnabled(False)
            self.ui.fromDate.setText(_translate("MainWindow", "From:"))
            self.ui.fromDate.setEnabled(False)
            self.ui.toDate.setText(_translate("MainWindow", "To:"))
            self.ui.toDate.setEnabled(False)
            self.ui.valueType.setCurrentIndex(0)
            self.ui.valueType.setEnabled(False)
            self.ui.addButton.setEnabled(False)

            # disable main window until job is finished
            self.setEnabled(False)

    # end of commitChanges()

    def contextHelp(self):
        """Slot for action 'actionContextHelp'. Activates "What is that?" mode."""
        QWhatsThis.enterWhatsThisMode()

    def onViewHistory(self):
        """Slot for action 'actionViewHistory'. Shows history of committed changes."""
        HistoryDialog_impl(self.parser, parent=self).exec_()
Esempio n. 4
0
class Filler2(QMainWindow):
    """SZARP Filler 2 application's main window (pyQt4)."""

    def __init__(self, szprefix, no_warn=False, parent=None):
        """Filler 2 class constructor."""
        QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # check single instance
        try:
            self.single_instance = SingleInstance(LOCKFILE)
        except IOError:
            logger.error("another instance of Filler 2 is running, exiting...")
            self.criticalError(
                _translate(
                    "MainWindow",
                    "Cannot acquire a single instance lock. There is "
                    "another Filler 2 program running on the system.",
                )
            )

            # parse local SZARP configuration
        try:
            self.parser = IPKParser(szprefix)
        except IOError as err:
            logger.error("cannot read SZARP configuration")
            logger.error(str(err))
            self.criticalError(_translate("MainWindow", "Cannot read SZARP configuration") + " (%s)." % err.bad_path)
            sys.exit(1)
        except ValueError as err:
            logger.error(str(err))
            self.criticalError(_translate("MainWindow", "Non-valid SZARP database prefix."))
            sys.exit(1)

        logger.info("editing database of prefix '%s'", self.parser.ipk_prefix)

        # verify SZARP prefix versus hostname
        if no_warn == False:
            try:
                process = subprocess.Popen(["/bin/hostname", "-s"], stdout=subprocess.PIPE)
                out, err = process.communicate()
                if err == None:
                    hostname = out[:-1]

                if hostname != self.parser.ipk_prefix:
                    self.warningBox(
                        _translate(
                            "MainWindow",
                            "Warning! Database prefix differs from hostname, "
                            "you are probably modifying non-local database.",
                        )
                    )
            except OSError:
                pass

                ### initialize Qt4 widgets ##

                # name of the local configuration
        self.ui.titleLabel.setText(self.parser.getTitle())

        # list of parameter sets
        self.ui.listOfSets.addItem(_translate("MainWindow", "--- Choose a set of parameters ---"))
        self.ui.listOfSets.addItems(self.parser.getSets())
        self.ui.listOfSets.model().setData(self.ui.listOfSets.model().index(0, 0), QVariant(0), Qt.UserRole - 1)
        self.ui.listOfSets.setEnabled(True)

        # parameter's type combobox
        self.dialog_factory = ValueDialogFactory()

        for name, icon, desc in self.dialog_factory.get_dialogs():
            self.ui.valueType.addItem(icon, desc, QVariant((name, desc)))

        self.ui.valueType.model().setData(self.ui.valueType.model().index(0, 0), QVariant(0), Qt.UserRole - 1)

        # date interval variables
        self.fromDate = None
        self.toDate = None

        # table of changes
        base = 64
        self.ui.changesTable.setColumnCount(6)
        self.ui.changesTable.setColumnWidth(0, 6 * base - 24)  # param's draw_name
        self.ui.changesTable.setColumnWidth(1, 3 * base)  # "from" date
        self.ui.changesTable.setColumnWidth(2, 3 * base)  # "to" date
        self.ui.changesTable.setColumnWidth(3, 3 * base)  # param's value type
        self.ui.changesTable.setColumnWidth(4, base - 20)  # remove entry button
        self.ui.changesTable.setColumnHidden(5, True)  # param's full name

        self.ui.changesTable.horizontalHeader().setVisible(False)
        self.ui.changesTable.setRowCount(0)

        # end of __init__()

    def criticalError(self, msg, title=None):
        """Display critical error dialog and terminate.

		Arguments:
			msg - text message to be displayed.
			title - optional dialog title.
		"""
        if title is None:
            title = "SZARP Filler 2 - " + _translate("MainWindow", "Critical Error")
        QMessageBox.critical(self, title, msg)
        sys.exit(1)

        # end of criticalError()

    def warningBox(self, msg, title=None):
        """Display warning dialog.

		Arguments:
			msg - text message to be displayed.
			title - optional dialog title.
		"""
        if title is None:
            title = "SZARP Filler 2 - " + _translate("MainWindow", "Warning")
        QMessageBox.warning(self, title, msg)

        # end of warningBox()

    def infoBox(self, msg, title=None):
        """Display information dialog.

		Arguments:
			msg - text message to be displayed.
			title - optional dialog title.
		"""
        if title is None:
            title = "SZARP Filler 2 - " + _translate("MainWindow", "Information")
        QMessageBox.information(self, title, msg)

        # end of infoBox()

    def questionBox(self, msg, title=None):
        """Display question dialog.

		Arguments:
			msg - text message to be displayed.
			title - optional dialog title.

		Returns:
			QMessageBox.Yes | QMessageBox.No - user's answer.
		"""
        if title is None:
            title = "SZARP Filler 2 - " + _translate("MainWindow", "Question")
        return QMessageBox.question(self, title, msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)

        # end of questionBox()

    def onSetChosen(self, text):
        """Slot for signal activated(QString) from 'listOfSets' (QComboBox).

		Arguments:
			text - name of the chosen set.
		"""
        self.ui.paramList.clear()
        self.ui.paramList.addItem(_translate("MainWindow", "--- Choose a parameter ---"))
        self.ui.paramList.model().setData(self.ui.paramList.model().index(0, 0), QVariant(0), Qt.UserRole - 1)

        # insert a list of parameters from given set
        for p in self.parser.getParams(unicode(text)):
            self.ui.paramList.addItem(p.draw_name, p)

            # activate/reset other ui elements
        self.ui.paramList.setEnabled(True)
        self.ui.paramList.setFocus()
        self.ui.valueType.setCurrentIndex(0)
        self.ui.valueType.setEnabled(False)
        self.ui.addButton.setEnabled(False)

        # end of onSetChosen()

    def onParamChosen(self, index):
        """Slot for signal activated(QString) from 'paramList' (QComboBox).

		Arguments:
			text - name of chosen parameter (not used).
		"""
        # activate other ui elements
        self.ui.fromDate.setEnabled(True)
        self.ui.toDate.setEnabled(True)
        self.ui.valueType.setEnabled(True)
        self.type_dialog = None
        self.validateInput()

        # end of onParamChosen()

    def onFromDate(self):
        """Slot for signal clicked() from 'fromDate' (QPushButton). Displays dialog
		for choosing date and time.
		"""
        if self.fromDate is None:
            if self.toDate is None:
                dlg = DatetimeDialog_impl()
            else:
                dlg = DatetimeDialog_impl(start_date=(self.toDate - datetime.timedelta(minutes=10)))
        else:
            if self.toDate is None or self.fromDate < self.toDate:
                dlg = DatetimeDialog_impl(start_date=self.fromDate)
            else:
                dlg = DatetimeDialog_impl(start_date=(self.toDate - datetime.timedelta(minutes=10)))

                # execute DatetimeDialog
        if dlg.exec_():
            self.fromDate = dlg.getValue()
            self.ui.fromDate.setText(_translate("MainWindow", "From:") + " " + self.fromDate.strftime("%Y-%m-%d %H:%M"))
            self.validateInput()

            # end of onFromDate()

    def onToDate(self):
        """Slot for signal clicked() from 'toDate' (QPushButton). Displays dialog
		for choosing date and time.
		"""
        if self.toDate is None:
            if self.fromDate is None:
                dlg = DatetimeDialog_impl()
            else:
                dlg = DatetimeDialog_impl(start_date=(self.fromDate + datetime.timedelta(minutes=10)))
        else:
            if self.fromDate is None or self.toDate > self.fromDate:
                dlg = DatetimeDialog_impl(start_date=self.toDate)
            else:
                dlg = DatetimeDialog_impl(start_date=(self.fromDate + datetime.timedelta(minutes=10)))

                # execute DatetimeDialog
        if dlg.exec_():
            self.toDate = dlg.getValue()
            self.ui.toDate.setText(_translate("MainWindow", "To:") + " " + self.toDate.strftime("%Y-%m-%d %H:%M"))
            self.validateInput()

            # end of onToDate()

    def onTypeChosen(self, index):
        """Slot for signal activated() from 'valueType' (QComboBox). Constructs
		appropriate dialog from factory and collects chosen plot parameters.
		"""
        # fetch dialog and parameter data
        dlg_name = self.ui.valueType.itemData(index).toPyObject()[0]
        param_info = self.ui.paramList.itemData(self.ui.paramList.currentIndex()).toPyObject()

        dlg = self.dialog_factory.construct(str(dlg_name), param_info.prec, param_info.lswmsw, parent=self)

        # reset type items' texts
        for i in range(self.ui.valueType.count()):
            desc = self.ui.valueType.itemData(i).toPyObject()[1]
            self.ui.valueType.setItemText(i, desc)

        if dlg.exec_():
            self.type_dialog = dlg
            self.ui.valueType.setItemText(index, dlg.get_value_desc())
        else:
            self.ui.valueType.setCurrentIndex(0)
            self.type_dialog = None
        self.validateInput()

        # end of onTypeChosen()

    def validateInput(self):
        """Check whether all needed data is filled and valid. If do, "Add"
		button is activated.
		"""
        if (
            self.ui.paramList.currentIndex() != 0
            and self.fromDate is not None
            and self.toDate is not None
            and self.ui.valueType.currentIndex() != 0
        ):
            self.ui.addButton.setEnabled(True)
        else:
            self.ui.addButton.setEnabled(False)

            # end of validateInput()

    def aboutQt(self):
        """Display about Qt4 dialog."""
        QMessageBox.aboutQt(self)

    def about(self):
        """Display about Filler 2 dialog."""
        AboutDialog_impl().exec_()

    def addChange(self):
        """Slot for signal clicked() from addButton (QPushButton). Adds
		change-entry to changesTable (QTableWidget)."""
        if self.fromDate >= self.toDate:
            self.warningBox(
                _translate("MainWindow", '"To" date is earlier (or equals) "From" date.\nAdding change aborted.')
            )
            return

        if self.toDate >= datetime.datetime.now():
            if QMessageBox.Yes != self.questionBox(
                _translate(
                    "MainWindow",
                    "You are trying to modify future data - "
                    "it will block SZARP from writing actual data in this period.\n\n"
                    "Are you sure that's what you really want to do?",
                )
            ):
                return

        param_info = self.ui.paramList.itemData(self.ui.paramList.currentIndex()).toPyObject()

        self.ui.changesTable.setRowCount(self.ui.changesTable.rowCount() + 1)
        self.addRow(
            self.ui.changesTable.rowCount() - 1,
            param_info.name,
            self.ui.paramList.currentText(),
            self.fromDate,
            self.toDate,
            self.type_dialog,
            param_info.lswmsw,
        )

        # reset type items' texts
        for i in range(self.ui.valueType.count()):
            desc = self.ui.valueType.itemData(i).toPyObject()[1]
            self.ui.valueType.setItemText(i, desc)
        self.ui.valueType.setCurrentIndex(0)

        # end of addChange()

    def addRow(self, row, fname, pname, from_date, to_date, typedlg, lswmsw):
        """Add row to changesTable (QTableWidget).

		Arguments:
			row - number of row to be set.
			fname - full parameter name
			pname - parameter's draw name
			from_date - beginning of time period
			to_date - end of time period
			value - parameter's value
			typedlg - object of input value dialog
			lswmsw - whether parametr is a combined lsw/msw
		"""
        # visible columns
        item_pname = QTableWidgetItem(unicode(pname))
        item_pname.setFlags(Qt.ItemIsEnabled)

        item_from_date = QTableWidgetItem(from_date.strftime("%Y-%m-%d %H:%M"))
        item_from_date.setFlags(Qt.ItemIsEnabled)
        item_from_date.setTextAlignment(Qt.AlignCenter)

        item_to_date = QTableWidgetItem(to_date.strftime("%Y-%m-%d %H:%M"))
        item_to_date.setFlags(Qt.ItemIsEnabled)
        item_to_date.setTextAlignment(Qt.AlignCenter)

        item_value = QTableWidgetItem(typedlg.get_value_desc())
        item_value.setFlags(Qt.ItemIsEnabled)
        item_value.setIcon(QIcon(typedlg.qicon_path))
        item_value.setTextAlignment(Qt.AlignCenter)

        # hidden column
        item_fname = QTableWidgetItem(unicode(fname))
        item_fname.setData(Qt.UserRole, QVariant((lswmsw, typedlg)))
        item_fname.setFlags(Qt.ItemIsEnabled)

        self.ui.changesTable.setItem(row, 0, item_pname)
        self.ui.changesTable.setItem(row, 1, item_from_date)
        self.ui.changesTable.setItem(row, 2, item_to_date)
        self.ui.changesTable.setItem(row, 3, item_value)
        self.ui.changesTable.setItem(row, 5, item_fname)

        # "remove" button widget
        rm_button = QPushButton(QIcon.fromTheme("window-close"), "")
        rm_button.setToolTip(_translate("MainWindow", "Remove entry"))
        rm_button.row_id = row
        QObject.connect(rm_button, SIGNAL("clicked()"), self.removeChange)
        self.ui.changesTable.setCellWidget(row, 4, rm_button)

        # end of addRow()

    def removeChange(self):
        """Slot for signal clicked() from rm_button (QPushButton). Removes
		entry from changesTable (QTableWidget).
		"""
        if QMessageBox.Yes != self.questionBox(_translate("MainWindow", "Remove change?")):
            return

        row = self.sender().row_id
        self.ui.changesTable.removeRow(row)

        # update row_id for every row
        for i in range(row, self.ui.changesTable.rowCount()):
            self.ui.changesTable.cellWidget(i, 4).row_id -= 1

            # end of removeChange()

    def clearChanges(self):
        """Slot for action 'actionClear'. Removes all entries from
		changesTable (QTableWidget).
		"""
        txt = _translate("MainWindow", "Are you sure you want to clear all changes?")

        if QMessageBox.Yes == self.questionBox(txt):
            self.ui.changesTable.setRowCount(0)

            # end of clearChanges()

    def commitChanges(self):
        """Slot for action 'actionSaveData'. Commits all scheduled changes
		to local szbase.
		"""
        if self.ui.changesTable.rowCount() == 0:
            self.warningBox(_translate("MainWindow", "No changes to commit."))
            return

            # list and confirm
        txt = _translate("MainWindow", "Following parameters will be modified:") + "\n\n"

        for i in range(0, self.ui.changesTable.rowCount()):
            txt.append("   * %s\n\n" % (self.ui.changesTable.item(i, 0).text()))

        txt.append(_translate("MainWindow", "Commit changes?"))

        if QMessageBox.Yes == self.questionBox(txt):
            # construct list of changes to be committed
            logger.info("committing scheduled changes...")
            changes_list = []

            for i in range(0, self.ui.changesTable.rowCount()):

                start_date = datetime.datetime.strptime(str(self.ui.changesTable.item(i, 1).text()), "%Y-%m-%d %H:%M")

                end_date = datetime.datetime.strptime(str(self.ui.changesTable.item(i, 2).text()), "%Y-%m-%d %H:%M")

                lswmsw, typedlg = self.ui.changesTable.item(i, 5).data(Qt.UserRole).toPyObject()

                # generate list of 10-minute probes in given interval
                dsec = int((end_date - start_date).total_seconds())
                dts = [start_date + datetime.timedelta(minutes=x) for x in range(0, dsec / 60 + 1, 10)]
                # generate probes' values
                dvals = typedlg.generate(dts)

                rmrk = typedlg.get_remark()

                changes_list.append(
                    SzChangeInfo(
                        draw_name=unicode(self.ui.changesTable.item(i, 0).text()),
                        name=unicode(self.ui.changesTable.item(i, 5).text()),
                        dvalues=dvals,
                        lswmsw=lswmsw,
                        remark=rmrk,
                    )
                )

                # do the job (in a new thread)
            szbw = SzbWriter(changes_list, self.parser)
            szbp = SzbProgressWin(szbw, parent=self)

            # reset all GUI elements
            self.ui.changesTable.setRowCount(0)
            self.fromDate = None
            self.toDate = None
            self.ui.listOfSets.setCurrentIndex(0)
            self.ui.paramList.clear()
            self.ui.paramList.setEnabled(False)
            self.ui.fromDate.setText(_translate("MainWindow", "From:"))
            self.ui.fromDate.setEnabled(False)
            self.ui.toDate.setText(_translate("MainWindow", "To:"))
            self.ui.toDate.setEnabled(False)
            self.ui.valueType.setCurrentIndex(0)
            self.ui.valueType.setEnabled(False)
            self.ui.addButton.setEnabled(False)

            # disable main window until job is finished
            self.setEnabled(False)

            # end of commitChanges()

    def contextHelp(self):
        """Slot for action 'actionContextHelp'. Activates "What is that?" mode."""
        QWhatsThis.enterWhatsThisMode()

    def onViewHistory(self):
        """Slot for action 'actionViewHistory'. Shows history of committed changes."""
        HistoryDialog_impl(self.parser, parent=self).exec_()