Beispiel #1
0
class InterfacePage(QWizardPage):
    """
    Allows the user to choose one among networkable interfaces to build a net upon.
    """
    def __init__(self, parent=None):
        QWizardPage.__init__(self, parent)
        self.__make_gui()
        self.__populate()
        self.connect(self.__dropdown, SIGNAL("currentIndexChanged(int)"), self.propagate)

    def __make_gui(self):
        self.setTitle(tr("Network Editor"))
        self.setSubTitle(tr("Select the interface to which you want to add a network"))
        box = QVBoxLayout(self)
        self.__dropdown = QComboBox()
        box.addWidget(self.__dropdown)

    def __candidates(self):
        candidates = list(
            QNetObject.getInstance().netcfg.iterNetworkables()
            )
        candidates.sort()
        return candidates

    def __populate(self):
        candidates = self.__candidates()
        for interface in candidates:
            variant = QVariant(interface)
            self.__dropdown.addItem(interface.fullName(), variant)

    def propagate(self):
        """
        propagate: emits a "changed" SIGNAL with the chosen interface as content
        """
        self.emit(SIGNAL("changed"), self.interface())

    def interface(self):
        """
        returns the currently selected interface
        """
        #QVariant with custom content
        variant = self.__dropdown.itemData(
            self.__dropdown.currentIndex()
            )
        interface = variant.toPyObject()
        return interface

    def setInterface(self, target):
        for index in xrange(self.__dropdown.count()):
            variant = self.__dropdown.itemData(index)
            interface = variant.toPyObject()
            if interface is target:
                break
        self.__dropdown.setCurrentIndex(index)
Beispiel #2
0
class AddAddressColumnDialog(utils.Dialog):
    def __init__(self, parent, hex_widget, column):
        utils.Dialog.__init__(self, parent, name='add_address_column_dialog')
        self.hexWidget = hex_widget
        self.column = column
        self.setWindowTitle(utils.tr('Add address bar'))

        self.setLayout(QVBoxLayout())

        self.configWidget = AddressColumnConfigurationWidget(self, hex_widget, None)
        self.layout().addWidget(self.configWidget)

        self.txtName = QLineEdit(self)
        self.configWidget.layout().insertRow(0, utils.tr('Name:'), self.txtName)

        self.cmbAlignment = QComboBox(self)
        self.cmbAlignment.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.cmbAlignment.addItem(utils.tr('To the left'), Qt.AlignLeft)
        self.cmbAlignment.addItem(utils.tr('To the right'), Qt.AlignRight)
        self.configWidget.layout().insertRow(1, utils.tr('Position:'), self.cmbAlignment)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.layout().addWidget(self.buttonBox)

    def addColumn(self):
        model = self.configWidget.createColumnModel(self.hexWidget)
        model.name = self.txtName.text()
        self.hexWidget.addAddressColumn(model, self.cmbAlignment.itemData(self.cmbAlignment.currentIndex()))
class GoogleFinanceUrlSetupDialog(QDialog):

    SETTING_GOOGLE_URL = 'googleUrl'
    SETTING_GOOGLE_COUNTRY = 'googleCountry'

    def __init__(self, parent):

        QDialog.__init__(self, parent)

        self.prop = MaeMoneyProperties.instance()
        self.urls = {}
        self.urls[self.prop.GOOGLE_COUNTRY_HK] = 'www.google.com.hk'
        self.urls[self.prop.GOOGLE_COUNTRY_CN] = 'www.google.com.cn'
        self.urls[self.prop.GOOGLE_COUNTRY_CAN] = 'www.google.ca'
        self.urls[self.prop.GOOGLE_COUNTRY_UK] = 'www.google.co.uk'
        self.urls[self.prop.GOOGLE_COUNTRY_US] = 'www.google.com'

        self.setupUi()

    def setupUi(self):
        self.setWindowModality(Qt.WindowModal)
        self.buttonBox = QDialogButtonBox(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)

        self.gridLayout = QGridLayout()
        self.setLayout(self.gridLayout)

        self.labelGFinanceUrl = QLabel(self.tr("Google URL"))
        self.gridLayout.addWidget(self.labelGFinanceUrl, 0, 1, 1, 1)
        self.comboBoxGFinanceUrl = QComboBox()
        for [country, url] in sorted(self.urls.iteritems()):
            self.comboBoxGFinanceUrl.addItem(country, url)

        googleCountry = self.prop.getGoogleCountry()
        index = self.comboBoxGFinanceUrl.findText(googleCountry)
        self.comboBoxGFinanceUrl.setCurrentIndex(index)
        self.gridLayout.addWidget(self.comboBoxGFinanceUrl, 0, 2, 1, 1)

        self.gridLayout.addWidget(QLabel(self.tr("Current setting")), 1, 1, 1, 1)
        self.gridLayout.addWidget(QLabel(self.prop.getGoogleCountry()),
                                  1, 2, 1, 1)

        self.setUrlButton = QPushButton(self.tr("Set URL"))
        self.gridLayout.addWidget(self.setUrlButton, 2, 1, 1, 2)

        self.loginErrorMsgLabel = QLabel("")
        self.gridLayout.addWidget(self.loginErrorMsgLabel, 3, 1, 1, 2)

        self.setWindowTitle(self.tr("Setup"))

        self.connect(self.buttonBox, SIGNAL("accepted()"), self.accept)
        self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
        self.connect(self.setUrlButton, SIGNAL("clicked()"), self.setUrl)

    def setUrl(self):
        indexSelected = self.comboBoxGFinanceUrl.currentIndex()
        country = self.comboBoxGFinanceUrl.itemText(indexSelected)
        url = self.comboBoxGFinanceUrl.itemData(indexSelected).toString().toAscii()
        self.prop.setGoogleCountryUrl(country, url)
        self.accept()
Beispiel #4
0
class AddressColumnConfigurationWidget(columnproviders.AbstractColumnConfigurationWidget, QWidget):
    def __init__(self, parent, hex_widget, column):
        columnproviders.AbstractColumnConfigurationWidget.__init__(self)
        QWidget.__init__(self, parent)
        self.hexWidget = hex_widget
        self.column = column

        self.setLayout(QFormLayout())

        self.cmbBase = QComboBox(self)
        self.cmbBase.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Base:'), self.cmbBase)
        for base in ((utils.tr('Hex'), 16), (utils.tr('Dec'), 10), (utils.tr('Oct'), 8), (utils.tr('Bin'), 2)):
            self.cmbBase.addItem(base[0], base[1])
        if column is not None:
            self.cmbBase.setCurrentIndex(self.cmbBase.findData(column.formatter.base))

        self.cmbStyle = QComboBox(self)
        self.cmbStyle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Style:'), self.cmbStyle)
        for style_data in ((utils.tr('No style'), 'none'), (utils.tr('C'), 'c'), (utils.tr('Assembler'), 'asm')):
            self.cmbStyle.addItem(style_data[0], style_data[1])
        if column is not None:
            self.cmbStyle.setCurrentIndex(self.cmbStyle.findData(column.formatter.styleName))

        self.intBaseAddress = integeredit.IntegerEdit(self)
        self.intBaseAddress.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addRow(utils.tr('Base address:'), self.intBaseAddress)
        self.intBaseAddress.minimum = -10000000000000
        if column is not None:
            self.intBaseAddress.number = column.baseAddress

    @property
    def _formatter(self):
        formatter = formatters.IntegerFormatter()
        formatter.base = self.cmbBase.itemData(self.cmbBase.currentIndex())
        formatter.style = self.cmbStyle.itemData(self.cmbStyle.currentIndex())
        return formatter

    def createColumnModel(self, hex_widget):
        return AddressColumnModel(None, self._formatter, self.intBaseAddress.number)

    def saveToColumn(self, column):
        column.formatter = self._formatter
        column.baseAddress = self.intBaseAddress.number
        column.reset()
Beispiel #5
0
class FloatColumnConfigurationWidget(QWidget, columnproviders.AbstractColumnConfigurationWidget):
    def __init__(self, parent, hex_widget, column):
        QWidget.__init__(self, parent)
        columnproviders.AbstractColumnConfigurationWidget.__init__(self)
        self.hexWidget = hex_widget
        self.column = column

        self.cmbBinaryFormat = QComboBox(self)
        self.cmbBinaryFormat.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

        for fmt in (valuecodecs.FloatCodec.FormatFloat, valuecodecs.FloatCodec.FormatDouble):
            self.cmbBinaryFormat.addItem(valuecodecs.FloatCodec.formatName(fmt), fmt)
            if column is not None and column.valuecodec.binaryFormat == fmt:
                self.cmbBinaryFormat.setCurrentIndex(self.cmbBinaryFormat.count() - 1)

        self.spnPrecision = QSpinBox(self)
        self.spnPrecision.setMinimum(0)
        self.spnPrecision.setMaximum(12)
        if column is not None:
            self.spnPrecision.setValue(column.formatter.precision)
        else:
            self.spnPrecision.setValue(6)

        self.spnColumnsOnRow = QSpinBox(self)
        self.spnColumnsOnRow.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.spnColumnsOnRow.setMinimum(1)
        self.spnColumnsOnRow.setMaximum(32)
        if column is not None:
            self.spnColumnsOnRow.setValue(column.columnsOnRow)
        else:
            self.spnColumnsOnRow.setValue(4)

        self.setLayout(QFormLayout())
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().addRow(utils.tr('Binary format:'), self.cmbBinaryFormat)
        self.layout().addRow(utils.tr('Digits after point:'), self.spnPrecision)
        self.layout().addRow(utils.tr('Columns on row:'), self.spnColumnsOnRow)

    @property
    def _valueCodec(self):
        c = valuecodecs.FloatCodec()
        c.binaryFormat = self.cmbBinaryFormat.itemData(self.cmbBinaryFormat.currentIndex())
        return c

    @property
    def _formatter(self):
        f = formatters.FloatFormatter()
        f.precision = self.spnPrecision.value()
        return f

    def createColumnModel(self, hex_widget):
        return FloatColumnModel(hex_widget.document, self._valueCodec, self._formatter, self.spnColumnsOnRow.value())

    def saveToColumn(self, column):
        column.valuecodec = self._valueCodec
        column.formatter = self._formatter
        column.columnsOnRow = self.spnColumnsOnRow.value()
        column.reset()
Beispiel #6
0
class SelectFriendDialog(ModalDialog):
    def __init__(self, base):
        ModalDialog.__init__(self, 290, 110)
        self.base = base
        self.setWindowTitle(i18n.get('select_friend_to_send_message'))

        self.accounts_combo = QComboBox()
        accounts = self.base.core.get_registered_accounts()
        for account in accounts:
            protocol = get_protocol_from(account.id_)
            icon = QIcon(base.get_image_path('%s.png' % protocol))
            self.accounts_combo.addItem(icon, get_username_from(account.id_),
                                        account.id_)

        completer = QCompleter(self.base.load_friends_list())
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.friend = QLineEdit()
        self.friend.setCompleter(completer)
        select_button = QPushButton(i18n.get('select'))
        select_button.clicked.connect(self.__validate)

        friend_caption = "%s (@)" % i18n.get('friend')
        form = QFormLayout()
        form.addRow(friend_caption, self.friend)
        form.addRow(i18n.get('account'), self.accounts_combo)
        form.setContentsMargins(30, 10, 10, 5)
        form.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)

        button = QPushButton(i18n.get('search'))
        button_box = QHBoxLayout()
        button_box.addStretch(0)
        button_box.addWidget(select_button)
        button_box.setContentsMargins(0, 0, 15, 15)

        layout = QVBoxLayout()
        layout.addLayout(form)
        layout.addLayout(button_box)
        layout.setSpacing(5)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        #load_button = ImageButton(base, 'action-status-menu.png',
        #        i18n.get('load_friends_list'))

        self.exec_()

    def __validate(self):
        if self.get_username() != '':
            self.accept()

    def get_account(self):
        index = self.accounts_combo.currentIndex()
        return str(self.accounts_combo.itemData(index).toPyObject())

    def get_username(self):
        return str(self.friend.text())
Beispiel #7
0
class SelectFriendDialog(ModalDialog):
    def __init__(self, base):
        ModalDialog.__init__(self, 290, 110)
        self.base = base
        self.setWindowTitle(i18n.get('select_friend_to_send_message'))

        self.accounts_combo = QComboBox()
        accounts = self.base.core.get_registered_accounts()
        for account in accounts:
            protocol = get_protocol_from(account.id_)
            icon = QIcon(base.get_image_path('%s.png' % protocol))
            self.accounts_combo.addItem(icon, get_username_from(account.id_), account.id_)

        completer = QCompleter(self.base.load_friends_list())
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.friend = QLineEdit()
        self.friend.setCompleter(completer)
        select_button = QPushButton(i18n.get('select'))
        select_button.clicked.connect(self.__validate)

        friend_caption = "%s (@)" % i18n.get('friend')
        form = QFormLayout()
        form.addRow(friend_caption, self.friend)
        form.addRow(i18n.get('account'), self.accounts_combo)
        form.setContentsMargins(30, 10, 10, 5)
        form.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)

        button = QPushButton(i18n.get('search'))
        button_box = QHBoxLayout()
        button_box.addStretch(0)
        button_box.addWidget(select_button)
        button_box.setContentsMargins(0, 0, 15, 15)

        layout = QVBoxLayout()
        layout.addLayout(form)
        layout.addLayout(button_box)
        layout.setSpacing(5)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        #load_button = ImageButton(base, 'action-status-menu.png',
        #        i18n.get('load_friends_list'))

        self.exec_()

    def __validate(self):
        if self.get_username() != '':
            self.accept()


    def get_account(self):
        index = self.accounts_combo.currentIndex()
        return str(self.accounts_combo.itemData(index).toPyObject())

    def get_username(self):
        return str(self.friend.text())
Beispiel #8
0
    def _combo_changed(self, index, combo: QComboBox = None, color=None):
        family = combo.itemData(index)
        if not family:
            # we use None as no-selection value, not empty string
            family = None

        LOG.debug("RGB: user selected %s for %s" % (repr(family), color))
        # reset slider position to min and max for layer
        self._set_minmax_slider(color, family)
        self.didChangeRGBComponentSelection.emit(self.recipe, color, family)
Beispiel #9
0
class SearchDialog(QDialog):
    def __init__(self, base):
        QDialog.__init__(self)
        self.base = base
        self.setWindowTitle(i18n.get('search'))
        self.setFixedSize(270, 110)
        self.setWindowFlags(Qt.Window | Qt.WindowTitleHint
                            | Qt.WindowCloseButtonHint
                            | Qt.CustomizeWindowHint)
        self.setModal(True)

        self.accounts_combo = QComboBox()
        accounts = self.base.core.get_registered_accounts()
        for account in accounts:
            protocol = get_protocol_from(account.id_)
            icon = QIcon(base.get_image_path('%s.png' % protocol))
            self.accounts_combo.addItem(icon, get_username_from(account.id_),
                                        account.id_)

        self.criteria = QLineEdit()
        self.criteria.setToolTip(i18n.get('criteria_tooltip'))

        form = QFormLayout()
        form.addRow(i18n.get('criteria'), self.criteria)
        form.addRow(i18n.get('account'), self.accounts_combo)
        form.setContentsMargins(30, 10, 10, 5)
        form.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)

        button = QPushButton(i18n.get('search'))
        button_box = QHBoxLayout()
        button_box.addStretch(0)
        button_box.addWidget(button)
        button_box.setContentsMargins(0, 0, 15, 15)

        button.clicked.connect(self.accept)

        layout = QVBoxLayout()
        layout.addLayout(form)
        layout.addLayout(button_box)
        layout.setSpacing(5)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        self.criteria.setFocus()

        self.exec_()

    def get_criteria(self):
        return self.criteria.text()

    def get_account(self):
        index = self.accounts_combo.currentIndex()
        return self.accounts_combo.itemData(index)
Beispiel #10
0
class SearchDialog(QDialog):
    def __init__(self, base):
        QDialog.__init__(self)
        self.base = base
        self.setWindowTitle(i18n.get('search'))
        self.setFixedSize(270, 110)
        self.setWindowFlags(Qt.Window | Qt.WindowTitleHint | Qt.WindowCloseButtonHint | Qt.CustomizeWindowHint)
        self.setModal(True)

        self.accounts_combo = QComboBox()
        accounts = self.base.core.get_registered_accounts()
        for account in accounts:
            protocol = get_protocol_from(account.id_)
            icon = QIcon(base.get_image_path('%s.png' % protocol))
            self.accounts_combo.addItem(icon, get_username_from(account.id_), account.id_)

        self.criteria = QLineEdit()
        self.criteria.setToolTip(i18n.get('criteria_tooltip'))

        form = QFormLayout()
        form.addRow(i18n.get('criteria'), self.criteria)
        form.addRow(i18n.get('account'), self.accounts_combo)
        form.setContentsMargins(30, 10, 10, 5)
        form.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)

        button = QPushButton(i18n.get('search'))
        button_box = QHBoxLayout()
        button_box.addStretch(0)
        button_box.addWidget(button)
        button_box.setContentsMargins(0, 0, 15, 15)

        button.clicked.connect(self.accept)

        layout = QVBoxLayout()
        layout.addLayout(form)
        layout.addLayout(button_box)
        layout.setSpacing(5)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
        self.criteria.setFocus()

        self.exec_()

    def get_criteria(self):
        return self.criteria.text()

    def get_account(self):
        index = self.accounts_combo.currentIndex()
        return self.accounts_combo.itemData(index)
class AppLocaleSetupDialog(QDialog):
    def __init__(self, parent):

        QDialog.__init__(self, parent)

        self.prop = MaeMoneyProperties.instance()
        self.locales = {}
        self.locales[self.prop.LANGUAGE_ZH_CN] = self.prop.LOCALE_ZH_CN
        self.locales[self.prop.LANGUAGE_ZH_HK] = self.prop.LOCALE_ZH_HK
        self.locales[self.prop.LANGUAGE_EN_US] = self.prop.LOCALE_EN_US

        self.setupUi()

    def setupUi(self):
        self.setWindowModality(Qt.WindowModal)
        self.buttonBox = QDialogButtonBox(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)

        self.gridLayout = QGridLayout()
        self.setLayout(self.gridLayout)

        self.labelAppLocale = QLabel(u"語言 Language")
        self.gridLayout.addWidget(self.labelAppLocale, 0, 1, 1, 1)
        self.comboBoxAppLocale = QComboBox()
        for [lang, appLocale] in sorted(self.locales.iteritems()):
            self.comboBoxAppLocale.addItem(lang, appLocale)

        language = self.prop.getAppLanguage()
        index = self.comboBoxAppLocale.findText(language)
        self.comboBoxAppLocale.setCurrentIndex(index)
        self.gridLayout.addWidget(self.comboBoxAppLocale, 0, 2, 1, 1)

        self.gridLayout.addWidget(QLabel(self.tr("Current setting")), 1, 1, 1, 1)
        self.gridLayout.addWidget(QLabel(self.prop.getAppLanguage()), 1, 2, 1, 1)

        self.setLanguageButton = QPushButton(self.tr("Set language"))
        self.gridLayout.addWidget(self.setLanguageButton, 2, 1, 1, 2)

        self.setWindowTitle(self.tr("Language setup"))

        self.connect(self.buttonBox, SIGNAL("accepted()"), self.accept)
        self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
        self.connect(self.setLanguageButton, SIGNAL("clicked()"), self.setLanguage)

    def setLanguage(self):
        indexSelected = self.comboBoxAppLocale.currentIndex()
        locale = self.comboBoxAppLocale.itemData(indexSelected)
        self.prop.setAppLocale(locale)
        self.accept()
Beispiel #12
0
class CreateColumnDialog(utils.Dialog):
    def __init__(self, parent, hex_widget):
        utils.Dialog.__init__(self, parent, name='create_column_dialog')
        self.hexWidget = hex_widget
        self.configWidget = None

        self.setWindowTitle(utils.tr('Add column'))
        self.setLayout(QVBoxLayout())

        self.cmbColumnProvider = QComboBox(self)
        self.cmbColumnProvider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.layout().addWidget(self.cmbColumnProvider)
        for provider in availableProviders():
            if provider.creatable:
                self.cmbColumnProvider.addItem(provider.name, provider)

        self.txtColumnName = QLineEdit(self)
        forml = QFormLayout()
        forml.addRow(utils.tr('Name:'), self.txtColumnName)
        self.layout().addLayout(forml)

        self.cmbColumnProvider.currentIndexChanged[int].connect(self._onCurrentProviderChanged)

        self.layout().addStretch()

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.layout().addWidget(self.buttonBox)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        self._onCurrentProviderChanged(self.cmbColumnProvider.currentIndex())

    def _onCurrentProviderChanged(self, index):
        provider = self.cmbColumnProvider.itemData(index)
        if self.configWidget is not None:
            self.configWidget.deleteLater()
            self.configWidget = None

        if provider is not None:
            self.configWidget = provider.createConfigurationWidget(self, self.hexWidget)
            self.layout().insertWidget(2, self.configWidget)

    def createColumnModel(self):
        model = self.configWidget.createColumnModel(self.hexWidget)
        model.name = self.txtColumnName.text()
        return model
Beispiel #13
0
class Window(QWidget):

    def __init__(self, parent = None):
    
        QWidget.__init__(self, parent)
        
        self.table = QTableView()
        self.imageTable = QTableView()
        delegate = PixelDelegate(self)
        self.imageTable.setItemDelegate(delegate)
        self.imageTable.horizontalHeader().hide()
        self.imageTable.verticalHeader().hide()
        self.imageTable.setShowGrid(False)
        
        self.imageCombo = QComboBox()
        self.imageCombo.addItem("Dream", QVariant(":/Pictures/dream.png"))
        self.imageCombo.addItem("Teapot", QVariant(":/Pictures/teapot.png"))
        
        gridCheckBox = QCheckBox(self.tr("Show grid:"))
        gridCheckBox.setCheckState(Qt.Unchecked)
        
        self.connect(self.imageCombo, SIGNAL("currentIndexChanged(int)"),
                     self.setModel)
        self.connect(gridCheckBox, SIGNAL("toggled(bool)"),
                     self.imageTable, SLOT("setShowGrid(bool)"))
        
        self.imageCombo.setCurrentIndex(1)
        
        layout = QGridLayout()
        layout.addWidget(self.imageTable, 0, 0, 1, 2)
        layout.addWidget(self.table, 0, 2, 1, 2)
        layout.addWidget(gridCheckBox, 1, 0)
        layout.addWidget(self.imageCombo, 1, 1)
        self.setLayout(layout)
    
    def setModel(self, row):
    
        image = QImage(self.imageCombo.itemData(row).toString())
        model = ImageModel(image, self)
        self.table.setModel(model)
        self.imageTable.setModel(model)
        
        for row in range(model.rowCount(QModelIndex())):
            self.imageTable.resizeRowToContents(row)
        for column in range(model.columnCount(QModelIndex())):
            self.imageTable.resizeColumnToContents(column)
Beispiel #14
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    """

    def __init__(self):
        super(ActionBar, self).__init__()
        self.setObjectName("actionbar")
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(1, 1, 1, 1)

        self.combo = QComboBox()
        self.combo.setObjectName("combotab")
        self.connect(self.combo, SIGNAL("currentIndexChanged(int)"),
            self.current_changed)
        hbox.addWidget(self.combo)

        self.lbl_checks = QLabel('')
        self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_checks)

        self._pos_text = "Ln: %d, Col: %d"
        self.lbl_position = QLabel(self._pos_text % (0, 0))
        self.lbl_position.setObjectName("position")
        self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_position)

        self.btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.btn_close.setObjectName('navigation_button')
        self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.btn_close)

    def add_item(self, text, data):
        self.combo.addItem(text, data)
        self.combo.setCurrentIndex(self.combo.count() - 1)

    def current_changed(self, index):
        data = self.combo.itemData(index)
        self.emit(SIGNAL("changeCurrent(PyQt_PyObject)"), data)

    def update_line_col(self, line, col):
        self.lbl_position.setText(self._pos_text % (line, col))
Beispiel #15
0
class ComboBox(QWidget):
    def __init__(self, id, text, **kwargs):
        QWidget.__init__(self)
        self.id = id
        self.widget = QComboBox(**kwargs)
        label = QLabel(text)
        hbox = HBoxLayout()
        hbox.addWidget(label)
        hbox.addWidget(self.widget, alignment=Qt.AlignRight)
        self.setLayout(hbox)

    def parameterValues(self):
        index = self.widget.currentIndex()
        data = self.widget.itemData(index).toString()
        if not data.isEmpty():
            text = data
        else:
            text = self.widget.currentText()
        return {self.id:text}
Beispiel #16
0
class CreateGame(Page):
    def __init__(self, window):
        Page.__init__(self, window)
        self.createWidgets(window)
        self._init = False

    def enterPage(self):
        Page.enterPage(self)
        if self._init:
            return
        self._init = True

        server_types = self.client.command(u'game_types')
        server_types = set(server_types) & set((u'awale', u'1000 bornes'))

        if u'awale' in server_types:
            self.game_types.addItem(tr('Awale'), u'awale')
        if u'1000 bornes' in server_types:
            self.game_types.addItem(tr('Mille bornes'), u'1000 bornes')

    def createWidgets(self, window):
        self.widget = QWidget()
        layout = QVBoxLayout()
        self.widget.setLayout(layout)

        grid = QGridLayout()

        grid.addWidget(QLabel(tr("Label:")), 0, 0)

        self.label = QLineEdit(u"label")
        grid.addWidget(self.label, 0, 1)

        grid.addWidget(QLabel(tr("Type:")), 1, 0)

        self.game_types = QComboBox()
        grid.addWidget(self.game_types, 1, 1)
        layout.addLayout(grid)

        spacer = createVerticalSpacer()
        layout.addItem(spacer)

        button_box = QHBoxLayout()
        layout.addLayout(button_box)

        refresh = QPushButton('&Create')
        button_box.addWidget(refresh)
        window.connect(refresh, SIGNAL('clicked()'), self.create)

        leave = QPushButton('&Leave')
        button_box.addWidget(leave)
        window.connect(leave, SIGNAL('clicked()'), self.abort)

    def create(self):
        index = self.game_types.currentIndex()
        variant = self.game_types.itemData(index)
        game_type = unicode(variant.toString())

        label = unicode(self.label.text())
        game = self.client.command(u'game_create', self.client.player_id, game_type, label)
        self.window.gotoSetupGamePage(game)

    def abort(self):
        self.window.gotoGameListPage()
Beispiel #17
0
class SimulationPanel(QWidget):

    def __init__(self):
        QWidget.__init__(self)

        layout = QVBoxLayout()

        self._simulation_mode_combo = QComboBox()
        addHelpToWidget(self._simulation_mode_combo, "run/simulation_mode")

        self._simulation_mode_combo.currentIndexChanged.connect(self.toggleSimulationMode)

        simulation_mode_layout = QHBoxLayout()
        simulation_mode_layout.addSpacing(10)
        simulation_mode_layout.addWidget(QLabel("Simulation mode:"), 0, Qt.AlignVCenter)
        simulation_mode_layout.addWidget(self._simulation_mode_combo, 0, Qt.AlignVCenter)

        simulation_mode_layout.addSpacing(20)

        self.run_button = QToolButton()
        self.run_button.setIconSize(QSize(32, 32))
        self.run_button.setText("Start Simulation")
        self.run_button.setIcon(resourceIcon("ide/gear_in_play"))
        self.run_button.clicked.connect(self.runSimulation)
        self.run_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        addHelpToWidget(self.run_button, "run/start_simulation")

        simulation_mode_layout.addWidget(self.run_button)
        simulation_mode_layout.addStretch(1)

        layout.addSpacing(5)
        layout.addLayout(simulation_mode_layout)
        layout.addSpacing(10)

        self._simulation_stack = QStackedWidget()
        self._simulation_stack.setLineWidth(1)
        self._simulation_stack.setFrameStyle(QFrame.StyledPanel)

        layout.addWidget(self._simulation_stack)

        self._simulation_widgets = OrderedDict()
        """ :type: OrderedDict[BaseRunModel,SimulationConfigPanel]"""

        self.addSimulationConfigPanel(EnsembleExperimentPanel())
        self.addSimulationConfigPanel(EnsembleSmootherPanel())
        self.addSimulationConfigPanel(IteratedEnsembleSmootherPanel(advanced_option=True))
        self.addSimulationConfigPanel(MultipleDataAssimilationPanel())

        self.setLayout(layout)


    def addSimulationConfigPanel(self, panel):
        assert isinstance(panel, SimulationConfigPanel)

        panel.toggleAdvancedOptions(False)
        self._simulation_stack.addWidget(panel)

        simulation_model = panel.getSimulationModel()

        self._simulation_widgets[simulation_model] = panel

        if not panel.is_advanced_option:
            self._simulation_mode_combo.addItem(str(simulation_model), simulation_model)

        panel.simulationConfigurationChanged.connect(self.validationStatusChanged)


    def getActions(self):
        return []

    def toggleAdvancedOptions(self, show_advanced):
        current_model = self.getCurrentSimulationModel()

        self._simulation_mode_combo.clear()

        for model, panel in self._simulation_widgets.iteritems():
            if show_advanced or not panel.is_advanced_option:
                self._simulation_mode_combo.addItem(str(model), model)

        old_index = self._simulation_mode_combo.findText(str(current_model))
        self._simulation_mode_combo.setCurrentIndex(old_index if old_index > -1 else 0)

    def toggleAdvancedMode(self, show_advanced):
        for panel in self._simulation_widgets.values():
            panel.toggleAdvancedOptions(show_advanced)

        self.toggleAdvancedOptions(show_advanced)

    def getCurrentSimulationModel(self):
        data = self._simulation_mode_combo.itemData(self._simulation_mode_combo.currentIndex(), Qt.UserRole)
        return data.toPyObject()

    def getSimulationArguments(self):
        """ @rtype: dict[str,object]"""
        simulation_widget = self._simulation_widgets[self.getCurrentSimulationModel()]
        return simulation_widget.getSimulationArguments()


    def runSimulation(self):
        case_name = getCurrentCaseName()
        message = "Are you sure you want to use case '%s' for initialization of the initial ensemble when running the simulations?" % case_name
        start_simulations = QMessageBox.question(self, "Start simulations?", message, QMessageBox.Yes | QMessageBox.No )

        if start_simulations == QMessageBox.Yes:
            run_model = self.getCurrentSimulationModel()
            arguments = self.getSimulationArguments()
            dialog = RunDialog(run_model, arguments, self)
            dialog.startSimulation()
            dialog.exec_()

            ERT.emitErtChange() # simulations may have added new cases.


    def toggleSimulationMode(self):
        current_model = self.getCurrentSimulationModel()
        if current_model is not None:
            widget = self._simulation_widgets[self.getCurrentSimulationModel()]
            self._simulation_stack.setCurrentWidget(widget)
            self.validationStatusChanged()


    def validationStatusChanged(self):
        widget = self._simulation_widgets[self.getCurrentSimulationModel()]
        self.run_button.setEnabled(widget.isConfigurationValid())
Beispiel #18
0
class GraphDialog(QDialog):

    edit_patterns = 0
    edit_curves = 1

    titles = {edit_patterns: 'Pattern editor', edit_curves: 'Curve editor'}

    labels = {edit_patterns: 'Patterns', edit_curves: 'Curves'}

    def __init__(self, dockwidget, parent, params, edit_type):

        QDialog.__init__(self, parent)
        main_lay = QVBoxLayout(self)
        self.dockwidget = dockwidget
        self.params = params
        self.edit_type = edit_type

        self.x_label = ''
        self.y_label = ''

        self.setMinimumWidth(600)
        self.setMinimumHeight(400)

        self.setWindowTitle(self.titles[edit_type])  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.current = None

        self.current_saved = False

        # File
        self.lbl_file = QLabel('File:')
        self.fra_file = QFrame()
        self.fra_file.setContentsMargins(0, 0, 0, 0)
        fra_file_lay = QHBoxLayout(self.fra_file)

        if edit_type == self.edit_patterns:
            self.txt_file = QLineEdit(self.params.patterns_file)
        elif edit_type == self.edit_curves:
            self.txt_file = QLineEdit(self.params.curves_file)

        self.txt_file.setReadOnly(True)
        self.txt_file.setAlignment(QtCore.Qt.AlignLeft
                                   | QtCore.Qt.AlignVCenter)
        self.txt_file.setSizePolicy(QSizePolicy.MinimumExpanding,
                                    QSizePolicy.Minimum)
        fra_file_lay.addWidget(self.txt_file)
        self.btn_file = QPushButton('Change')  # TODO: softcode
        self.btn_file.clicked.connect(self.import_file)
        fra_file_lay.addWidget(self.btn_file)
        fra_file_lay.setContentsMargins(0, 0, 0, 0)

        self.lbl_list = QLabel(self.labels[edit_type])
        self.lst_list = QListWidget()
        self.lst_list.currentItemChanged.connect(self.list_item_changed)

        # Form
        self.fra_form = QFrame()
        fra_form1_lay = QFormLayout(self.fra_form)
        fra_form1_lay.setContentsMargins(0, 0, 0, 0)
        fra_form1_lay.addRow(self.lbl_list, self.lst_list)

        # Buttons
        self.fra_buttons = QFrame()
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        fra_buttons_lay.setContentsMargins(0, 0, 0, 0)

        if self.edit_type == self.edit_patterns:
            ele_name = 'pattern'
        elif self.edit_type == self.edit_curves:
            ele_name = 'curve'

        self.btn_new = QPushButton('New ' + ele_name)  # TODO: softcode
        self.btn_new.clicked.connect(self.new_element)
        fra_buttons_lay.addWidget(self.btn_new)

        self.btn_import = QPushButton('Import ' + ele_name +
                                      's')  # TODO: softcode
        self.btn_import.clicked.connect(self.import_file)
        fra_buttons_lay.addWidget(self.btn_import)

        self.btn_save = QPushButton('Save current ' +
                                    ele_name)  # TODO: softcode
        self.btn_save.clicked.connect(self.save)
        fra_buttons_lay.addWidget(self.btn_save)

        self.btn_del = QPushButton('Delete current ' +
                                   ele_name)  # TODO: softcode
        self.btn_del.clicked.connect(self.del_item)
        fra_buttons_lay.addWidget(self.btn_del)

        # ID
        self.lbl_id = QLabel('ID:')
        self.txt_id = QLineEdit()
        self.txt_id.setSizePolicy(QSizePolicy.Maximum,
                                  QSizePolicy.MinimumExpanding)
        self.lbl_desc = QLabel('Desc.:')
        self.txt_desc = QLineEdit()

        self.fra_id = QFrame()
        fra_id_lay = QHBoxLayout(self.fra_id)
        fra_id_lay.addWidget(self.lbl_id)
        fra_id_lay.addWidget(self.txt_id)
        fra_id_lay.addWidget(self.lbl_desc)
        fra_id_lay.addWidget(self.txt_desc)

        # Table form
        self.table = QTableWidget(self)
        self.rows_nr = 24
        self.cols_nr = 2
        self.table.setRowCount(self.rows_nr)
        self.table.setColumnCount(self.cols_nr)
        self.table.verticalHeader().setVisible(False)

        # Initialize empty table
        self.clear_table()

        self.table.itemChanged.connect(self.data_changed)

        self.fra_table = QFrame()
        fra_table_lay = QVBoxLayout(self.fra_table)
        fra_table_lay.setContentsMargins(0, 0, 0, 0)

        if edit_type == self.edit_curves:
            self.fra_pump_type = QFrame()
            fra_pump_type_lay = QFormLayout(self.fra_pump_type)

            self.lbl_pump_type = QLabel('Curve type:')  # TODO: softcode
            self.cbo_pump_type = QComboBox()

            for key, name in Curve.type_names.iteritems():
                self.cbo_pump_type.addItem(name, key)

            fra_pump_type_lay.addRow(self.lbl_pump_type, self.cbo_pump_type)

            fra_table_lay.addWidget(self.fra_pump_type)

            self.cbo_pump_type.activated.connect(self.cbo_pump_type_activated)

        fra_table_lay.addWidget(self.table)
        self.btn_add_row = QPushButton('Add row')
        self.btn_add_row.clicked.connect(self.add_row)
        fra_table_lay.addWidget(self.btn_add_row)

        # Graph canvas
        self.fra_graph = QFrame()
        self.static_canvas = StaticMplCanvas(self.fra_graph,
                                             width=5,
                                             height=4,
                                             dpi=100)
        fra_graph_lay = QVBoxLayout(self.fra_graph)
        fra_graph_lay.addWidget(self.static_canvas)

        # Top frame
        self.fra_top = QFrame()
        fra_top_lay = QVBoxLayout(self.fra_top)
        fra_top_lay.addWidget(self.fra_form)
        fra_top_lay.addWidget(self.fra_id)
        fra_top_lay.addWidget(self.fra_buttons)

        # Bottom frame
        self.fra_bottom = QFrame()
        fra_bottom_lay = QHBoxLayout(self.fra_bottom)
        fra_bottom_lay.addWidget(self.fra_table)
        fra_bottom_lay.addWidget(self.fra_graph)

        # Main
        main_lay.addWidget(self.fra_top)
        main_lay.addWidget(self.fra_bottom)

        # Get existing patterns/curves
        self.need_to_update_graph = False
        if self.edit_type == self.edit_patterns:
            for pattern_id, pattern in self.params.patterns.iteritems():
                self.lst_list.addItem(pattern.id)

        elif self.edit_type == self.edit_curves:
            for curve_id, curve in self.params.curves.iteritems():
                self.lst_list.addItem(curve.id)

        if self.lst_list.count() > 0:
            self.lst_list.setCurrentRow(0)
            self.txt_id.setEnabled(True)
            self.txt_desc.setEnabled(True)
            self.btn_save.setEnabled(True)
            self.btn_del.setEnabled(True)
            self.table.setEnabled(True)
            self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)
        else:
            self.txt_id.setEnabled(False)
            self.txt_desc.setEnabled(False)
            self.btn_save.setEnabled(False)
            self.btn_del.setEnabled(False)
            self.table.setEnabled(False)
            self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.new_dialog = None
        self.need_to_update_graph = True

    def cbo_pump_type_activated(self):
        self.update_table_headers()
        self.update_graph()

    def add_row(self):
        row_pos = self.table.rowCount()
        self.table.insertRow(row_pos)
        col = 0
        item = QTableWidgetItem(str(row_pos))

        if self.edit_type == self.edit_patterns:
            self.table.setItem(row_pos, col, item)
            item.setFlags(QtCore.Qt.ItemIsSelectable)

    def setVisible(self, bool):
        QDialog.setVisible(self, bool)

        self.update_table_headers()
        self.update_graph()

    def list_item_changed(self):

        p_index = self.lst_list.currentRow()

        flags = Qt.ItemFlags()
        flags != Qt.ItemIsEnabled

        # Clear table
        self.clear_table()

        self.need_to_update_graph = False
        if p_index >= 0:

            self.table.setRowCount(0)

            if self.edit_type == self.edit_patterns:
                self.current = self.params.patterns[
                    self.lst_list.currentItem().text()]
                for v in range(len(self.current.values)):

                    row_pos = self.table.rowCount()
                    self.table.insertRow(row_pos)

                    item = QTableWidgetItem(str(v))
                    item.setFlags(flags)
                    self.table.setItem(v, 0, item)
                    self.table.setItem(
                        v, 1, QTableWidgetItem(str(self.current.values[v])))

            elif self.edit_type == self.edit_curves:
                self.current = self.params.curves[
                    self.lst_list.currentItem().text()]
                for v in range(len(self.current.xs)):

                    row_pos = self.table.rowCount()
                    self.table.insertRow(row_pos)

                    self.table.setItem(
                        v, 0, QTableWidgetItem(str(self.current.xs[v])))
                    self.table.setItem(
                        v, 1, QTableWidgetItem(str(self.current.ys[v])))

                curve_type = self.current.type
                self.cbo_pump_type.setCurrentIndex(curve_type)

            # Update GUI
            self.txt_id.setText(self.current.id)
            self.txt_desc.setText(self.current.desc)

            self.update_table_headers()

            # Update graph
            self.need_to_update_graph = True
            self.update_graph()

        else:

            # No curves
            self.txt_id.setText('')
            self.txt_desc.setText('')

            # Update table and chart
            self.need_to_update_graph = False
            for v in range(self.table.columnCount()):
                self.table.setItem(v, 1, QTableWidgetItem(''))

            self.need_to_update_graph = True
            self.update_graph()

    def import_file(self):

        config_file = ConfigFile(Parameters.config_file_path)

        directory = None
        if self.edit_type == GraphDialog.edit_curves:
            directory = self.params.last_curves_dir
        elif self.edit_type == GraphDialog.edit_patterns:
            directory = self.params.last_patterns_dir

        if directory is None:
            directory = self.params.last_project_dir

        file_path = QFileDialog.getOpenFileName(self, 'Select file', directory,
                                                'Files (*.txt *.inp)')

        if file_path is None or file_path == '':
            return
        else:
            if self.edit_type == GraphDialog.edit_patterns:
                # Save patterns file path in configuration file
                config_file.set_patterns_file_path(file_path)
                Parameters.patterns_file = file_path
            elif self.edit_type == GraphDialog.edit_curves:
                # Save curve file path in configuration file
                config_file.set_curves_file_path(file_path)
                Parameters.curves_file = file_path

        self.read(file_path)

    def read(self, file_path):

        self.lst_list.clear()

        if self.edit_type == self.edit_patterns:
            InpFile.read_patterns(self.params, file_path)
            for pattern_id, pattern in self.params.patterns.iteritems():
                # desc = ' (' + pattern.desc + ')' if pattern.desc is not None else ''
                self.lst_list.addItem(pattern.id)
                self.params.patterns[pattern.id] = pattern

        elif self.edit_type == self.edit_curves:
            InpFile.read_curves(self.params, file_path)
            for curve_id, curve in self.params.curves.iteritems():
                # desc = ' (' + curve.desc + ')' if curve.desc is not None else ''
                self.lst_list.addItem(curve.id)
                self.params.curves[curve.id] = curve

        if self.lst_list.count() > 0:
            self.lst_list.setCurrentRow(0)

    def new_element(self):

        old_ids = []
        if self.edit_type == self.edit_patterns:
            for pattern in self.params.patterns.itervalues():
                old_ids.append(pattern.id)
        elif self.edit_type == self.edit_curves:
            for curve in self.params.curves.itervalues():
                old_ids.append(curve.id)
        self.new_dialog = NewIdDialog(self, old_ids)
        self.new_dialog.exec_()

        new_id = self.new_dialog.get_newid()
        description = self.new_dialog.get_description()
        if new_id is None or description is None:
            return

        if self.edit_type == self.edit_patterns:
            new_pattern = Pattern(new_id, description)
            self.params.patterns[new_pattern.id] = new_pattern
            self.lst_list.addItem(new_pattern.id)
        elif self.edit_type == self.edit_curves:
            curve_type = self.cbo_pump_type.itemData(
                self.cbo_pump_type.currentIndex())
            new_curve = Curve(new_id, curve_type, desc=description)
            self.params.curves[new_curve.id] = new_curve
            self.lst_list.addItem(new_curve.id)

        self.lst_list.setCurrentRow(self.lst_list.count() - 1)

        self.txt_id.setText(new_id)
        self.txt_desc.setText(description)

        # Clear table
        self.clear_table()
        self.static_canvas.axes.clear()

        self.txt_id.setEnabled(True)
        self.txt_desc.setEnabled(True)
        self.btn_save.setEnabled(True)
        self.btn_del.setEnabled(True)
        self.table.setEnabled(True)
        self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)

    def save(self):

        self.need_to_update_graph = False

        # Check for ID
        if not self.txt_id.text():
            QMessageBox.warning(
                self,
                Parameters.plug_in_name,
                u'Please specify the ID.',  # TODO: softcode
                QMessageBox.Ok)
            return

        if self.edit_type == GraphDialog.edit_patterns:
            values = []
            for row in range(self.table.rowCount()):
                item = self.table.item(row, 1)
                if item is not None and item.text() != '':
                    values.append(self.from_item_to_val(item))
                else:
                    values.append('0')

            pattern = Pattern(self.txt_id.text(), self.txt_desc.text(), values)

            old_patterns = self.params.patterns
            old_patterns[pattern.id] = pattern
            self.params.patterns = old_patterns

            self.lst_list.currentItem().setText(pattern.id)

        elif self.edit_type == GraphDialog.edit_curves:

            # Check for ID unique
            xs = []
            ys = []
            for row in range(self.table.rowCount()):
                item_x = self.table.item(row, 0)
                item_y = self.table.item(row, 1)

                if item_x.text() != '' and item_y.text() != '':
                    xs.append(self.from_item_to_val(item_x))
                    ys.append(self.from_item_to_val(item_y))

            curve_type = self.cbo_pump_type.itemData(
                self.cbo_pump_type.currentIndex())
            curve = Curve(self.txt_id.text(), curve_type, self.txt_desc.text())
            for v in range(len(xs)):
                curve.append_xy(xs[v], ys[v])

            old_curves = self.params.curves
            old_curves[curve.id] = curve
            self.params.curves = old_curves

            self.lst_list.currentItem().setText(curve.id)

            # Update GUI
            self.dockwidget.update_curves_combo()

        # self.read()
        self.need_to_update_graph = True

    def clear_table(self):

        self.need_to_update_graph = False
        for r in range(self.table.rowCount()):
            self.table.setItem(r, 0, QTableWidgetItem(None))
            self.table.setItem(r, 1, QTableWidgetItem(None))

        for row in range(self.rows_nr):
            for col in range(self.cols_nr):
                if self.edit_type == self.edit_patterns:
                    if col == 0:
                        item = QTableWidgetItem(str(row))
                        self.table.setItem(row, col, item)
                        item.setFlags(QtCore.Qt.ItemIsSelectable)
                    # elif col == 1 and row == 0:
                    #     item = QTableWidgetItem(str(1))
                    #     self.table.setItem(row, col, item)
                    #     item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)

                # elif self.edit_type == self.edit_curves:
                # if row == 0:
                # item = QTableWidgetItem(str(0))
                # self.table.setItem(row, 0, item)
                # item = QTableWidgetItem(str(1))
                # self.table.setItem(row, 1, item)
                # item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        self.need_to_update_graph = True

    def del_item(self):
        selected_row = self.lst_list.currentRow()
        name = self.lst_list.currentItem().text()
        if selected_row < 0:
            return

        self.lst_list.takeItem(selected_row)
        if self.lst_list.count() == 0:
            self.txt_id.setEnabled(False)
            self.txt_desc.setEnabled(False)
            self.btn_save.setEnabled(False)
            self.btn_del.setEnabled(False)
            self.table.setEnabled(False)
            self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)

        if self.edit_type == GraphDialog.edit_curves:
            del self.params.curves[name]
            # Update GUI
            self.dockwidget.update_curves_combo()
        elif self.edit_type == GraphDialog.edit_patterns:
            del self.params.patterns[name]
            # Update GUI
            self.dockwidget.update_patterns_combo()

    def data_changed(self):

        if self.need_to_update_graph:
            self.update_graph()

    def update_table_headers(self):
        if self.edit_type == self.edit_patterns:
            self.x_label = 'Time period'
            self.y_label = 'Multiplier'
        elif self.edit_type == self.edit_curves:
            cbo_data = self.cbo_pump_type.itemData(
                self.cbo_pump_type.currentIndex())
            if cbo_data == Curve.type_efficiency:
                self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']'
                self.y_label = 'Efficiency ' + '[' + self.params.options.units_deltaz[
                    self.params.options.units] + ']'
            if cbo_data == Curve.type_headloss:
                self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']'
                self.y_label = 'Headloss ' + '[' + self.params.options.units_deltaz[
                    self.params.options.units] + ']'
            if cbo_data == Curve.type_pump:
                self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']'
                self.y_label = 'Head ' + '[' + self.params.options.units_deltaz[
                    self.params.options.units] + ']'
            if cbo_data == Curve.type_volume:
                self.x_label = 'Height ' + '[' + self.params.options.flow_units + ']'
                self.y_label = 'Volume ' + '[' + self.params.options.units_deltaz[
                    self.params.options.units] + ']'

        self.table.setHorizontalHeaderLabels([self.x_label,
                                              self.y_label])  # TODO: softcode

    def update_graph(self):

        if not self.need_to_update_graph:
            return

        xs = []
        ys = []

        for row in range(self.table.rowCount()):
            item = self.table.item(row, 0)
            x = self.from_item_to_val(item)
            item = self.table.item(row, 1)
            y = self.from_item_to_val(item)

            if x is not None:
                xs.append(float(x))
            if y is not None:
                ys.append(float(y))

        if len(xs) == 0 or len(ys) == 0:
            self.static_canvas.clear()
            return

        xys_t = zip(xs, ys)
        xys_t.sort()

        xys = zip(*xys_t)
        xs = xys[0]
        ys = xys[1]

        if self.edit_type == self.edit_patterns:
            y_axis_label = 'Mult. avg.: ' + '{0:.2f}'.format(
                (numpy.average(ys)))
            self.static_canvas.draw_bars_graph(
                ys,
                time_period=self.params.times.pattern_timestep,
                y_axes_label=y_axis_label)

        elif self.edit_type == self.edit_curves:

            # Account for different types of curves
            cbo_data = self.cbo_pump_type.itemData(
                self.cbo_pump_type.currentIndex())

            series_length = min(len(xs), len(ys))

            # Need to account for different types of curves
            if cbo_data == Curve.type_efficiency or cbo_data == Curve.type_headloss or cbo_data == Curve.type_volume:
                self.static_canvas.draw_line_graph(xs[:series_length],
                                                   ys[:series_length],
                                                   self.x_label, self.y_label)

            elif cbo_data == Curve.type_pump:
                if series_length == 1 or series_length == 3:
                    if series_length == 1:
                        # 3 curve points
                        curve_xs = [0, xs[0], xs[0] * 2]
                        curve_ys = [ys[0] * 1.33, ys[0], 0]
                        # y = a * x^2 + b * x + c

                    elif series_length == 3:
                        # 3 curve points
                        curve_xs = [xs[0], xs[1], xs[2]]
                        curve_ys = [ys[0], ys[1], ys[2]]

                    (a, b, c) = numpy.polyfit(curve_xs, curve_ys, 2)

                    # Create a few interpolated values
                    interp_xs = []
                    interp_ys = []
                    n_vals = 30
                    for v in range(n_vals + 1):
                        x = (curve_xs[2] - curve_xs[0]) / n_vals * v
                        interp_xs.append(x)
                        y = a * x**2 + b * x + c
                        interp_ys.append(y)

                    self.static_canvas.draw_line_graph(interp_xs, interp_ys,
                                                       self.x_label,
                                                       self.y_label)

                else:
                    self.static_canvas.draw_line_graph(xs[:series_length],
                                                       ys[:series_length],
                                                       self.x_label,
                                                       self.y_label)

    def from_item_to_val(self, item):

        if item is None:
            value = None
        else:
            value = item.text()
        try:
            value = float(value)
            value = max(value, 0)

        except:
            value = None

        return value
class NumericParameterWidget(GenericParameterWidget):
    """Widget class for Numeric parameter."""
    def __init__(self, parameter, parent=None):
        """Constructor

        .. versionadded:: 2.2

        :param parameter: A NumericParameter object.
        :type parameter: NumericParameter

        """
        super(NumericParameterWidget, self).__init__(parameter, parent)

        self._input = QWidget()

        self._unit_widget = QLabel()
        self.set_unit()

        # Size policy
        self._spin_box_size_policy = QSizePolicy(QSizePolicy.Fixed,
                                                 QSizePolicy.Fixed)

        label_policy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self._unit_widget.setSizePolicy(label_policy)

        # Add unit description to description
        description = self._description_label.text()
        description += '<br><br>Available units:'
        description += '<ul>'
        for allowed_unit in self._parameter.allowed_units:
            description += '<li>'
            description += '<b>' + allowed_unit.name + '</b>: '
            description += allowed_unit.description
            description += '</li>'
        description += '</ul>'
        self._description_label.setText(description)

    def get_parameter(self):
        """Obtain boolean parameter object from the current widget state.

        :returns: A BooleanParameter from the current state of widget

        """
        self._parameter.value = self._input.value()
        if len(self._parameter.allowed_units) > 1:
            current_index = self._unit_widget.currentIndex()
            unit = self._unit_widget.itemData(current_index, Qt.UserRole)
            if hasattr(unit, 'toPyObject'):
                unit = unit.toPyObject()
            self._parameter.unit = unit
        return self._parameter

    def set_unit(self):
        """Set up label or combo box for unit."""
        if len(self._parameter.allowed_units) == 1:
            self._unit_widget = QLabel(self._parameter.unit.name)
            self._unit_widget.setToolTip(self._parameter.unit.help_text)
        elif len(self._parameter.allowed_units) > 1:
            self._unit_widget = QComboBox()
            index = -1
            current_index = -1
            for allowed_unit in self._parameter.allowed_units:
                name = allowed_unit.name
                tooltip = allowed_unit.help_text
                index += 1
                if allowed_unit.guid == self._parameter.unit.guid:
                    current_index = index
                self._unit_widget.addItem(name)
                self._unit_widget.setItemData(index, tooltip, Qt.ToolTipRole)
                self._unit_widget.setItemData(index, allowed_unit, Qt.UserRole)
            self._unit_widget.setCurrentIndex(current_index)
            self._unit_widget.setToolTip('Select your preferred unit')
            self._unit_widget.currentIndex()

    def set_value(self, value):
        """Set the value of the input

        :param value: The new value
        :type value: int, float
        """
        self._input.setValue(value)
Beispiel #20
0
class UVLightV2(COMCUPluginBase):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletUVLightV2, *args)

        self.uv_light = self.device

        self.cbe_uva = CallbackEmulator(self.uv_light.get_uva, self.cb_uva,
                                        self.increase_error_count)

        self.cbe_uvb = CallbackEmulator(self.uv_light.get_uvb, self.cb_uvb,
                                        self.increase_error_count)

        self.cbe_uvi = CallbackEmulator(self.uv_light.get_uvi, self.cb_uvi,
                                        self.increase_error_count)

        self.index_label = IndexLabel(' UVI: ? ')
        self.index_label.setText('0.0')

        self.current_uva = None
        self.current_uvb = None
        self.current_uvi = None

        plots = [('UVA', Qt.red, lambda: self.current_uva, u'{} mW/m²'.format),
                 ('UVB', Qt.darkGreen, lambda: self.current_uvb,
                  u'{} mW/m²'.format)]

        self.plot_widget = PlotWidget(u'UV [mW/m²]',
                                      plots,
                                      extra_key_widgets=[self.index_label])

        self.time_label = QLabel('Integration Time:')
        self.time_combo = QComboBox()
        self.time_combo.addItem("50 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_50MS)
        self.time_combo.addItem("100 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_100MS)
        self.time_combo.addItem("200 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_200MS)
        self.time_combo.addItem("400 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_400MS)
        self.time_combo.addItem("800 ms",
                                BrickletUVLightV2.INTEGRATION_TIME_800MS)
        self.time_combo.currentIndexChanged.connect(self.new_config)

        self.saturation_label = QLabel(
            'Sensor is saturated, choose a shorter integration time!')
        self.saturation_label.setStyleSheet('QLabel { color : red }')
        self.saturation_label.hide()

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.time_label)
        hlayout.addWidget(self.time_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.saturation_label)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

    def start(self):
        async_call(self.uv_light.get_configuration, None,
                   self.get_configucation_async, self.increase_error_count)
        async_call(self.uv_light.get_uva, None, self.cb_uva,
                   self.increase_error_count)
        self.cbe_uva.set_period(100)
        async_call(self.uv_light.get_uvb, None, self.cb_uvb,
                   self.increase_error_count)
        self.cbe_uvb.set_period(100)
        async_call(self.uv_light.get_uvi, None, self.cb_uvi,
                   self.increase_error_count)
        self.cbe_uvi.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_uva.set_period(0)
        self.cbe_uvb.set_period(0)
        self.cbe_uvi.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletUVLightV2.DEVICE_IDENTIFIER

    def get_configucation_async(self, integration_time):
        self.time_combo.setCurrentIndex(
            self.time_combo.findData(integration_time))

    def new_config(self, value):
        try:
            self.uv_light.set_configuration(
                self.time_combo.itemData(self.time_combo.currentIndex()))
        except:
            pass

    def cb_uva(self, uva):
        self.saturation_label.setVisible(uva < 0)

        if uva < 0:  # saturated
            return

        self.current_uva = uva / 10.0

    def cb_uvb(self, uvb):
        self.saturation_label.setVisible(uvb < 0)

        if uvb < 0:  # saturated
            return

        self.current_uvb = uvb / 10.0

    def cb_uvi(self, uvi):
        self.saturation_label.setVisible(uvi < 0)

        if uvi < 0:  # saturated
            return

        uvi = round(uvi / 10.0, 1)

        self.index_label.setText(unicode(uvi))

        if uvi < 2.5:
            background = 'green'
            color = 'white'
        elif uvi < 5.5:
            background = 'yellow'
            color = 'black'
        elif uvi < 7.5:
            background = 'orange'
            color = 'black'
        elif uvi < 10.5:
            background = 'red'
            color = 'white'
        else:
            background = 'magenta'
            color = 'white'

        self.index_label.setStyleSheet(
            'QLabel {{ background : {0}; color : {1} }}'.format(
                background, color))
Beispiel #21
0
class AnalogIn(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAnalogIn, *args)

        self.ai = self.device

        self.cbe_voltage = CallbackEmulator(self.ai.get_voltage,
                                            self.cb_voltage,
                                            self.increase_error_count)

        self.voltage_label = VoltageLabel('Voltage: ')

        self.current_value = None

        plot_list = [['', Qt.red, self.get_current_value]]
        self.plot_widget = PlotWidget('Voltage [mV]', plot_list)

        layout_h2 = QHBoxLayout()
        layout_h2.addStretch()
        layout_h2.addWidget(self.voltage_label)
        layout_h2.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h2)
        layout.addWidget(self.plot_widget)

        if self.firmware_version >= (2, 0, 1):
            self.combo_range = QComboBox()
            self.combo_range.addItem('Automatic',
                                     BrickletAnalogIn.RANGE_AUTOMATIC)
            if self.firmware_version >= (2, 0, 3):
                self.combo_range.addItem('0V - 3.30V',
                                         BrickletAnalogIn.RANGE_UP_TO_3V)
            self.combo_range.addItem('0V - 6.05V',
                                     BrickletAnalogIn.RANGE_UP_TO_6V)
            self.combo_range.addItem('0V - 10.32V',
                                     BrickletAnalogIn.RANGE_UP_TO_10V)
            self.combo_range.addItem('0V - 36.30V',
                                     BrickletAnalogIn.RANGE_UP_TO_36V)
            self.combo_range.addItem('0V - 45.00V',
                                     BrickletAnalogIn.RANGE_UP_TO_45V)
            self.combo_range.currentIndexChanged.connect(self.range_changed)

            layout_h1 = QHBoxLayout()
            layout_h1.addStretch()
            layout_h1.addWidget(QLabel('Range:'))
            layout_h1.addWidget(self.combo_range)

            if self.firmware_version >= (2, 0, 3):
                self.spin_average = QSpinBox()
                self.spin_average.setMinimum(0)
                self.spin_average.setMaximum(255)
                self.spin_average.setSingleStep(1)
                self.spin_average.setValue(50)
                self.spin_average.editingFinished.connect(
                    self.spin_average_finished)

                layout_h1.addStretch()
                layout_h1.addWidget(QLabel('Average Length:'))
                layout_h1.addWidget(self.spin_average)

            layout_h1.addStretch()
            layout.addLayout(layout_h1)

    def get_range_async(self, range_):
        self.combo_range.setCurrentIndex(self.combo_range.findData(range_))

    def get_averaging_async(self, average):
        self.spin_average.setValue(average)

    def start(self):
        if self.firmware_version >= (2, 0, 1):
            async_call(self.ai.get_range, None, self.get_range_async,
                       self.increase_error_count)
        if self.firmware_version >= (2, 0, 3):
            async_call(self.ai.get_averaging, None, self.get_averaging_async,
                       self.increase_error_count)
        async_call(self.ai.get_voltage, None, self.cb_voltage,
                   self.increase_error_count)
        self.cbe_voltage.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_voltage.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'analog_in'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def cb_voltage(self, voltage):
        self.current_value = voltage
        self.voltage_label.setText(str(voltage / 1000.0))

    def range_changed(self, index):
        if index >= 0 and self.firmware_version >= (2, 0, 1):
            range_ = self.combo_range.itemData(index)
            async_call(self.ai.set_range, range_, None,
                       self.increase_error_count)

    def spin_average_finished(self):
        self.ai.set_averaging(self.spin_average.value())
Beispiel #22
0
class SupportingDocumentsWidget(QWidget):
    """
    Widget for managing an entity's supporting documents. It enables listing
    of documents grouped by tabs depending on type.
    """
    def __init__(self, entity_supporting_document, supporting_doc_model_cls,
                 parent=None):
        """
        Class constructor.
        :param entity_supporting_document: Object containing information
        pertaining to document types, parent entity etc.
        :type entity_supporting_document: EntitySupportingDocument
        :param supporting_doc_model_cls: Class representing the data model
        corresponding to the entity supporting document object.
        :type supporting_doc_model_cls: object
        :param parent: Parent container widget.
        :type parent: QWidget
        """
        QWidget.__init__(self, parent)

        self._init_gui()

        self._entity_supporting_doc = entity_supporting_document

        #Container for document type widgets based on lookup id
        self._doc_type_widgets = {}

        #Init document manager
        self.source_document_manager = SourceDocumentManager(
            self._entity_supporting_doc,
            supporting_doc_model_cls,
            self
        )

        self._load_document_types()

        #Connect signals
        self._btn_add_document.clicked.connect(
            self._on_add_supporting_document
        )
        self._cbo_doc_type.currentIndexChanged.connect(
            self.on_doc_type_changed
        )
        self._doc_tab_container.currentChanged.connect(
            self.on_tab_doc_type_changed
        )

    def _init_gui(self):
        self._gl = QGridLayout(self)
        self._label = QLabel(self)
        self._label.setText(self.tr('Select document type'))
        self._gl.addWidget(self._label, 0, 0, 1, 1)
        self._cbo_doc_type = QComboBox(self)
        self._gl.addWidget(self._cbo_doc_type, 0, 1, 1, 1)
        self._btn_add_document = QPushButton(self)
        doc_ico = QIcon(':/plugins/stdm/images/icons/document.png')
        self._btn_add_document.setIcon(doc_ico)
        self._btn_add_document.setText(self.tr('Add document...'))
        self._btn_add_document.setMaximumWidth(200)
        self._gl.addWidget(self._btn_add_document, 0, 2, 1, 1)
        self._doc_tab_container = QTabWidget(self)
        self._gl.addWidget(self._doc_tab_container, 1, 0, 1, 3)

        self.setMinimumHeight(140)

    def on_doc_type_changed(self, idx):
        """
        Slot raised when the document types changes. The corresponding
        widget in the tab container is also selected.
        :param idx: Item index in the combobox.
        :type idx: int
        """
        if idx == -1:
            return

        self._doc_tab_container.setCurrentIndex(idx)

    def on_tab_doc_type_changed(self, idx):
        """
        Slot raised when the document types changes. The corresponding
        widget in the tab container is also selected.
        :param idx: Item index in the tab widget.
        :type idx: int
        """
        if idx == -1:
            return

        self._cbo_doc_type.setCurrentIndex(idx)

    def current_document_type(self):
        """
        :return: Returns the currently selected document type in the combobox.
        :rtype: str
        """
        return self._cbo_doc_type.currentText()

    def current_document_type_id(self):
        """
        :return: Returns the primary key/id of the currently selected
        document type in the combobox, else -1 if there is not current
        item in the combobox
        :rtype: int
        """
        if not self.current_document_type():
            return -1

        curr_idx = self._cbo_doc_type.currentIndex()

        return self._cbo_doc_type.itemData(curr_idx)

    def count(self):
        """
        :return: Returns the number of document types supported by this
        widget.
        :rtype: int
        """
        return self._cbo_doc_type.count()

    def document_type_containers(self):
        """
        :return: Returns a list of document container widgets for all
        registered document types.
        :rtype: list
        """
        return self.source_document_manager.containers.values()

    def document_type_widget(self, name):
        """
        Searches for the document type widget that corresponds to the given
        name.
        :param name: Name of the document type.
        :type name: str
        :return: Returns the document widget corresponding to the given type
        name.
        :rtype: QWidget
        """
        idx = self._cbo_doc_type.findText(name)

        if idx == -1:
            return None

        rec_id = self._cbo_doc_type.itemData(idx)

        return self._doc_type_widgets.get(rec_id, None)

    def _load_document_types(self):
        #Load document types in the combobox and tab widget
        vl_cls = entity_model(
            self._entity_supporting_doc.document_type_entity,
            entity_only=True
        )

        vl_obj = vl_cls()
        res = vl_obj.queryObject().all()
        for r in res:
            #Add to combo
            self._cbo_doc_type.addItem(r.value, r.id)

            #Add to tab widget
            doc_type_widget = _DocumentTypeContainer(self)
            self._doc_tab_container.addTab(doc_type_widget, r.value)
            self._doc_type_widgets[r.id] = doc_type_widget

            #Register container
            self.source_document_manager.registerContainer(
                doc_type_widget.container,
                r.id
            )

    def _on_add_supporting_document(self):
        #Slot raised when the user select to add a supporting document
        if self.count == 0:
            return

        select = self.tr('Select')
        supporting_docs_str = 'Supporting Documents'
        title = u'{0} {1} {2}'.format(
            select,
            self.current_document_type(),
            supporting_docs_str
        )

        filter_str = u'{0} (*.jpg *.jpeg *.png *.bmp *.tiff *.svg)'.format(
            supporting_docs_str
        )

        #Get last path for supporting documents
        last_path = last_document_path()
        if last_path is None:
            last_path = '/home'

        else:
            dir = QDir(last_path)
            if not dir.exists():
                last_path = '/home'

        source_docs = QFileDialog.getOpenFileNames(
            self, title, last_path, filter_str
        )

        doc_type_id = self._cbo_doc_type.itemData(self._cbo_doc_type.currentIndex())
        parent_entity = self._entity_supporting_doc.parent_entity

        for doc in source_docs:
            self.source_document_manager.insertDocumentFromFile(
                doc,
                doc_type_id,
                parent_entity
            )

        #Set last path
        if len(source_docs) > 0:
            doc = source_docs[0]
            fi = QFileInfo(doc)
            dir_path = fi.absolutePath()
            set_last_document_path(dir_path)
Beispiel #23
0
class SimulationPanel(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        layout = QVBoxLayout()

        self._simulation_mode_combo = QComboBox()
        addHelpToWidget(self._simulation_mode_combo, "run/simulation_mode")

        self._simulation_mode_combo.currentIndexChanged.connect(
            self.toggleSimulationMode)

        simulation_mode_layout = QHBoxLayout()
        simulation_mode_layout.addSpacing(10)
        simulation_mode_layout.addWidget(QLabel("Simulation mode:"), 0,
                                         Qt.AlignVCenter)
        simulation_mode_layout.addWidget(self._simulation_mode_combo, 0,
                                         Qt.AlignVCenter)

        simulation_mode_layout.addSpacing(20)

        self.run_button = QToolButton()
        self.run_button.setIconSize(QSize(32, 32))
        self.run_button.setText("Start Simulation")
        self.run_button.setIcon(resourceIcon("ide/gear_in_play"))
        self.run_button.clicked.connect(self.runSimulation)
        self.run_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        addHelpToWidget(self.run_button, "run/start_simulation")

        simulation_mode_layout.addWidget(self.run_button)
        simulation_mode_layout.addStretch(1)

        layout.addSpacing(5)
        layout.addLayout(simulation_mode_layout)
        layout.addSpacing(10)

        self._simulation_stack = QStackedWidget()
        self._simulation_stack.setLineWidth(1)
        self._simulation_stack.setFrameStyle(QFrame.StyledPanel)

        layout.addWidget(self._simulation_stack)

        self._simulation_widgets = {}
        """ :type: dict[BaseRunModel,SimulationConfigPanel]"""

        self.addSimulationConfigPanel(EnsembleExperimentPanel())
        self.addSimulationConfigPanel(EnsembleSmootherPanel())
        self.addSimulationConfigPanel(IteratedEnsembleSmootherPanel())
        self.addSimulationConfigPanel(MultipleDataAssimilationPanel())

        self.setLayout(layout)

    def addSimulationConfigPanel(self, panel):
        assert isinstance(panel, SimulationConfigPanel)

        panel.toggleAdvancedOptions(False)
        self._simulation_stack.addWidget(panel)

        simulation_model = panel.getSimulationModel()

        self._simulation_widgets[simulation_model] = panel
        self._simulation_mode_combo.addItem(str(simulation_model),
                                            simulation_model)
        panel.simulationConfigurationChanged.connect(
            self.validationStatusChanged)

    def getActions(self):
        return []

    def toggleAdvancedMode(self, show_advanced):
        for panel in self._simulation_widgets.values():
            panel.toggleAdvancedOptions(show_advanced)

    def getCurrentSimulationModel(self):
        data = self._simulation_mode_combo.itemData(
            self._simulation_mode_combo.currentIndex(), Qt.UserRole)
        return data.toPyObject()

    def getSimulationArguments(self):
        """ @rtype: dict[str,object]"""
        simulation_widget = self._simulation_widgets[
            self.getCurrentSimulationModel()]
        return simulation_widget.getSimulationArguments()

    def runSimulation(self):
        case_name = getCurrentCaseName()
        message = "Are you sure you want to use case '%s' for initialization of the initial ensemble when running the simulations?" % case_name
        start_simulations = QMessageBox.question(
            self, "Start simulations?", message,
            QMessageBox.Yes | QMessageBox.No)

        if start_simulations == QMessageBox.Yes:
            run_model = self.getCurrentSimulationModel()
            arguments = self.getSimulationArguments()
            dialog = RunDialog(run_model, arguments, self)
            dialog.startSimulation()
            dialog.exec_()

            ERT.emitErtChange()  # simulations may have added new cases.

    def toggleSimulationMode(self):
        widget = self._simulation_widgets[self.getCurrentSimulationModel()]
        self._simulation_stack.setCurrentWidget(widget)
        self.validationStatusChanged()

    def validationStatusChanged(self):
        widget = self._simulation_widgets[self.getCurrentSimulationModel()]
        self.run_button.setEnabled(widget.isConfigurationValid())
class BugReportsWidget(QWidget):
    PREFERRED_WIDTH  = 400
    PREFERRED_HEIGHT = 150
    
    def __init__(self, parent, mt):
        super(BugReportsWidget, self).__init__(parent)
        self.mt = mt
        
        layout = QVBoxLayout(self)
#         layout.setContentsMargins(0, 0, 0, 0)
        
        self.entry = QTextEdit(self)
        
        self.issues = {}
        self.issuesComboModel = IssuesComboModel()
        
        self.dropdown_reports = QComboBox(self)
        self.dropdown_reports.setModel(self.issuesComboModel)
        self.display_report()
        self.details_btn = QPushButton("Details", self)
        self.details_btn.setEnabled(False)
        self.refresh_btn = QPushButton("Refresh", self)
        create_report_btn = QPushButton("New", self)
        
        topLayout = QHBoxLayout()
        topLayout.addWidget(self.dropdown_reports, 1)
        topLayout.addWidget(self.details_btn)
        topLayout.addWidget(self.refresh_btn)
        topLayout.addSpacing(20)
        topLayout.addWidget(create_report_btn)
        layout.addLayout(topLayout)

        layout.addWidget(QLabel("Description:", self))
        
        self.entry.setLineWrapMode(QTextEdit.WidgetWidth)
        self.entry.setReadOnly(True)
        layout.addWidget(self.entry)
                
        self.dropdown_reports.currentIndexChanged.connect(self.display_report)
        self.details_btn.clicked.connect(self.displayReportDetails)
        self.refresh_btn.clicked.connect(self.update_reports)
        create_report_btn.clicked.connect(self.createBugReport)
        
        self.update_reports()

    def repoChanged(self):
        self.update_reports()

    def displayReportDetails(self):
        selectedIssue = self.selectedIssue()
        if selectedIssue == None:
            return
        url = selectedIssue.issueUrl
        if url != None:
            webbrowser.open(url, new=2)
            
    def isRepoSpecified(self):
        repoUser = self.mt.options[u"repo_user"]
        repoName = self.mt.options[u"repo_name"]
        if repoUser and repoName:
            return True
        return False

    @pyqtSlot(QThread, unicode)
    def downloadedIssues(self, thread, _):
        self.refresh_btn.setEnabled(self.isRepoSpecified())
        j = json.loads(thread.getResult())
        
        newKeys = set()
        for i, issueDict in enumerate(j):
            issue = Issue(issueDict)
            newKeys.add(issue.id)
            self.issues[issue.id] = issue
            if not self.issuesComboModel.hasKey(issue.id):
                self.issuesComboModel.externalRowInserted(issue.id, issue, i)
            else:
                self.issuesComboModel.externalRowUpdated(issue.id, issue)
        
        oldKeys = set(self.issuesComboModel.keys)
        for removedKey in oldKeys - newKeys:
            self.issuesComboModel.externalRowRemoved(removedKey)
        self.details_btn.setEnabled(self.issuesComboModel.rowCount() > 0)
        
    @pyqtSlot(QThread, unicode)
    def errorDownloadingIssues(self, _thread, _url):
        self.refresh_btn.setEnabled(self.isRepoSpecified())
        log_error("Error fetching issues from github.")

    def update_reports(self):
        self.refresh_btn.setEnabled(False)
        repoUser = self.mt.options[u"repo_user"]
        repoName = self.mt.options[u"repo_name"]
        if repoUser and repoName:
            log_debug("Fetching issues from repository %s/%s" % (repoUser, repoName))
            thread = DownloadThread(self, "https://api.github.com/repos/%s/%s/issues?state=open" % (repoUser, repoName))
            thread.finished.connect(thread.deleteLater)
            thread.error.connect(self.errorDownloadingIssues)
            thread.success.connect(self.downloadedIssues)
            thread.start()
        else:
            log_warning("No Lunchinator GitHub repository specified.")
            
    def createBugReport(self):
        repoUser = self.mt.options[u"repo_user"]
        repoName = self.mt.options[u"repo_name"]
        if repoUser and repoName:
            url = "https://github.com/%s/%s/issues/new" % (repoUser, repoName)
            if url != None:
                webbrowser.open(url, new=2)
        else:
            log_warning("No Lunchinator GitHub repository specified.")
            QMessageBox.critical(self, "No Repository", "No Lunchinator GitHub repository specified.", buttons=QMessageBox.Ok, defaultButton=QMessageBox.Ok)
        
    def selectedIssue(self):
        issueID = self.dropdown_reports.itemData(self.dropdown_reports.currentIndex(), IssuesComboModel.KEY_ROLE).toInt()[0]
        if not issueID in self.issues:
            log_error("ID of selected issue is not in issues dictionary")
            return None
        return self.issues[issueID]
        
    def display_report(self):
        if self.dropdown_reports.currentIndex()>=0:
            self.entry.setText(self.selectedIssue().description)    

    def sizeHint(self):
        return QSize(self.PREFERRED_WIDTH, self.PREFERRED_HEIGHT)
class OWImportImages(widget.OWWidget):
    name = "Import Images"
    description = "Import images from a directory(s)"
    icon = "icons/ImportImages.svg"
    priority = 110

    outputs = [("Data", Orange.data.Table)]

    #: list of recent paths
    recent_paths = settings.Setting([])  # type: List[RecentPath]
    currentPath = settings.Setting(None)

    want_main_area = False
    resizing_enabled = False

    Modality = Qt.ApplicationModal
    # Modality = Qt.WindowModal

    MaxRecentItems = 20

    def __init__(self):
        super().__init__()
        #: widget's runtime state
        self.__state = State.NoState
        self._imageMeta = []
        self._imageCategories = {}

        self.__invalidated = False
        self.__pendingTask = None

        vbox = gui.vBox(self.controlArea)
        hbox = gui.hBox(vbox)
        self.recent_cb = QComboBox(
            sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon,
            minimumContentsLength=16,
        )
        self.recent_cb.activated[int].connect(self.__onRecentActivated)
        icons = standard_icons(self)

        browseaction = QAction(
            "Open/Load Images",
            self,
            iconText="\N{HORIZONTAL ELLIPSIS}",
            icon=icons.dir_open_icon,
            toolTip="Select a directory from which to load the images")
        browseaction.triggered.connect(self.__runOpenDialog)
        reloadaction = QAction("Reload",
                               self,
                               icon=icons.reload_icon,
                               toolTip="Reload current image set")
        reloadaction.triggered.connect(self.reload)
        self.__actions = namespace(
            browse=browseaction,
            reload=reloadaction,
        )

        browsebutton = QPushButton(browseaction.iconText(),
                                   icon=browseaction.icon(),
                                   toolTip=browseaction.toolTip(),
                                   clicked=browseaction.trigger)
        reloadbutton = QPushButton(
            reloadaction.iconText(),
            icon=reloadaction.icon(),
            clicked=reloadaction.trigger,
            default=True,
        )

        hbox.layout().addWidget(self.recent_cb)
        hbox.layout().addWidget(browsebutton)
        hbox.layout().addWidget(reloadbutton)

        self.addActions([browseaction, reloadaction])

        reloadaction.changed.connect(
            lambda: reloadbutton.setEnabled(reloadaction.isEnabled()))
        box = gui.vBox(vbox, "Info")
        self.infostack = QStackedWidget()

        self.info_area = QLabel(text="No image set selected", wordWrap=True)
        self.progress_widget = QProgressBar(minimum=0, maximum=0)
        self.cancel_button = QPushButton(
            "Cancel",
            icon=icons.cancel_icon,
        )
        self.cancel_button.clicked.connect(self.cancel)

        w = QWidget()
        vlayout = QVBoxLayout()
        vlayout.setContentsMargins(0, 0, 0, 0)
        hlayout = QHBoxLayout()
        hlayout.setContentsMargins(0, 0, 0, 0)

        hlayout.addWidget(self.progress_widget)
        hlayout.addWidget(self.cancel_button)
        vlayout.addLayout(hlayout)

        self.pathlabel = TextLabel()
        self.pathlabel.setTextElideMode(Qt.ElideMiddle)
        self.pathlabel.setAttribute(Qt.WA_MacSmallSize)

        vlayout.addWidget(self.pathlabel)
        w.setLayout(vlayout)

        self.infostack.addWidget(self.info_area)
        self.infostack.addWidget(w)

        box.layout().addWidget(self.infostack)

        self.__initRecentItemsModel()
        self.__invalidated = True
        self.__executor = ThreadExecutor(self)

        QApplication.postEvent(self, QEvent(RuntimeEvent.Init))

    def __initRecentItemsModel(self):
        if self.currentPath is not None and \
                not os.path.isdir(self.currentPath):
            self.currentPath = None

        recent_paths = []
        for item in self.recent_paths:
            if os.path.isdir(item.abspath):
                recent_paths.append(item)
        recent_paths = recent_paths[:OWImportImages.MaxRecentItems]
        recent_model = self.recent_cb.model()
        for pathitem in recent_paths:
            item = RecentPath_asqstandarditem(pathitem)
            recent_model.appendRow(item)

        self.recent_paths = recent_paths

        if self.currentPath is not None and \
                os.path.isdir(self.currentPath) and self.recent_paths and \
                os.path.samefile(self.currentPath, self.recent_paths[0].abspath):
            self.recent_cb.setCurrentIndex(0)
        else:
            self.currentPath = None
            self.recent_cb.setCurrentIndex(-1)
        self.__actions.reload.setEnabled(self.currentPath is not None)

    def customEvent(self, event):
        """Reimplemented."""
        if event.type() == RuntimeEvent.Init:
            if self.__invalidated:
                try:
                    self.start()
                finally:
                    self.__invalidated = False

        super().customEvent(event)

    def __runOpenDialog(self):
        startdir = os.path.expanduser("~/")
        if self.recent_paths:
            startdir = self.recent_paths[0].abspath

        if OWImportImages.Modality == Qt.WindowModal:
            dlg = QFileDialog(
                self,
                "Select Top Level Directory",
                startdir,
                acceptMode=QFileDialog.AcceptOpen,
                modal=True,
            )
            dlg.setFileMode(QFileDialog.Directory)
            dlg.setOption(QFileDialog.ShowDirsOnly)
            dlg.setDirectory(startdir)
            dlg.setAttribute(Qt.WA_DeleteOnClose)

            @dlg.accepted.connect
            def on_accepted():
                dirpath = dlg.selectedFiles()
                if dirpath:
                    self.setCurrentPath(dirpath[0])
                    self.start()

            dlg.open()
        else:
            dirpath = QFileDialog.getExistingDirectory(
                self, "Select Top Level Directory", startdir)
            if dirpath:
                self.setCurrentPath(dirpath)
                self.start()

    def __onRecentActivated(self, index):
        item = self.recent_cb.itemData(index)
        if item is None:
            return
        assert isinstance(item, RecentPath)
        self.setCurrentPath(item.abspath)
        self.start()

    def __updateInfo(self):
        if self.__state == State.NoState:
            text = "No image set selected"
        elif self.__state == State.Processing:
            text = "Processing"
        elif self.__state == State.Done:
            nvalid = sum(imeta.isvalid for imeta in self._imageMeta)
            ncategories = len(self._imageCategories)
            if ncategories < 2:
                text = "{} images".format(nvalid)
            else:
                text = "{} images / {} categories".format(nvalid, ncategories)
        elif self.__state == State.Cancelled:
            text = "Cancelled"
        elif self.__state == State.Error:
            text = "Error state"
        else:
            assert False

        self.info_area.setText(text)

        if self.__state == State.Processing:
            self.infostack.setCurrentIndex(1)
        else:
            self.infostack.setCurrentIndex(0)

    def setCurrentPath(self, path):
        """
        Set the current root image path to path

        If the path does not exists or is not a directory the current path
        is left unchanged

        Parameters
        ----------
        path : str
            New root import path.

        Returns
        -------
        status : bool
            True if the current root import path was successfully
            changed to path.
        """
        if self.currentPath is not None and path is not None and \
                os.path.isdir(self.currentPath) and os.path.isdir(path) and \
                os.path.samefile(self.currentPath, path):
            return True

        if not os.path.exists(path):
            warnings.warn("'{}' does not exist".format(path), UserWarning)
            return False
        elif not os.path.isdir(path):
            warnings.warn("'{}' is not a directory".format(path), UserWarning)
            return False

        newindex = self.addRecentPath(path)
        self.recent_cb.setCurrentIndex(newindex)
        if newindex >= 0:
            self.currentPath = path
        else:
            self.currentPath = None
        self.__actions.reload.setEnabled(self.currentPath is not None)

        if self.__state == State.Processing:
            self.cancel()

        return True

    def addRecentPath(self, path):
        """
        Prepend a path entry to the list of recent paths

        If an entry with the same path already exists in the recent path
        list it is moved to the first place

        Parameters
        ----------
        path : str
        """
        existing = None
        for pathitem in self.recent_paths:
            if os.path.samefile(pathitem.abspath, path):
                existing = pathitem
                break

        model = self.recent_cb.model()

        if existing is not None:
            selected_index = self.recent_paths.index(existing)
            assert model.item(selected_index).data(Qt.UserRole) is existing
            self.recent_paths.remove(existing)
            row = model.takeRow(selected_index)
            self.recent_paths.insert(0, existing)
            model.insertRow(0, row)
        else:
            item = RecentPath(path, None, None)
            self.recent_paths.insert(0, item)
            model.insertRow(0, RecentPath_asqstandarditem(item))
        return 0

    def __setRuntimeState(self, state):
        assert state in State
        self.setBlocking(state == State.Processing)
        message = ""
        if state == State.Processing:
            assert self.__state in [
                State.Done, State.NoState, State.Error, State.Cancelled
            ]
            message = "Processing"
        elif state == State.Done:
            assert self.__state == State.Processing
        elif state == State.Cancelled:
            assert self.__state == State.Processing
            message = "Cancelled"
        elif state == State.Error:
            message = "Error during processing"
        elif state == State.NoState:
            message = ""
        else:
            assert False

        self.__state = state

        if self.__state == State.Processing:
            self.infostack.setCurrentIndex(1)
        else:
            self.infostack.setCurrentIndex(0)

        self.setStatusMessage(message)
        self.__updateInfo()

    def reload(self):
        """
        Restart the image scan task
        """
        if self.__state == State.Processing:
            self.cancel()

        self._imageMeta = []
        self._imageCategories = {}
        self.start()

    def start(self):
        """
        Start/execute the image indexing operation
        """
        self.error()

        self.__invalidated = False
        if self.currentPath is None:
            return

        if self.__state == State.Processing:
            assert self.__pendingTask is not None
            log.info("Starting a new task while one is in progress. "
                     "Cancel the existing task (dir:'{}')".format(
                         self.__pendingTask.startdir))
            self.cancel()

        startdir = self.currentPath

        self.__setRuntimeState(State.Processing)

        report_progress = methodinvoke(self, "__onReportProgress", (object, ))

        task = ImageScan(startdir, report_progress=report_progress)

        # collect the task state in one convenient place
        self.__pendingTask = taskstate = namespace(
            task=task,
            startdir=startdir,
            future=None,
            watcher=None,
            cancelled=False,
            cancel=None,
        )

        def cancel():
            # Cancel the task and disconnect
            if taskstate.future.cancel():
                pass
            else:
                taskstate.task.cancelled = True
                taskstate.cancelled = True
                try:
                    taskstate.future.result(timeout=3)
                except UserInterruptError:
                    pass
                except TimeoutError:
                    log.info("The task did not stop in in a timely manner")
            taskstate.watcher.finished.disconnect(self.__onRunFinished)

        taskstate.cancel = cancel

        def run_image_scan_task_interupt():
            try:
                return task.run()
            except UserInterruptError:
                # Suppress interrupt errors, so they are not logged
                return

        taskstate.future = self.__executor.submit(run_image_scan_task_interupt)
        taskstate.watcher = FutureWatcher(taskstate.future)
        taskstate.watcher.finished.connect(self.__onRunFinished)

    @Slot()
    def __onRunFinished(self):
        assert QThread.currentThread() is self.thread()
        assert self.__state == State.Processing
        assert self.__pendingTask is not None
        assert self.sender() is self.__pendingTask.watcher
        assert self.__pendingTask.future.done()
        task = self.__pendingTask
        self.__pendingTask = None

        try:
            image_meta = task.future.result()
        except Exception as err:
            sys.excepthook(*sys.exc_info())
            state = State.Error
            image_meta = []
            self.error(traceback.format_exc())
        else:
            state = State.Done
            self.error()

        categories = {}

        for imeta in image_meta:
            # derive categories from the path relative to the starting dir
            dirname = os.path.dirname(imeta.path)
            relpath = os.path.relpath(dirname, task.startdir)
            categories[dirname] = relpath

        self._imageMeta = image_meta
        self._imageCategories = categories

        self.__setRuntimeState(state)
        self.commit()

    def cancel(self):
        """
        Cancel current pending task (if any).
        """
        if self.__state == State.Processing:
            assert self.__pendingTask is not None
            self.__pendingTask.cancel()
            self.__pendingTask = None
            self.__setRuntimeState(State.Cancelled)

    @Slot(object)
    def __onReportProgress(self, arg):
        # report on scan progress from a worker thread
        # arg must be a namespace(count: int, lastpath: str)
        assert QThread.currentThread() is self.thread()
        if self.__state == State.Processing:
            self.pathlabel.setText(prettyfypath(arg.lastpath))

    def commit(self):
        """
        Create and commit a Table from the collected image meta data.
        """
        if self._imageMeta:
            categories = self._imageCategories
            if len(categories) > 1:
                cat_var = Orange.data.DiscreteVariable(
                    "category", values=list(sorted(categories.values())))
            else:
                cat_var = None
            # Image name (file basename without the extension)
            imagename_var = Orange.data.StringVariable("image name")
            # Full fs path
            image_var = Orange.data.StringVariable("image")
            image_var.attributes["type"] = "image"
            # file size/width/height
            size_var = Orange.data.ContinuousVariable("size",
                                                      number_of_decimals=0)
            width_var = Orange.data.ContinuousVariable("width",
                                                       number_of_decimals=0)
            height_var = Orange.data.ContinuousVariable("height",
                                                        number_of_decimals=0)
            domain = Orange.data.Domain(
                [], [cat_var] if cat_var is not None else [],
                [imagename_var, image_var, size_var, width_var, height_var])
            cat_data = []
            meta_data = []

            for imgmeta in self._imageMeta:
                if imgmeta.isvalid:
                    if cat_var is not None:
                        category = categories.get(os.path.dirname(
                            imgmeta.path))
                        cat_data.append([cat_var.to_val(category)])
                    else:
                        cat_data.append([])
                    basename = os.path.basename(imgmeta.path)
                    imgname, _ = os.path.splitext(basename)

                    meta_data.append([
                        imgname, imgmeta.path, imgmeta.size, imgmeta.width,
                        imgmeta.height
                    ])

            cat_data = numpy.array(cat_data, dtype=float)
            meta_data = numpy.array(meta_data, dtype=object)
            table = Orange.data.Table.from_numpy(
                domain, numpy.empty((len(cat_data), 0), dtype=float), cat_data,
                meta_data)
        else:
            table = None

        self.send("Data", table)

    def onDeleteWidget(self):
        self.cancel()
        self.__executor.shutdown(wait=True)
class OperationSelectorDialog(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self,parent)
        self.resize(280, 150)#Todo: find good values
        
        self.serachlineedit = SearchLineEdit(parent=self, function=None)
        self.setWindowTitle('Operaatiopohja haku')
        
        self.makeComboBox()
        self.makeButtons()
        self.makeLayout()
    
    def makeComboBox(self):
        self.combobox = QComboBox(parent=self)
        self.combobox.addItem('Lääkintä', SqlHandler.searchAnimal)#MedicationBase
        self.combobox.addItem('Rokotus', SqlHandler.searchAnimal)#VaccinationBase
        self.combobox.addItem('Leikkaus', SqlHandler.searchAnimal)#SurgeryBase
        self.combobox.addItem('Ultraäänitutkimus', SqlHandler.searchAnimal)#UltrasonicBase
        self.combobox.addItem('Endoskopointi', SqlHandler.searchAnimal)#EndoscopyBase
        self.combobox.addItem('Ontumatutkimus', SqlHandler.searchAnimal)#LamenessBase
        self.combobox.addItem('Röntkentutkimus', SqlHandler.searchAnimal)#XrayBase
        self.combobox.addItem('Hammastutkimus', SqlHandler.searchAnimal)#DentalexaminationBase
        self.combobox.addItem('Laboratoriotutkimus', SqlHandler.searchAnimal)#OperationBase
        self.combobox.addItem('muu', SqlHandler.searchAnimal)#OperationBase
        
        self.combobox.currentIndexChanged['int'].connect(self.changeSearchLineEditFunction)
        self.combobox.setCurrentIndex(0)
    
    def makeButtons(self):
        self.cancelButton = QPushButton(parent=self, text='Hylkää')
        self.cancelButton.clicked.connect(self.close)
        
        self.okButton = QPushButton(parent=self, text='Valitse')
        self.okButton.clicked.connect(self.okPressed)
    
    
    def makeLayout(self):
        print('makeLayout')
        buttonslayout = QHBoxLayout()
        buttonslayout.addStretch()
        buttonslayout.addWidget(self.cancelButton)
        buttonslayout.addWidget(self.okButton)

        searchLayout = QHBoxLayout()
        searchLayout.addWidget(QLabel(text='Etsi', parent=self))
        searchLayout.addWidget(self.serachlineedit)
        
        selectorlayout = QVBoxLayout()
        selectorlayout.addLayout(searchLayout)
        selectorlayout.addWidget(QLabel(text='Operaation tyyppi', parent=self))
        selectorlayout.addWidget(self.combobox)
        selectorlayout.addStretch()
        
        ownmainlayout = QVBoxLayout()
        ownmainlayout.addLayout(selectorlayout)
        ownmainlayout.addLayout(buttonslayout)
        self.setLayout(ownmainlayout)
        

    def changeSearchLineEditFunction(self, index):
        self.serachlineedit.function = self.combobox.itemData(index)
    
    def okPressed(self):
        item = self.serachlineedit.getCurrentItem()
        if item != None:
            self.parent().addAskedItem(item)
            self.close()
        else:
            box = QMessageBox()
            box.setText('Valitse operaatio')
            box.exec()
Beispiel #27
0
class EditFilterDialog(QDialog):
    def __init__(self, client, args, filters, parent=None):
        QDialog.__init__(self, parent)

        self.vbox = QVBoxLayout(self)
        self.client = client
        self.args = args
        self.filters = filters
        self.parent = parent

        self.setWindowTitle(self.tr('Add a filter'))

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setEnabled(True)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self.connect(self.buttonBox, SIGNAL("accepted()"), self.accept)
        self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)

        self.filter = QComboBox()
        self.valuebox = None
        self.vbox.addWidget(self.filter)

        for arg in self.filters:
            if not arg in arg_types or self.args.has_key(arg):
                continue
            if not isinstance(arg_types[arg].filter(self.client, arg, '', compatibility=self.parent.compatibility), QWidget):
                print 'warning, ', arg, 'isn\'t a widget'
                continue
            self.filter.addItem(arg_types[arg].label, QVariant(arg))

        index = -1
        if self.filter.count() > 0:
            index = 0
        self.filter.setCurrentIndex(index)
        self.editFilterChanged(index)

        self.connect(self.filter, SIGNAL('currentIndexChanged(int)'), self.editFilterChanged)

        self.vbox.addWidget(self.buttonBox)

    def editFilterChanged(self, index):
        if self.valuebox:
            self.vbox.removeWidget(self.valuebox)
            self.valuebox.hide()

        if index < 0:
            self.valuebox = QLineEdit()
            self.value = self.valuebox
            self.valuebox.setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        else:
            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
            arg = unicode(self.filter.itemData(index).toString())
            self.value = arg_types[arg].filter(self.client, arg, '', self.parent.compatibility)
            if arg_types[arg].unit:
                self.valuebox = QWidget(self)
                layout = QHBoxLayout(self.valuebox)
                layout.addWidget(self.value)
                layout.addWidget(QLabel(arg_types[arg].unit))
            else:
                self.valuebox = self.value

        self.connect(self, SIGNAL('finished(int)'), self.valuebox.done)
        self.vbox.insertWidget(1, self.valuebox)

    def run(self):
        if self.exec_():
            return self.value
        return None
Beispiel #28
0
class StyleChooser(QWidget):
    def __init__(self, area_supported=False):
        QWidget.__init__(self)
        self._style = PlotStyle("StyleChooser Internal Style")
        self._styles = STYLES if area_supported else STYLES_LINE_ONLY

        self.setMinimumWidth(140)
        self.setMaximumHeight(25)

        layout = QHBoxLayout()
        layout.setMargin(0)
        layout.setSpacing(2)

        self.line_chooser = QComboBox()
        self.line_chooser.setToolTip("Select line style.")
        for style in self._styles:
            self.line_chooser.addItem(*style)

        self.marker_chooser = QComboBox()
        self.marker_chooser.setToolTip("Select marker style.")
        for marker in MARKERS:
            self.marker_chooser.addItem(*marker)

        self.thickness_spinner = QDoubleSpinBox()
        self.thickness_spinner.setToolTip("Line thickness")
        self.thickness_spinner.setMinimum(0.1)
        self.thickness_spinner.setDecimals(1)
        self.thickness_spinner.setSingleStep(0.1)

        self.size_spinner = QDoubleSpinBox()
        self.size_spinner.setToolTip("Marker Size")
        self.size_spinner.setMinimum(0.1)
        self.size_spinner.setDecimals(1)
        self.size_spinner.setSingleStep(0.1)

        layout.addWidget(self.line_chooser)
        layout.addWidget(self.thickness_spinner)
        layout.addWidget(self.marker_chooser)
        layout.addWidget(self.size_spinner)

        self.setLayout(layout)

        self.line_chooser.currentIndexChanged.connect(self._updateStyle)
        self.marker_chooser.currentIndexChanged.connect(self._updateStyle)
        self.thickness_spinner.valueChanged.connect(self._updateStyle)
        self.size_spinner.valueChanged.connect(self._updateStyle)

        self._updateLineStyleAndMarker(self._style.line_style,
                                       self._style.marker, self._style.width,
                                       self._style.size)
        self._layout = layout

    def getItemSizes(self):
        line_style_combo_width = self._layout.itemAt(0).sizeHint().width()
        thickness_spinner_width = self._layout.itemAt(1).sizeHint().width()
        marker_combo_width = self._layout.itemAt(2).sizeHint().width()
        size_spinner_width = self._layout.itemAt(3).sizeHint().width()
        return line_style_combo_width, thickness_spinner_width, marker_combo_width, size_spinner_width

    def _findLineStyleIndex(self, line_style):
        for index, style in enumerate(self._styles):
            if style[1] == line_style:
                return index
            elif style[1] is None and line_style == "":
                return index
        return -1

    def _findMarkerStyleIndex(self, marker):
        for index, style in enumerate(MARKERS):
            if style[1] == marker:
                return index
            elif style[1] is None and marker == "":
                return index
        return -1

    def _updateLineStyleAndMarker(self, line_style, marker, thickness, size):
        self.line_chooser.setCurrentIndex(self._findLineStyleIndex(line_style))
        self.marker_chooser.setCurrentIndex(self._findMarkerStyleIndex(marker))
        self.thickness_spinner.setValue(thickness)
        self.size_spinner.setValue(size)

    def _updateStyle(self):
        self.marker_chooser.setEnabled(
            self.line_chooser.currentText() != "Area")

        line_style = self.line_chooser.itemData(
            self.line_chooser.currentIndex())
        marker_style = self.marker_chooser.itemData(
            self.marker_chooser.currentIndex())
        thickness = float(self.thickness_spinner.value())
        size = float(self.size_spinner.value())

        self._style.line_style = str(line_style.toString())
        self._style.marker = str(marker_style.toString())
        self._style.width = thickness
        self._style.size = size

    def setStyle(self, style):
        """ @type style: PlotStyle """
        self._style.copyStyleFrom(style)
        self._updateLineStyleAndMarker(style.line_style, style.marker,
                                       style.width, style.size)

    def getStyle(self):
        """ @rtype: PlotStyle """
        style = PlotStyle("Generated Style from StyleChooser")
        style.copyStyleFrom(self._style)
        return style

    def createLabelLayout(self, layout=None):
        if layout is None:
            layout = QHBoxLayout()

        titles = ["Line Style", "Width", "Marker Style", "Size"]
        sizes = self.getItemSizes()
        for title, size in zip(titles, sizes):
            label = QLabel(title)
            label.setFixedWidth(size)
            layout.addWidget(label)

        return layout
Beispiel #29
0
class QualityDialog(QDialog):
    def __init__(self, parent, params):

        QDialog.__init__(self, parent)

        self.parent = parent
        self.params = params

        self.setMinimumWidth(min_width)
        # self.setMinimumHeight(min_height)

        # Build dialog
        self.setWindowTitle('Options - Quality')  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.fra_form = QFrame(self)
        fra_form_lay = QFormLayout(self.fra_form)
        fra_form_lay.setContentsMargins(10, 10, 10, 10)

        self.lbl_parameter = QLabel('Parameter:')  # TODO: softocode
        self.cbo_parameter = QComboBox()
        fra_form_lay.addRow(self.lbl_parameter, self.cbo_parameter)

        self.lbl_mass_units = QLabel('Mass units:')  # TODO: softocode
        self.cbo_mass_units = QComboBox()
        fra_form_lay.addRow(self.lbl_mass_units, self.cbo_mass_units)

        self.lbl_rel_diff = QLabel('Relative diffusivity:')  # TODO: softocode
        self.txt_rel_diff = QLineEdit()
        fra_form_lay.addRow(self.lbl_rel_diff, self.txt_rel_diff)

        self.lbl_trace_node = QLabel('Trace node:')  # TODO: softocode
        self.txt_trace_node = QLineEdit()
        fra_form_lay.addRow(self.lbl_trace_node, self.txt_trace_node)

        self.lbl_quality_tol = QLabel('Quality tolerance:')  # TODO: softocode
        self.txt_quality_tol = QLineEdit()
        fra_form_lay.addRow(self.lbl_quality_tol, self.txt_quality_tol)

        # Buttons
        self.fra_buttons = QFrame(self)
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        self.btn_Ok = QPushButton('OK')
        self.btn_Cancel = QPushButton('Cancel')
        fra_buttons_lay.addWidget(self.btn_Ok)
        fra_buttons_lay.addWidget(self.btn_Cancel)

        # Add to main
        fra_main_lay = QVBoxLayout(self)
        fra_main_lay.setContentsMargins(0, 0, 0, 0)
        fra_main_lay.addWidget(self.fra_form)
        fra_main_lay.addWidget(self.fra_buttons)

        self.setup()

    def setup(self):
        for key, value in self.params.options.quality.quality_text.iteritems():
            self.cbo_parameter.addItem(value, key)

        for key, value in self.params.options.quality.quality_units_text.iteritems(
        ):
            self.cbo_mass_units.addItem(value, key)

        # Buttons
        self.btn_Cancel.clicked.connect(self.btn_cancel_clicked)
        self.btn_Ok.clicked.connect(self.btn_ok_clicked)

        # Validators
        self.txt_rel_diff.setValidator(RegExValidators.get_pos_decimals())
        self.txt_quality_tol.setValidator(RegExValidators.get_pos_decimals())

    def show(self):
        super(QualityDialog, self).show()

        self.cbo_parameter.setCurrentIndex(
            self.cbo_parameter.findData(self.params.options.quality.parameter))
        self.cbo_mass_units.setCurrentIndex(
            self.cbo_mass_units.findData(
                self.params.options.quality.mass_units))
        self.txt_rel_diff.setText(
            str(self.params.options.quality.relative_diff))
        self.txt_trace_node.setText(
            str(self.params.options.quality.trace_junction_id))
        self.txt_quality_tol.setText(
            str(self.params.options.quality.quality_tol))

    def btn_cancel_clicked(self):
        self.setVisible(False)

    def btn_ok_clicked(self):

        # Update parameters and options
        self.params.options.quality.parameter = self.cbo_parameter.itemData(
            self.cbo_parameter.currentIndex())
        self.params.options.quality.mass_units = self.cbo_mass_units.itemData(
            self.cbo_mass_units.currentIndex())

        self.params.options.quality.relative_diff = float(
            self.txt_rel_diff.text())
        self.params.options.quality.trace_junction_id = self.txt_trace_node.text(
        )
        self.params.options.quality.quality_tol = float(
            self.txt_quality_tol.text())

        self.setVisible(False)
Beispiel #30
0
class GPFModelerParameterDefinitionDialog(ModelerParameterDefinitionDialog):
    
    PARAMETER_BANDS = "Raster bands"
    
    paramTypes = ModelerParameterDefinitionDialog.paramTypes
    if PARAMETER_BANDS not in paramTypes:
        paramTypes.extend([PARAMETER_BANDS])
    
    def setupUi(self):
        if self.paramType == GPFModelerParameterDefinitionDialog.PARAMETER_BANDS or \
           isinstance(self.param, ParameterBands):
        
            self.setWindowTitle(self.tr('Parameter definition'))

            self.verticalLayout = QVBoxLayout(self)
            self.verticalLayout.setSpacing(40)
            self.verticalLayout.setMargin(20)
        
            self.horizontalLayoutName = QHBoxLayout(self)
            self.horizontalLayoutName.setSpacing(2)
            self.horizontalLayoutName.setMargin(0)
            self.label = QLabel(self.tr('Parameter name'))
            self.horizontalLayoutName.addWidget(self.label)
            self.nameTextBox = QLineEdit()
            self.horizontalLayoutName.addWidget(self.nameTextBox)
            self.verticalLayout.addLayout(self.horizontalLayoutName)
        
            self.horizontalLayoutRequired = QHBoxLayout(self)
            self.horizontalLayoutRequired.setSpacing(2)
            self.horizontalLayoutRequired.setMargin(0)
            self.horizontalLayoutParent = QHBoxLayout(self)
            self.horizontalLayoutParent.setSpacing(2)
            self.horizontalLayoutParent.setMargin(0)
            self.horizontalLayoutDefault = QHBoxLayout(self)
            self.horizontalLayoutDefault.setSpacing(2)
            self.horizontalLayoutDefault.setMargin(0)
            self.horizontalLayoutDatatype = QHBoxLayout(self)
            self.horizontalLayoutDatatype.setSpacing(2)
            self.horizontalLayoutDatatype.setMargin(0)
        
            if isinstance(self.param, Parameter):
                self.nameTextBox.setText(self.param.description)
                
            
            self.horizontalLayoutDefault.addWidget(QLabel(self.tr('Default band')))
            self.defaultTextBox = QLineEdit()
            if self.param is not None:
                self.defaultTextBox.setText(self.param.default)
            self.horizontalLayoutDefault.addWidget(self.defaultTextBox)
            self.verticalLayout.addLayout(self.horizontalLayoutDefault)
            self.horizontalLayoutDefault.addWidget(QLabel(self.tr('Raster layer')))
            self.parentCombo = QComboBox()
            idx = 0
            for param in self.alg.inputs.values():
                if isinstance(param.param, (ParameterRaster)):
                    self.parentCombo.addItem(param.param.description, param.param.name)
                    if self.param is not None:
                        if self.param.bandSourceRaster == param.param.name:
                            self.parentCombo.setCurrentIndex(idx)
                    idx += 1
            self.horizontalLayoutDefault.addWidget(self.parentCombo)
            self.verticalLayout.addLayout(self.horizontalLayoutDefault)
            
            
            self.horizontalLayoutRequired.addWidget(QLabel(self.tr('Required')))
            self.yesNoCombo = QComboBox()
            self.yesNoCombo.addItem(self.tr('Yes'))
            self.yesNoCombo.addItem(self.tr('No'))
            self.horizontalLayoutRequired.addWidget(self.yesNoCombo)
            if self.param is not None:
                self.yesNoCombo.setCurrentIndex(
                    1 if self.param.optional else 0)
            self.verticalLayout.addLayout(self.horizontalLayoutRequired)
        
            self.buttonBox = QDialogButtonBox(self)
            self.buttonBox.setOrientation(Qt.Horizontal)
            self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                              | QDialogButtonBox.Ok)
            self.buttonBox.setObjectName('buttonBox')
            self.buttonBox.accepted.connect(self.okPressed)
            self.buttonBox.rejected.connect(self.cancelPressed)
        
            self.verticalLayout.addWidget(self.buttonBox)
        
            self.setLayout(self.verticalLayout)
        
        else:
            ModelerParameterDefinitionDialog.setupUi(self)
            
    
    def okPressed(self):
        if self.paramType == GPFModelerParameterDefinitionDialog.PARAMETER_BANDS or \
           isinstance(self.param, ParameterBands):
            description = unicode(self.nameTextBox.text())
            if description.strip() == '':
                QMessageBox.warning(self, self.tr('Unable to define parameter'),
                                    self.tr('Invalid parameter name'))
                return
            if self.param is None:
                validChars = \
                    'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
                safeName = ''.join(c for c in description if c in validChars)
                name = safeName.lower()
                i = 2
                while name in self.alg.inputs:
                    name = safeName.lower() + str(i)
            else:
                name = self.param.name
                
                
            if self.parentCombo.currentIndex() < 0:
                QMessageBox.warning(self, self.tr('Unable to define parameter'),
                                    self.tr('Wrong or missing parameter values'))
                return
            
            raster = self.parentCombo.itemData(self.parentCombo.currentIndex())
            default = unicode(self.defaultTextBox.text())
            self.param = ParameterBands(name, description, default, raster, optional=False)

            self.param.optional = self.yesNoCombo.currentIndex() == 1
            self.close()
            
        else:
            ModelerParameterDefinitionDialog.okPressed(self)
Beispiel #31
0
class ReportDialog(QDialog):
    def __init__(self, parent, params):

        QDialog.__init__(self, parent)

        self.parent = parent
        self.params = params

        self.setMinimumWidth(min_width)
        # self.setMinimumHeight(min_height)

        # Build dialog
        self.setWindowTitle('Options - Report')  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.fra_form = QFrame(self)
        fra_form_lay = QFormLayout(self.fra_form)
        fra_form_lay.setContentsMargins(10, 10, 10, 10)

        self.lbl_status = QLabel('Hydraulic status:')  # TODO: softocode
        self.cbo_status = QComboBox()
        fra_form_lay.addRow(self.lbl_status, self.cbo_status)

        self.lbl_summary = QLabel('Summary')  # TODO: softocode
        self.cbo_summary = QComboBox()
        fra_form_lay.addRow(self.lbl_summary, self.cbo_summary)

        self.lbl_energy = QLabel('Energy')  # TODO: softocode
        self.cbo_energy = QComboBox()
        fra_form_lay.addRow(self.lbl_energy, self.cbo_energy)

        self.lbl_nodes = QLabel('Nodes')  # TODO: softocode
        self.cbo_nodes = QComboBox()
        fra_form_lay.addRow(self.lbl_nodes, self.cbo_nodes)

        self.lbl_links = QLabel('Links')  # TODO: softocode
        self.cbo_links = QComboBox()
        fra_form_lay.addRow(self.lbl_links, self.cbo_links)

        # Buttons
        self.fra_buttons = QFrame(self)
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        self.btn_Ok = QPushButton('OK')
        self.btn_Cancel = QPushButton('Cancel')
        fra_buttons_lay.addWidget(self.btn_Ok)
        fra_buttons_lay.addWidget(self.btn_Cancel)

        # Add to main
        fra_main_lay = QVBoxLayout(self)
        fra_main_lay.setContentsMargins(0, 0, 0, 0)
        fra_main_lay.addWidget(self.fra_form)
        fra_main_lay.addWidget(self.fra_buttons)

        self.setup()

    def setup(self):

        # Combos
        for key, value in Report.status_names.iteritems():
            self.cbo_status.addItem(value, key)

        for key, value in Report.summary_names.iteritems():
            self.cbo_summary.addItem(value, key)

        for key, value in Report.energy_names.iteritems():
            self.cbo_energy.addItem(value, key)

        for key, value in Report.nodes_names.iteritems():
            self.cbo_nodes.addItem(value, key)

        for key, value in Report.links_names.iteritems():
            self.cbo_links.addItem(value, key)

        # Buttons
        self.btn_Cancel.clicked.connect(self.btn_cancel_clicked)
        self.btn_Ok.clicked.connect(self.btn_ok_clicked)

    def show(self):
        super(ReportDialog, self).show()
        self.cbo_status.setCurrentIndex(
            self.cbo_status.findData(self.params.report.status))
        self.cbo_summary.setCurrentIndex(
            self.cbo_summary.findData(self.params.report.summary))
        self.cbo_energy.setCurrentIndex(
            self.cbo_energy.findData(self.params.report.energy))
        self.cbo_nodes.setCurrentIndex(
            self.cbo_nodes.findData(self.params.report.nodes))
        self.cbo_links.setCurrentIndex(
            self.cbo_links.findData(self.params.report.links))

    def btn_cancel_clicked(self):
        self.setVisible(False)

    def btn_ok_clicked(self):

        self.params.report.status = self.cbo_status.itemData(
            self.cbo_status.currentIndex())
        self.params.report.summary = self.cbo_summary.itemData(
            self.cbo_summary.currentIndex())
        self.params.report.energy = self.cbo_energy.itemData(
            self.cbo_energy.currentIndex())
        self.params.report.nodes = self.cbo_nodes.itemData(
            self.cbo_nodes.currentIndex())
        self.params.report.links = self.cbo_links.itemData(
            self.cbo_links.currentIndex())

        self.setVisible(False)
Beispiel #32
0
class StyleChooser(QWidget):
    styleChanged = pyqtSignal(str, str)

    STYLE_OFF = ("Off", None)
    STYLE_AREA = ("Area", "#")
    STYLE_SOLID = ("Solid", "-")
    STYLE_DASHED = ("Dashed", "--")
    STYLE_DOTTED = ("Dotted", ":")
    STYLE_DASH_DOTTED = ("Dash Dotted", "-.")

    STYLES = [STYLE_OFF, STYLE_AREA, STYLE_SOLID, STYLE_DASHED, STYLE_DOTTED, STYLE_DASH_DOTTED]
    STYLES_LINE_ONLY = [STYLE_OFF, STYLE_SOLID, STYLE_DASHED, STYLE_DOTTED, STYLE_DASH_DOTTED]

    MARKER_OFF = ("Off", None)
    MARKER_X = ("X", "x")
    MARKER_CIRCLE = ("Circle", "o")
    MARKER_POINT = ("Point", ".")
    MARKER_STAR = ("Star", "*")
    MARKER_DIAMOND = ("Diamond", "D")

    MARKERS = [MARKER_OFF, MARKER_X, MARKER_CIRCLE, MARKER_POINT, MARKER_STAR, MARKER_DIAMOND]

    """Combines a StyleChooser with a label"""
    def __init__(self, label, line_style=STYLE_OFF, marker_style=MARKER_OFF, area_supported=False, labeled=False):
        QWidget.__init__(self)

        self.__styles = StyleChooser.STYLES if area_supported else StyleChooser.STYLES_LINE_ONLY

        self.setMinimumWidth(140)
        if labeled:
            self.setMaximumHeight(45)
        else:
            self.setMaximumHeight(25)

        layout = QHBoxLayout()
        layout.setMargin(0)
        layout.setSpacing(2)

        self.line_chooser = QComboBox()
        self.line_chooser.setToolTip("Select line style.")
        for style in self.__styles:
            self.line_chooser.addItem(*style)

        self.marker_chooser = QComboBox()
        self.marker_chooser.setToolTip("Select marker style.")
        for marker in StyleChooser.MARKERS:
            self.marker_chooser.addItem(*marker)

        self.style_label = QLabel("%s:" % label)
        self.style_label.setAlignment(Qt.AlignLeft | Qt.AlignBottom)
        layout.addWidget(self.style_label)

        if labeled:
            labeled_line_chooser = self._createLabeledChooser("Line Style", self.line_chooser)
            labeled_marker_chooser = self._createLabeledChooser("Marker", self.marker_chooser)
            layout.addWidget(labeled_line_chooser)
            layout.addWidget(labeled_marker_chooser)
        else:
            layout.addWidget(self.line_chooser)
            layout.addWidget(self.marker_chooser)

        self.setLayout(layout)
        self.label = label

        self.line_chooser.currentIndexChanged.connect(self.updateStyle)
        self.marker_chooser.currentIndexChanged.connect(self.updateStyle)

        self.line_chooser.setCurrentIndex(self.__styles.index(line_style))
        self.marker_chooser.setCurrentIndex(StyleChooser.MARKERS.index(marker_style))

    def _createLabeledChooser(self, label, chooser):
        labeled_line_chooser = QWidget()
        llc_layout = QVBoxLayout()
        llc_layout.setMargin(0)
        llc_layout.addWidget(QLabel(label))
        llc_layout.addWidget(chooser)
        labeled_line_chooser.setLayout(llc_layout)
        return labeled_line_chooser

    def updateLineStyleAndMarker(self, line_style, marker):
        self.line_chooser.setCurrentIndex(self.__styles.index(line_style))
        self.marker_chooser.setCurrentIndex(StyleChooser.MARKERS.index(marker))


    def updateStyle(self):
        self.marker_chooser.setEnabled(self.line_chooser.currentText() != "Area")

        line_style = self.line_chooser.itemData(self.line_chooser.currentIndex())
        marker_style = self.marker_chooser.itemData(self.marker_chooser.currentIndex())

        line_style = str(line_style.toString())
        marker_style = str(marker_style.toString())

        self.styleChanged.emit(line_style, marker_style)
Beispiel #33
0
class EditOrAddMemberDialog(QDialog, FWidget):
    def __init__(self,
                 table_p,
                 parent,
                 scoop=None,
                 member=None,
                 *args,
                 **kwargs):
        FWidget.__init__(self, parent, *args, **kwargs)

        self.table_p = table_p
        self.member = member
        self.scoop = scoop
        self.parent = parent
        full_name = ""
        self.ddn_field = FormatDate(QDate(QDate.currentDate()))

        addres = ""
        nationality = ""
        phone = ""
        if self.member:
            self.new = False
            full_name = self.member.full_name
            mddn = self.member.ddn
            if mddn:
                day, month, year = mddn.split("/")
                ddn = datetime.strptime(mddn, '%d/%m/%Y')
                self.ddn_field.setDate(QDate(ddn))
            addres = self.member.addres
            nationality = self.member.nationality
            phone = str(self.member.phone or "")

            self.title = u"Modification de {}".format(self.member)
            self.succes_msg = u"{} a été bien mise à jour".format(self.member)
        else:
            self.new = True
            self.succes_msg = u"Client a été bien enregistré"
            self.title = u"Ajout nouveau membre"
            self.member = CooperativeMember()
        self.setWindowTitle(self.title)

        vbox = QVBoxLayout()
        # vbox.addWidget(FPageTitle(u"Utilisateur: %s " % self.member.name))

        self.full_name_field = LineEdit(full_name)
        self.sex_list = CooperativeMember.SEX.items()
        # Combobox widget
        self.sex_box = QComboBox()

        for index, value in enumerate(self.sex_list):
            # form = self.sex_list[index]
            self.sex_box.addItem("{}".format(value[1].upper()), value[0])
            if self.member.sex == value[0]:
                self.sex_box.setCurrentIndex(index)
        # print("DE", ddn)
        # self.ddn_field.setDate(ddn)
        # self.ddn_field = QDateEdit(QDate(ddn))
        self.addres_field = QTextEdit(addres)
        self.nationality_field = LineEdit(nationality)
        self.phone_field = IntLineEdit(phone)
        self.phone_field.setInputMask("## ## ## ##")
        self.poste_list = get_postes()
        self.poste_box = QComboBox()
        for index, value in enumerate(self.poste_list):
            self.poste_box.addItem(
                "{}".format(self.poste_list.get(value).upper()), value)
            if self.member.poste == value:
                print(value)
                self.poste_box.setCurrentIndex(index)

        formbox = QFormLayout()
        formbox.addRow(FormLabel(u"Nom complet : *"), self.full_name_field)
        formbox.addRow(FormLabel(u"Sexe *:"), self.sex_box)
        formbox.addRow(FormLabel(u"Date de naissance *:"), self.ddn_field)
        formbox.addRow(FormLabel(u"Poste occupé *:"), self.poste_box)
        formbox.addRow(FormLabel(u"Nationalité *:"), self.nationality_field)
        formbox.addRow(FormLabel(u"Téléphone :"), self.phone_field)
        formbox.addRow(FormLabel(u"Adresse :"), self.addres_field)

        butt = Button(u"Enregistrer")
        butt.clicked.connect(self.save_edit)
        formbox.addRow("", butt)

        vbox.addLayout(formbox)
        self.setLayout(vbox)

    def is_valide(self):
        if check_is_empty(self.full_name_field):
            return False
        if check_is_empty(self.ddn_field):
            return False
        if check_is_empty(self.nationality_field):
            return False
        if check_is_empty(self.phone_field):
            return False
        return True

    def save_edit(self):
        ''' add operation '''
        if not self.is_valide():
            return
        print("Save")
        self.member.scoop = self.scoop
        self.member.full_name = self.full_name_field.text()
        self.member.sex = self.sex_box.itemData(self.sex_box.currentIndex())
        self.member.ddn = self.ddn_field.text()
        self.member.addres = self.addres_field.toPlainText()
        self.member.nationality = self.nationality_field.text()
        phone = self.phone_field.text()
        self.member.phone = is_int(phone)
        self.member.poste = self.poste_box.itemData(
            self.poste_box.currentIndex())
        try:
            self.member.save_()
            self.close()
            self.table_p.refresh_()
            self.parent.Notify(
                u"Le membre {} ({}) a été mise à jour".format(
                    self.member.full_name, self.member.poste), "success")
        except peewee.IntegrityError:
            field_error(self.full_name_field,
                        "Ce nom existe dans la basse de donnée.")
class SelectParameterWidget(GenericParameterWidget):
    """Widget class for List parameter."""
    def __init__(self, parameter, parent=None):
        """Constructor

        :param parameter: A ListParameter object.
        :type parameter: ListParameter

        """
        super(SelectParameterWidget, self).__init__(parameter, parent)

        self.input = QComboBox()

        index = -1
        current_index = -1
        for opt in self._parameter.options_list:
            index += 1
            if opt == self._parameter.value:
                current_index = index
            self.input.addItem(opt)
            self.input.setItemData(index, opt, Qt.UserRole)

        self.input.setCurrentIndex(current_index)

        self.inner_input_layout.addWidget(self.input)

    def raise_invalid_type_exception(self):
        message = 'Expecting element type of %s' % (
            self._parameter.element_type.__name__)
        err = ValueError(message)
        return err

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A ListParameter from the current state of widget

        """
        current_index = self.input.currentIndex()
        selected_value = self.input.itemData(current_index, Qt.UserRole)
        if hasattr(selected_value, 'toPyObject'):
            selected_value = selected_value.toPyObject()

        try:
            self._parameter.value = selected_value
        except ValueError:
            err = self.raise_invalid_type_exception()
            raise err

        return self._parameter

    def set_choice(self, choice):
        """Set choice value by item's string.

        :param choice: The choice.
        :type choice: str

        :returns: True if success, else False.
        :rtype: bool
        """
        # Find index of choice
        choice_index = self._parameter.options_list.index(choice)
        if choice_index < 0:
            return False
        else:
            self.input.setCurrentIndex(choice_index)
            return True
class ChangeClassDialog(QDialog):
    pagetitle = 'Change Class'
    holdc = {}
    hold = []

    def __init__(self, session, students, parent=None):
        super(ChangeClassDialog, self).__init__(parent)

        ko = 0
        self.students = self.pullStudents(students)
        self.session = session[2]
        self.claszs = self.pullClass(1)

        self.d_displayData = QComboBox()
        for k in self.claszs:
            act = str(self.claszs[k]) + ' '
            for k in self.claszs:
                arr = self.pullClass(k)
                for dd in arr:
                    self.d_displayData.addItem(str(act + arr[dd]).upper(), dd)

        self.frame1 = QGroupBox('Students')
        self.frame2 = QGroupBox('New Class')

        hc1_box = QVBoxLayout()

        tree = QTreeWidget()
        tree.setHeaderLabel("Students?")
        self.std_arr = {}
        parent = QTreeWidgetItem(tree)
        parent.setText(0, "Selected Students")
        parent.setFlags(parent.flags() | Qt.ItemIsTristate
                        | Qt.ItemIsUserCheckable)
        for student in self.students:
            child = QTreeWidgetItem(parent)
            child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            child.setText(
                0,
                str(student['surname'] + ' ' + student['firstname'] + ' ' +
                    student['othername']).title())
            self.std_arr[student['id']] = child
            child.setCheckState(0, Qt.Checked)
            ko += 1

        hc1_box.addWidget(tree)

        self.li1 = []
        self.li1ID = []

        exp = QLabel('Select Class')
        ses_name = str(session[1]) + ' ' + str(session[3])
        ses = QLabel(ses_name)

        v_box = QHBoxLayout()
        v_box.addWidget(exp)
        v_box.addStretch()
        v_box.addWidget(self.d_displayData)

        hv_box = QVBoxLayout()
        hv_box.addWidget(ses)
        hv_box.addStretch()
        hv_box.addLayout(v_box)

        self.frame1.setLayout(hc1_box)
        #frame1.setFrameShape(QFrame.StyledPanel)
        self.frame2.setLayout(hv_box)
        #frame2.setFrameShape(QFrame.StyledPanel)

        h_box = QVBoxLayout()
        h_box.addWidget(self.frame2)
        h_box.addWidget(self.frame1)

        self.pb = QPushButton()
        self.pb.setObjectName("setclass")
        self.pb.setText("Set Class")

        self.pb1 = QPushButton()
        self.pb1.setObjectName("remclass")
        self.pb1.setText("Remove from Class")

        self.pb2 = QPushButton()
        self.pb2.setObjectName("Cancel")
        self.pb2.setText("Cancel")

        but_box = QHBoxLayout()
        but_box.addWidget(self.pb2)
        but_box.addWidget(self.pb1)
        but_box.addWidget(self.pb)

        main_box = QVBoxLayout()
        main_box.addLayout(h_box)
        main_box.addLayout(but_box)

        self.setLayout(main_box)
        self.connect(self.pb, SIGNAL("clicked()"), lambda: self.button_click())
        self.connect(self.pb1, SIGNAL("clicked()"),
                     lambda: self.button_remove())
        self.connect(self.pb2, SIGNAL("clicked()"),
                     lambda: self.button_close())
        self.setWindowTitle(self.pagetitle)

    def catItems(self, a, b):
        _a = a
        self.cas = self.pullCas(_a)
        self.li1 = []
        self.li1ID = []
        for rp in self.hold:
            self.hc2_box.removeWidget(rp)
            sip.delete(rp)

        self.hold = []
        ko = 0
        for ca in self.cas:
            num = ca['id']
            self.li1ID.append(num)
            self.c1 = QCheckBox('cbx' + str(num))
            self.c1.setText(str(ca['name']).upper())
            self.c1.setObjectName("chkx" + str(num))
            self.c1.setChecked(True)
            self.hc2_box.addWidget(self.c1)
            self.hold.append(self.c1)
            self.li1.append(self.c1)
            ko += 1

        #self.hc2_box.show()

    def pullClasz(self):
        cn = Db()
        arr = cn.selectn('datas', '', '', {'pubID': 11})
        return arr

    def pullClass(self, a):
        self.a = a
        cn = Db()
        students = cn.select('datas', '', '', {'subID': self.a, 'active': 0})
        arr = {}

        for j in students:
            arr[j[0]] = j[2]
        return arr

    def pullStudents(self, a):
        cn = Db()
        arr = cn.selectStudents(a)
        return arr

    def pullCas(self, a):
        _a = a
        cn = Db()
        arr = cn.selectn('datas', '', '', {'subID': _a})
        return arr

    def button_close(self):
        self.reject()

    def button_remove(self):
        students = self.getValues()
        session = self.session
        data = StudentTable()
        data.classRemoveStudent(session, students)
        self.accept()

    def button_click(self):
        students = self.getValue()
        moveclass = self.d_displayData.itemData(
            self.d_displayData.currentIndex())
        session = self.session
        data = StudentTable()
        data.classMoveStudent(session, moveclass, students)
        self.accept()

    def getValue(self):
        k1 = []
        for i in self.std_arr:
            if self.std_arr[i].checkState(0) == Qt.Checked:
                k1.append(i)

        return k1

    def getValues(self):

        k1 = []
        for i in self.std_arr:
            if self.std_arr[i].checkState(0) == Qt.Checked:
                k1.append(i)

        return k1

    def pullSession(self, a):
        # select a file
        self.a = a
        g = Db()
        return g.select('session', '', 1, {'id': self.a})
Beispiel #36
0
class AnalogIn(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAnalogIn, *args)

        self.ai = self.device

        self.cbe_voltage = CallbackEmulator(self.ai.get_voltage,
                                            self.cb_voltage,
                                            self.increase_error_count)

        self.current_voltage = None  # float, V

        plots = [('Voltage', Qt.red, lambda: self.current_voltage,
                  format_voltage)]
        self.plot_widget = PlotWidget('Voltage [V]', plots)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)

        if self.firmware_version >= (2, 0, 1):
            self.combo_range = QComboBox()
            self.combo_range.addItem('Automatic',
                                     BrickletAnalogIn.RANGE_AUTOMATIC)
            if self.firmware_version >= (2, 0, 3):
                self.combo_range.addItem('0 - 3.30 V',
                                         BrickletAnalogIn.RANGE_UP_TO_3V)
            self.combo_range.addItem('0 - 6.05 V',
                                     BrickletAnalogIn.RANGE_UP_TO_6V)
            self.combo_range.addItem('0 - 10.32 V',
                                     BrickletAnalogIn.RANGE_UP_TO_10V)
            self.combo_range.addItem('0 - 36.30 V',
                                     BrickletAnalogIn.RANGE_UP_TO_36V)
            self.combo_range.addItem('0 - 45.00 V',
                                     BrickletAnalogIn.RANGE_UP_TO_45V)
            self.combo_range.currentIndexChanged.connect(self.range_changed)

            hlayout = QHBoxLayout()
            hlayout.addWidget(QLabel('Range:'))
            hlayout.addWidget(self.combo_range)
            hlayout.addStretch()

            if self.firmware_version >= (2, 0, 3):
                self.spin_average = QSpinBox()
                self.spin_average.setMinimum(0)
                self.spin_average.setMaximum(255)
                self.spin_average.setSingleStep(1)
                self.spin_average.setValue(50)
                self.spin_average.editingFinished.connect(
                    self.spin_average_finished)

                hlayout.addWidget(QLabel('Average Length:'))
                hlayout.addWidget(self.spin_average)

            line = QFrame()
            line.setFrameShape(QFrame.HLine)
            line.setFrameShadow(QFrame.Sunken)

            layout.addWidget(line)
            layout.addLayout(hlayout)

    def get_range_async(self, range_):
        self.combo_range.setCurrentIndex(self.combo_range.findData(range_))

    def get_averaging_async(self, average):
        self.spin_average.setValue(average)

    def start(self):
        if self.firmware_version >= (2, 0, 1):
            async_call(self.ai.get_range, None, self.get_range_async,
                       self.increase_error_count)

            if self.firmware_version >= (2, 0, 3):
                async_call(self.ai.get_averaging, None,
                           self.get_averaging_async, self.increase_error_count)

        async_call(self.ai.get_voltage, None, self.cb_voltage,
                   self.increase_error_count)

        self.cbe_voltage.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_voltage.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER

    def cb_voltage(self, voltage):
        self.current_voltage = voltage / 1000.0

    def range_changed(self, index):
        if index >= 0 and self.firmware_version >= (2, 0, 1):
            range_ = self.combo_range.itemData(index)
            async_call(self.ai.set_range, range_, None,
                       self.increase_error_count)

    def spin_average_finished(self):
        self.ai.set_averaging(self.spin_average.value())
class ImmatriculationSCoopViewWidget(FWidget):

    def __init__(self, parent, dmd=None, *args, **kwargs):
        super(ImmatriculationSCoopViewWidget, self).__init__(
            parent=parent, *args, **kwargs)

        self.parent = parent
        self.parentWidget().set_window_title("FORMULAIRE D’IMMATRICULATION")
        self.dmd = dmd
        self.scoop = self.dmd.scoop
        self.name_declarant_field = QLineEdit()
        self.name_declarant_field.setPlaceholderText("M. / Mme")
        self.name_declarant_field.setMaximumWidth(600)

        self.procuration_field = QLineEdit()
        self.procuration_field.setPlaceholderText(
            "Réf.de la Procuration le cas échéant")
        self.procuration_field.setMaximumWidth(600)
        self.quality_box = QComboBox()
        self.quality_box.setMaximumWidth(600)
        self.quality_box.currentIndexChanged.connect(self.change_select)
        self.qualities_list = get_qualities()
        for index, value in enumerate(self.qualities_list):
            self.quality_box.addItem(
                "{}".format(self.qualities_list.get(value).upper()), value)

        self.type_box = QComboBox()
        self.type_box.setMaximumWidth(600)
        self.type_lists = Immatriculation.TYPES
        for index, value in enumerate(self.type_lists):
            print(value)
            self.type_box.addItem("{}".format(value[1], index))
        self.tel_declarant_field = IntLineEdit()
        self.tel_declarant_field.setInputMask('## ## ## ##')
        self.tel_declarant_field.setMaximumWidth(600)
        self.btn = Button_save("Sauvegarder")
        self.btn.setMaximumWidth(600)
        self.btn.clicked.connect(self.save)

        declarant_formbox = QFormLayout()
        declarant_formbox.addRow(FLabel("<strong>Type de d'immatriculation *: </strong>"), self.type_box)
        declarant_formbox.addRow(FLabel("<strong>Nom et prénom du declarant *: </strong>"), self.name_declarant_field)
        declarant_formbox.addRow(FLabel("<strong>En qualité de *: </strong>"), self.quality_box)
        declarant_formbox.addRow(FLabel("<strong>Procuration *: </strong>"), self.procuration_field)
        declarant_formbox.addRow(FLabel("<strong>Numéro tel. du declarant *: </strong>"), self.tel_declarant_field)
        declarant_formbox.addRow(FLabel(""), self.btn)
        self.declarantGroupBox = QGroupBox("Info. du déclarant de la {} *".format(self.scoop.denomination))
        self.declarantGroupBox.setStyleSheet(CSS_CENTER)
        self.declarantGroupBox.setLayout(declarant_formbox)
        vbox = QVBoxLayout()
        # vbox.addWidget(self.infoGroupBox)
        vbox.addWidget(self.declarantGroupBox)
        # vbox.addLayout(editbox)
        self.setLayout(vbox)

    def change_select(self):
        self.qlt_select = self.quality_box.itemData(
            self.quality_box.currentIndex())

        self.procuration_field.setEnabled(False)
        if self.qlt_select == Immatriculation.TP:
            self.procuration_field.setEnabled(True)
            # if check_is_empty(self.procuration_field):
            #     return False

    def is_not_valide(self):
        # print(check_is_empty(self.name_declarant_field))
        if self.quality_box.itemData(self.quality_box.currentIndex()) == Immatriculation.TP:
            if check_is_empty(self.procuration_field) or check_is_empty(self.tel_declarant_field):
                return True
        return check_is_empty(self.name_declarant_field) or check_is_empty(self.tel_declarant_field)

    def save(self):
        if self.is_not_valide():
            return False

        imma = Immatriculation()
        imma.scoop = self.scoop
        imma.typ_imm = self.type_lists[self.type_box.currentIndex()][0]
        imma.name_declarant = self.name_declarant_field.text()
        imma.quality = self.quality_box.itemData(self.quality_box.currentIndex())
        imma.procuration = self.procuration_field.text()
        imma.tel_declarant = self.tel_declarant_field.text()
        imma.save_ident()
        self.dmd.status = self.dmd.ENDPROCCES
        self.dmd.save_()
        self.parent.change_context(ResgistrationManagerWidget)
Beispiel #38
0
class Thermocouple(PluginBase):
    qtcb_error_state = pyqtSignal(bool, bool)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickletThermocouple, *args)

        self.thermo = self.device

        self.qtcb_error_state.connect(self.cb_error_state)
        self.thermo.register_callback(self.thermo.CALLBACK_ERROR_STATE,
                                      self.qtcb_error_state.emit)

        self.cbe_temperature = CallbackEmulator(self.thermo.get_temperature,
                                                self.cb_temperature,
                                                self.increase_error_count)

        self.current_temperature = None  # float, °C

        self.error_label = QLabel('Current Errors: None')
        self.error_label.setAlignment(Qt.AlignVCenter | Qt.AlignRight)

        plots = [('Temperature', Qt.red, lambda: self.current_temperature,
                  u'{:.2f} °C'.format)]
        self.plot_widget = PlotWidget(u'Temperature [°C]',
                                      plots,
                                      extra_key_widgets=[self.error_label])

        self.averaging_label = QLabel('Averaging:')
        self.averaging_combo = QComboBox()
        self.averaging_combo.addItem('1', BrickletThermocouple.AVERAGING_1)
        self.averaging_combo.addItem('2', BrickletThermocouple.AVERAGING_2)
        self.averaging_combo.addItem('4', BrickletThermocouple.AVERAGING_4)
        self.averaging_combo.addItem('8', BrickletThermocouple.AVERAGING_8)
        self.averaging_combo.addItem('16', BrickletThermocouple.AVERAGING_16)

        self.type_label = QLabel('Thermocouple Type:')
        self.type_combo = QComboBox()
        self.type_combo.addItem('B', BrickletThermocouple.TYPE_B)
        self.type_combo.addItem('E', BrickletThermocouple.TYPE_E)
        self.type_combo.addItem('J', BrickletThermocouple.TYPE_J)
        self.type_combo.addItem('K', BrickletThermocouple.TYPE_K)
        self.type_combo.addItem('N', BrickletThermocouple.TYPE_N)
        self.type_combo.addItem('R', BrickletThermocouple.TYPE_R)
        self.type_combo.addItem('S', BrickletThermocouple.TYPE_S)
        self.type_combo.addItem('T', BrickletThermocouple.TYPE_T)
        self.type_combo.addItem('Gain 8', BrickletThermocouple.TYPE_G8)
        self.type_combo.addItem('Gain 32', BrickletThermocouple.TYPE_G32)

        self.filter_label = QLabel('Noise Rejection Filter:')
        self.filter_combo = QComboBox()
        self.filter_combo.addItem('50 Hz',
                                  BrickletThermocouple.FILTER_OPTION_50HZ)
        self.filter_combo.addItem('60 Hz',
                                  BrickletThermocouple.FILTER_OPTION_60HZ)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.averaging_label)
        hlayout.addWidget(self.averaging_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.type_label)
        hlayout.addWidget(self.type_combo)
        hlayout.addStretch()
        hlayout.addWidget(self.filter_label)
        hlayout.addWidget(self.filter_combo)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addWidget(self.plot_widget)
        layout.addWidget(line)
        layout.addLayout(hlayout)

        self.averaging_combo.currentIndexChanged.connect(
            self.configuration_changed)
        self.type_combo.currentIndexChanged.connect(self.configuration_changed)
        self.filter_combo.currentIndexChanged.connect(
            self.configuration_changed)

    def start(self):
        async_call(self.thermo.get_temperature, None, self.cb_temperature,
                   self.increase_error_count)
        async_call(self.thermo.get_configuration, None, self.cb_configuration,
                   self.increase_error_count)
        async_call(self.thermo.get_error_state, None,
                   lambda e: self.cb_error_state(e.over_under, e.open_circuit))
        self.cbe_temperature.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_temperature.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletThermocouple.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def configuration_changed(self, _):
        conf_averaging = self.averaging_combo.itemData(
            self.averaging_combo.currentIndex())
        conf_type = self.type_combo.itemData(self.type_combo.currentIndex())
        conf_filter = self.filter_combo.itemData(
            self.filter_combo.currentIndex())

        self.thermo.set_configuration(conf_averaging, conf_type, conf_filter)

    def cb_temperature(self, temperature):
        self.current_temperature = temperature / 100.0

    def cb_configuration(self, conf):
        self.averaging_combo.blockSignals(True)
        self.averaging_combo.setCurrentIndex(
            self.averaging_combo.findData(conf.averaging))
        self.averaging_combo.blockSignals(False)

        self.type_combo.blockSignals(True)
        self.type_combo.setCurrentIndex(
            self.type_combo.findData(conf.thermocouple_type))
        self.type_combo.blockSignals(False)

        self.filter_combo.blockSignals(True)
        self.filter_combo.setCurrentIndex(
            self.filter_combo.findData(conf.filter))
        self.filter_combo.blockSignals(False)

    def cb_error_state(self, over_under, open_circuit):
        if over_under or open_circuit:
            text = 'Current Errors: '
            if over_under:
                text += 'Over/Under Voltage'
            if over_under and open_circuit:
                text += ' and '
            if open_circuit:
                text += 'Open Circuit\n(defective thermocouple or nothing connected)'

            self.error_label.setStyleSheet('QLabel { color : red }')
            self.error_label.setText(text)
        else:
            self.error_label.setStyleSheet('')
            self.error_label.setText('Current Errors: None')
class OWImportImages(widget.OWWidget):
    name = "Import Images"
    description = "Import images from a directory(s)"
    icon = "icons/ImportImages.svg"
    priority = 110

    outputs = [("Data", Orange.data.Table)]

    #: list of recent paths
    recent_paths = settings.Setting([])  # type: List[RecentPath]
    currentPath = settings.Setting(None)

    want_main_area = False
    resizing_enabled = False

    Modality = Qt.ApplicationModal
    # Modality = Qt.WindowModal

    MaxRecentItems = 20

    def __init__(self):
        super().__init__()
        #: widget's runtime state
        self.__state = State.NoState
        self._imageMeta = []
        self._imageCategories = {}

        self.__invalidated = False
        self.__pendingTask = None

        vbox = gui.vBox(self.controlArea)
        hbox = gui.hBox(vbox)
        self.recent_cb = QComboBox(
            sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon,
            minimumContentsLength=16,
        )
        self.recent_cb.activated[int].connect(self.__onRecentActivated)
        icons = standard_icons(self)

        browseaction = QAction(
            "Open/Load Images", self,
            iconText="\N{HORIZONTAL ELLIPSIS}",
            icon=icons.dir_open_icon,
            toolTip="Select a directory from which to load the images"
        )
        browseaction.triggered.connect(self.__runOpenDialog)
        reloadaction = QAction(
            "Reload", self,
            icon=icons.reload_icon,
            toolTip="Reload current image set"
        )
        reloadaction.triggered.connect(self.reload)
        self.__actions = namespace(
            browse=browseaction,
            reload=reloadaction,
        )

        browsebutton = QPushButton(
            browseaction.iconText(),
            icon=browseaction.icon(),
            toolTip=browseaction.toolTip(),
            clicked=browseaction.trigger
        )
        reloadbutton = QPushButton(
            reloadaction.iconText(),
            icon=reloadaction.icon(),
            clicked=reloadaction.trigger,
            default=True,
        )

        hbox.layout().addWidget(self.recent_cb)
        hbox.layout().addWidget(browsebutton)
        hbox.layout().addWidget(reloadbutton)

        self.addActions([browseaction, reloadaction])

        reloadaction.changed.connect(
            lambda: reloadbutton.setEnabled(reloadaction.isEnabled())
        )
        box = gui.vBox(vbox, "Info")
        self.infostack = QStackedWidget()

        self.info_area = QLabel(
            text="No image set selected",
            wordWrap=True
        )
        self.progress_widget = QProgressBar(
            minimum=0, maximum=0
        )
        self.cancel_button = QPushButton(
            "Cancel", icon=icons.cancel_icon,
        )
        self.cancel_button.clicked.connect(self.cancel)

        w = QWidget()
        vlayout = QVBoxLayout()
        vlayout.setContentsMargins(0, 0, 0, 0)
        hlayout = QHBoxLayout()
        hlayout.setContentsMargins(0, 0, 0, 0)

        hlayout.addWidget(self.progress_widget)
        hlayout.addWidget(self.cancel_button)
        vlayout.addLayout(hlayout)

        self.pathlabel = TextLabel()
        self.pathlabel.setTextElideMode(Qt.ElideMiddle)
        self.pathlabel.setAttribute(Qt.WA_MacSmallSize)

        vlayout.addWidget(self.pathlabel)
        w.setLayout(vlayout)

        self.infostack.addWidget(self.info_area)
        self.infostack.addWidget(w)

        box.layout().addWidget(self.infostack)

        self.__initRecentItemsModel()
        self.__invalidated = True
        self.__executor = ThreadExecutor(self)

        QApplication.postEvent(self, QEvent(RuntimeEvent.Init))

    def __initRecentItemsModel(self):
        if self.currentPath is not None and \
                not os.path.isdir(self.currentPath):
            self.currentPath = None

        recent_paths = []
        for item in self.recent_paths:
            if os.path.isdir(item.abspath):
                recent_paths.append(item)
        recent_paths = recent_paths[:OWImportImages.MaxRecentItems]
        recent_model = self.recent_cb.model()
        for pathitem in recent_paths:
            item = RecentPath_asqstandarditem(pathitem)
            recent_model.appendRow(item)

        self.recent_paths = recent_paths

        if self.currentPath is not None and \
                os.path.isdir(self.currentPath) and self.recent_paths and \
                os.path.samefile(self.currentPath, self.recent_paths[0].abspath):
            self.recent_cb.setCurrentIndex(0)
        else:
            self.currentPath = None
            self.recent_cb.setCurrentIndex(-1)
        self.__actions.reload.setEnabled(self.currentPath is not None)

    def customEvent(self, event):
        """Reimplemented."""
        if event.type() == RuntimeEvent.Init:
            if self.__invalidated:
                try:
                    self.start()
                finally:
                    self.__invalidated = False

        super().customEvent(event)

    def __runOpenDialog(self):
        startdir = os.path.expanduser("~/")
        if self.recent_paths:
            startdir = self.recent_paths[0].abspath

        if OWImportImages.Modality == Qt.WindowModal:
            dlg = QFileDialog(
                self, "Select Top Level Directory", startdir,
                acceptMode=QFileDialog.AcceptOpen,
                modal=True,
            )
            dlg.setFileMode(QFileDialog.Directory)
            dlg.setOption(QFileDialog.ShowDirsOnly)
            dlg.setDirectory(startdir)
            dlg.setAttribute(Qt.WA_DeleteOnClose)

            @dlg.accepted.connect
            def on_accepted():
                dirpath = dlg.selectedFiles()
                if dirpath:
                    self.setCurrentPath(dirpath[0])
                    self.start()
            dlg.open()
        else:
            dirpath = QFileDialog.getExistingDirectory(
                self, "Select Top Level Directory", startdir
            )
            if dirpath:
                self.setCurrentPath(dirpath)
                self.start()

    def __onRecentActivated(self, index):
        item = self.recent_cb.itemData(index)
        if item is None:
            return
        assert isinstance(item, RecentPath)
        self.setCurrentPath(item.abspath)
        self.start()

    def __updateInfo(self):
        if self.__state == State.NoState:
            text = "No image set selected"
        elif self.__state == State.Processing:
            text = "Processing"
        elif self.__state == State.Done:
            nvalid = sum(imeta.isvalid for imeta in self._imageMeta)
            ncategories = len(self._imageCategories)
            if ncategories < 2:
                text = "{} images".format(nvalid)
            else:
                text = "{} images / {} categories".format(nvalid, ncategories)
        elif self.__state == State.Cancelled:
            text = "Cancelled"
        elif self.__state == State.Error:
            text = "Error state"
        else:
            assert False

        self.info_area.setText(text)

        if self.__state == State.Processing:
            self.infostack.setCurrentIndex(1)
        else:
            self.infostack.setCurrentIndex(0)

    def setCurrentPath(self, path):
        """
        Set the current root image path to path

        If the path does not exists or is not a directory the current path
        is left unchanged

        Parameters
        ----------
        path : str
            New root import path.

        Returns
        -------
        status : bool
            True if the current root import path was successfully
            changed to path.
        """
        if self.currentPath is not None and path is not None and \
                os.path.isdir(self.currentPath) and os.path.isdir(path) and \
                os.path.samefile(self.currentPath, path):
            return True

        if not os.path.exists(path):
            warnings.warn("'{}' does not exist".format(path), UserWarning)
            return False
        elif not os.path.isdir(path):
            warnings.warn("'{}' is not a directory".format(path), UserWarning)
            return False

        newindex = self.addRecentPath(path)
        self.recent_cb.setCurrentIndex(newindex)
        if newindex >= 0:
            self.currentPath = path
        else:
            self.currentPath = None
        self.__actions.reload.setEnabled(self.currentPath is not None)

        if self.__state == State.Processing:
            self.cancel()

        return True

    def addRecentPath(self, path):
        """
        Prepend a path entry to the list of recent paths

        If an entry with the same path already exists in the recent path
        list it is moved to the first place

        Parameters
        ----------
        path : str
        """
        existing = None
        for pathitem in self.recent_paths:
            if os.path.samefile(pathitem.abspath, path):
                existing = pathitem
                break

        model = self.recent_cb.model()

        if existing is not None:
            selected_index = self.recent_paths.index(existing)
            assert model.item(selected_index).data(Qt.UserRole) is existing
            self.recent_paths.remove(existing)
            row = model.takeRow(selected_index)
            self.recent_paths.insert(0, existing)
            model.insertRow(0, row)
        else:
            item = RecentPath(path, None, None)
            self.recent_paths.insert(0, item)
            model.insertRow(0, RecentPath_asqstandarditem(item))
        return 0

    def __setRuntimeState(self, state):
        assert state in State
        self.setBlocking(state == State.Processing)
        message = ""
        if state == State.Processing:
            assert self.__state in [State.Done,
                                    State.NoState,
                                    State.Error,
                                    State.Cancelled]
            message = "Processing"
        elif state == State.Done:
            assert self.__state == State.Processing
        elif state == State.Cancelled:
            assert self.__state == State.Processing
            message = "Cancelled"
        elif state == State.Error:
            message = "Error during processing"
        elif state == State.NoState:
            message = ""
        else:
            assert False

        self.__state = state

        if self.__state == State.Processing:
            self.infostack.setCurrentIndex(1)
        else:
            self.infostack.setCurrentIndex(0)

        self.setStatusMessage(message)
        self.__updateInfo()

    def reload(self):
        """
        Restart the image scan task
        """
        if self.__state == State.Processing:
            self.cancel()

        self._imageMeta = []
        self._imageCategories = {}
        self.start()

    def start(self):
        """
        Start/execute the image indexing operation
        """
        self.error()

        self.__invalidated = False
        if self.currentPath is None:
            return

        if self.__state == State.Processing:
            assert self.__pendingTask is not None
            log.info("Starting a new task while one is in progress. "
                     "Cancel the existing task (dir:'{}')"
                     .format(self.__pendingTask.startdir))
            self.cancel()

        startdir = self.currentPath

        self.__setRuntimeState(State.Processing)

        report_progress = methodinvoke(
            self, "__onReportProgress", (object,))

        task = ImageScan(startdir, report_progress=report_progress)

        # collect the task state in one convenient place
        self.__pendingTask = taskstate = namespace(
            task=task,
            startdir=startdir,
            future=None,
            watcher=None,
            cancelled=False,
            cancel=None,
        )

        def cancel():
            # Cancel the task and disconnect
            if taskstate.future.cancel():
                pass
            else:
                taskstate.task.cancelled = True
                taskstate.cancelled = True
                try:
                    taskstate.future.result(timeout=3)
                except UserInterruptError:
                    pass
                except TimeoutError:
                    log.info("The task did not stop in in a timely manner")
            taskstate.watcher.finished.disconnect(self.__onRunFinished)

        taskstate.cancel = cancel

        def run_image_scan_task_interupt():
            try:
                return task.run()
            except UserInterruptError:
                # Suppress interrupt errors, so they are not logged
                return

        taskstate.future = self.__executor.submit(run_image_scan_task_interupt)
        taskstate.watcher = FutureWatcher(taskstate.future)
        taskstate.watcher.finished.connect(self.__onRunFinished)

    @Slot()
    def __onRunFinished(self):
        assert QThread.currentThread() is self.thread()
        assert self.__state == State.Processing
        assert self.__pendingTask is not None
        assert self.sender() is self.__pendingTask.watcher
        assert self.__pendingTask.future.done()
        task = self.__pendingTask
        self.__pendingTask = None

        try:
            image_meta = task.future.result()
        except Exception as err:
            sys.excepthook(*sys.exc_info())
            state = State.Error
            image_meta = []
            self.error(traceback.format_exc())
        else:
            state = State.Done
            self.error()

        categories = {}

        for imeta in image_meta:
            # derive categories from the path relative to the starting dir
            dirname = os.path.dirname(imeta.path)
            relpath = os.path.relpath(dirname, task.startdir)
            categories[dirname] = relpath

        self._imageMeta = image_meta
        self._imageCategories = categories

        self.__setRuntimeState(state)
        self.commit()

    def cancel(self):
        """
        Cancel current pending task (if any).
        """
        if self.__state == State.Processing:
            assert self.__pendingTask is not None
            self.__pendingTask.cancel()
            self.__pendingTask = None
            self.__setRuntimeState(State.Cancelled)

    @Slot(object)
    def __onReportProgress(self, arg):
        # report on scan progress from a worker thread
        # arg must be a namespace(count: int, lastpath: str)
        assert QThread.currentThread() is self.thread()
        if self.__state == State.Processing:
            self.pathlabel.setText(prettyfypath(arg.lastpath))

    def commit(self):
        """
        Create and commit a Table from the collected image meta data.
        """
        if self._imageMeta:
            categories = self._imageCategories
            if len(categories) > 1:
                cat_var = Orange.data.DiscreteVariable(
                    "category", values=list(sorted(categories.values()))
                )
            else:
                cat_var = None
            # Image name (file basename without the extension)
            imagename_var = Orange.data.StringVariable("image name")
            # Full fs path
            image_var = Orange.data.StringVariable("image")
            image_var.attributes["type"] = "image"
            # file size/width/height
            size_var = Orange.data.ContinuousVariable(
                "size", number_of_decimals=0)
            width_var = Orange.data.ContinuousVariable(
                "width", number_of_decimals=0)
            height_var = Orange.data.ContinuousVariable(
                "height", number_of_decimals=0)
            domain = Orange.data.Domain(
                [], [cat_var] if cat_var is not None else [],
                [imagename_var, image_var, size_var, width_var, height_var]
            )
            cat_data = []
            meta_data = []

            for imgmeta in self._imageMeta:
                if imgmeta.isvalid:
                    if cat_var is not None:
                        category = categories.get(os.path.dirname(imgmeta.path))
                        cat_data.append([cat_var.to_val(category)])
                    else:
                        cat_data.append([])
                    basename = os.path.basename(imgmeta.path)
                    imgname, _ = os.path.splitext(basename)

                    meta_data.append(
                        [imgname, imgmeta.path, imgmeta.size,
                         imgmeta.width, imgmeta.height]
                    )

            cat_data = numpy.array(cat_data, dtype=float)
            meta_data = numpy.array(meta_data, dtype=object)
            table = Orange.data.Table.from_numpy(
                domain, numpy.empty((len(cat_data), 0), dtype=float),
                cat_data, meta_data
            )
        else:
            table = None

        self.send("Data", table)

    def onDeleteWidget(self):
        self.cancel()
        self.__executor.shutdown(wait=True)
class geobricks_qgis_plugin_faostat:

    def __init__(self, iface):
        self.iface = iface
        self.layout = QVBoxLayout()
        self.cbGroups = QComboBox()
        self.cbDomains = QComboBox()
        self.cbElements = QComboBox()
        self.cbItems = QComboBox()
        self.download_folder = QLineEdit()
        try:
            if self.last_download_folder is not None:
                self.download_folder.setText(self.last_download_folder)
        except:
            self.last_download_folder = None
        self.download_folder_button = QPushButton(self.tr('...'))
        self.download_folder_button.clicked.connect(self.select_output_file)
        self.progress = QProgressBar()
        self.add_to_canvas = QCheckBox(self.tr('Add output layer to canvas'))
        self.start_download_button = QPushButton(self.tr('Start Download'))
        self.start_download_button.clicked.connect(self.download_data)
        self.progress_label = QLabel('<b>' + self.tr('Progress') + '</b>')
        self.bar = QgsMessageBar()
        self.plugin_dir = os.path.dirname(__file__)
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'geobricks_qgis_plugin_faostat_{}.qm'.format(locale))
        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)
        self.dlg = geobricks_qgis_plugin_faostatDialog()
        self.actions = []
        self.menu = self.tr('FAOSTAT Data Downloader')
        self.toolbar = self.iface.addToolBar('geobricks_qgis_plugin_faostat')
        self.toolbar.setObjectName('geobricks_qgis_plugin_faostat')
        self.initialized = False

    def run(self):

        # Build UI
        self.build_ui()

        # Populate domains
        groups = get_groups()
        for group in groups:
            self.cbGroups.addItem(group['label'], group['code'])

        # Test message bar
        self.bar.pushMessage(None, str(len(groups)) + self.tr(' groups added'), level=QgsMessageBar.INFO)

    def build_ui(self):

        # Reset layout
        self.layout = QVBoxLayout()

        # Groups
        lbl_0 = QLabel('<b>' + self.tr('Groups') + '</b>')
        self.cbGroups.addItem(self.tr('Please select a groups...'))
        self.cbGroups.activated[str].connect(self.on_groups_change)

        # Domains
        lbl_1 = QLabel('<b>' + self.tr('Domains') + '</b>')
        self.cbDomains.addItem(self.tr('Please select a group to populate this combo-box...'))
        self.cbDomains.activated[str].connect(self.on_domain_change)

        # Elements
        lbl_2 = QLabel('<b>' + self.tr('Elements') + '</b>')
        self.cbElements.addItem(self.tr('Please select a domain to populate this combo-box...'))

        # Items
        lbl_3 = QLabel('<b>' + self.tr('Items') + '</b>')
        self.cbItems.addItem(self.tr('Please select a domain to populate this combo-box...'))

        # Download Folder
        lbl_4 = QLabel('<b>' + self.tr('Download Folder') + '</b>')
        download_folder_widget = QWidget()
        download_folder_layout = QHBoxLayout()
        download_folder_widget.setLayout(download_folder_layout)
        download_folder_layout.addWidget(self.download_folder)
        download_folder_layout.addWidget(self.download_folder_button)

        # Progress bar
        self.progress.setValue(0)

        # Add to canvas
        self.add_to_canvas.toggle()

        # Message bar
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.layout.addWidget(self.bar)

        # Add widgets to layout
        self.layout.addWidget(lbl_0)
        self.layout.addWidget(self.cbGroups)
        self.layout.addWidget(lbl_1)
        self.layout.addWidget(self.cbDomains)
        self.layout.addWidget(lbl_2)
        self.layout.addWidget(self.cbElements)
        self.layout.addWidget(lbl_3)
        self.layout.addWidget(self.cbItems)
        self.layout.addWidget(lbl_4)
        self.layout.addWidget(download_folder_widget)
        self.layout.addWidget(self.add_to_canvas)
        self.layout.addWidget(self.start_download_button)
        self.layout.addWidget(self.progress_label)
        self.layout.addWidget(self.progress)

        # Set layout
        self.dlg.setLayout(self.layout)

        # Show dialog
        self.dlg.show()

    def download_data(self):

        # Get user selection
        group_code = self.cbGroups.itemData(self.cbGroups.currentIndex())
        domain_code = self.cbDomains.itemData(self.cbDomains.currentIndex())
        element_code = self.cbElements.itemData(self.cbElements.currentIndex())
        item_code = self.cbItems.itemData(self.cbItems.currentIndex())
        download_folder = self.download_folder.text()

        # Check selection
        if group_code is None:
            self.bar.pushMessage(None, self.tr('Please select a group'), level=QgsMessageBar.CRITICAL)
        elif domain_code is None:
            self.bar.pushMessage(None, self.tr('Please select a domain'), level=QgsMessageBar.CRITICAL)
        elif element_code is None:
            self.bar.pushMessage(None, self.tr('Please select an element'), level=QgsMessageBar.CRITICAL)
        elif item_code is None:
            self.bar.pushMessage(None, self.tr('Please select an item'), level=QgsMessageBar.CRITICAL)
        elif download_folder is None or len(download_folder) == 0:
            self.bar.pushMessage(None, self.tr('Please select a download folder'), level=QgsMessageBar.CRITICAL)
        else:
            # Get data
            data = get_data(domain_code, element_code, item_code)
            # Notify the user
            self.bar.pushMessage(None, self.tr('Downloaded rows: ') + str(len(data)), level=QgsMessageBar.INFO)
            # Layer name
            layer_name = self.cbItems.currentText().replace(' ', '_') + '_' + self.cbElements.currentText().replace(' ', '_')
            folder_name = os.path.join(download_folder, group_code, domain_code)
            if not os.path.exists(folder_name):
                os.makedirs(folder_name)
            # Copy template layer
            output_file = copy_layer(folder_name, layer_name)
            layer = QgsVectorLayer(output_file, 'layer_name', 'ogr')
            # Add all the years to the layer
            feature_idx = 64
            year_to_be_shown = 2014
            number_of_nulls = 0
            for year in range(2014, 1960, -1):
                progress = (1 + (feature_idx - 64)) * 1.86
                self.progress.setValue(progress)
                self.progress_label.setText('<b>' + self.tr('Progress') + ': ' + '</b> ' + self.tr('Adding Year ') + str(year))
                year_data = self.get_year_data(data, year)
                layer.dataProvider().addAttributes([QgsField(str(year), QVariant.Double)])
                if len(year_data) > 0:
                    layer.startEditing()
                    for feature in layer.getFeatures():
                        if feature['FAOSTAT'] is not None:
                            feature_code = str(feature['FAOSTAT'])
                            for d in year_data:
                                data_code = str(d['code'])
                                if data_code == feature_code:
                                    value = d['value']
                                    layer.changeAttributeValue(feature.id(), (feature_idx), float(value))
                                    tmp_feature = QgsFeature()
                                    tmp_feature.setAttributes([float(value)])
                                    layer.dataProvider().addFeatures([tmp_feature])
                                    if value is None:
                                        number_of_nulls += 1
                    layer.commitChanges()
                else:
                    year_to_be_shown -= 1
                feature_idx += 1
            # Add layer to canvas
            if self.add_to_canvas.isChecked():
                renderer = self.create_join_renderer(layer, str(year_to_be_shown), 11, QgsGraduatedSymbolRendererV2.Pretty)
                l = QgsVectorLayer(output_file, layer_name + '(' + str(year_to_be_shown) + ')', 'ogr')
                r = renderer.clone()
                r.setClassAttribute(str(year_to_be_shown))
                l.setRendererV2(r)
                QgsMapLayerRegistry.instance().addMapLayer(l)
                self.iface.legendInterface().setLayerVisible(l, True)
            # Close pop-up
            self.dlg.close()

    def create_join_renderer(self, layer, field, classes, mode, color='PuBu'):
        symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
        style = QgsStyleV2().defaultStyle()
        colorRamp = style.colorRampRef(color)
        renderer = QgsGraduatedSymbolRendererV2.createRenderer(layer, field, classes, mode, symbol, colorRamp)
        label_format = self.create_join_label_format(2)
        renderer.setLabelFormat(label_format)
        return renderer

    def create_join_label_format(self, precision):
        format = QgsRendererRangeV2LabelFormat()
        template = '%1 - %2'
        format.setFormat(template)
        format.setPrecision(precision)
        format.setTrimTrailingZeroes(True)
        return format

    def get_year_data(self, data, year):
        out = []
        for d in data:
            if d['year'] == str(year):
                out.append(d)
        return out

    def on_groups_change(self, text):

        # Get selected group code
        group_code = self.cbGroups.itemData(self.cbGroups.currentIndex())

        # Update domains list
        domains = get_domains(group_code)
        self.cbDomains.clear()
        self.cbDomains.addItem(self.tr('Please select a domain'))
        for domain in domains:
            self.cbDomains.addItem(domain['label'], domain['code'])

    def on_domain_change(self, text):

        # Get selected domain code
        domain_code = self.cbDomains.itemData(self.cbDomains.currentIndex())

        # Check domain code
        if domain_code is not None:

            # Update elements list
            try:
                elements = get_elements(domain_code)
                self.cbElements.clear()
                self.cbElements.addItem(self.tr('Please select an element'))
                for element in elements:
                    self.cbElements.addItem(element['label'], element['code'])
            except ValueError:
                self.bar.pushMessage(None, self.tr('No elements available for this domain. Please select another domain.'), level=QgsMessageBar.CRITICAL)

            # Update items list
            try:
                items = get_items(domain_code)
                self.cbItems.clear()
                self.cbItems.addItem(self.tr('Please select an item'))
                for item in items:
                    self.cbItems.addItem(item['label'], item['code'])
            except:
                self.bar.pushMessage(None, self.tr('No items available for this domain. Please select another domain.'), level=QgsMessageBar.CRITICAL)

        else:
            self.bar.pushMessage(None, self.tr('No domain selected. Please select a domain.'), level=QgsMessageBar.CRITICAL)

    def tr(self, message):
        return QCoreApplication.translate('geobricks_qgis_plugin_faostat', message)

    def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True,
                   status_tip=None, whats_this=None, parent=None):
        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        if status_tip is not None:
            action.setStatusTip(status_tip)
        if whats_this is not None:
            action.setWhatsThis(whats_this)
        if add_to_toolbar:
            self.toolbar.addAction(action)
        if add_to_menu:
            self.iface.addPluginToMenu(
                self.menu,
                action)
        self.actions.append(action)
        return action

    def initGui(self):
        icon_path = ':/plugins/geobricks_qgis_plugin_faostat/icon.png'
        self.add_action(
            icon_path,
            text=self.tr('FAOSTAT Data Downloader'),
            callback=self.run,
            parent=self.iface.mainWindow())

    def unload(self):
        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(self.tr('FAOSTAT Data Downloader')),
                action)
            self.iface.removeToolBarIcon(action)
        del self.toolbar

    def select_output_file(self):
        filename = QFileDialog.getExistingDirectory(self.dlg, self.tr('Select Folder'))
        self.last_download_folder = filename
        self.download_folder.setText(self.last_download_folder)
Beispiel #41
0
class ReferencedTableEditor(QWidget):
    referenced_table_changed = pyqtSignal(str)

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setupUi()

        self.cbo_ref_table.setInsertPolicy(QComboBox.InsertAlphabetically)

        self.cbo_ref_table.currentIndexChanged[str].connect(
            self._on_ref_table_changed)

        #Tables that will be omitted from the referenced table list
        self._omit_ref_tables = []

    def add_omit_table(self, table):
        """
        Add a table name that will be omitted from the list of referenced
        tables.
        :param table: Table name that will be omitted
        :type table: str
        """
        if not table in self._omit_ref_tables:
            self._omit_ref_tables.append(table)

    def add_omit_tables(self, tables):
        """
        Add a list of tables that will be omitted from the list of referenced
        tables.
        :param tables: Table names to be omitted.
        :type tables: list
        """
        for t in tables:
            self.add_omit_table(t)

    @property
    def omit_tables(self):
        """
        :return: Returns a list of tables that are to be omitted from the
        list of referenced tables.
        """
        return self._omit_ref_tables

    def setupUi(self):
        self.setObjectName("ReferencedTableEditor")
        self.gridLayout = QGridLayout(self)
        self.gridLayout.setVerticalSpacing(10)
        self.gridLayout.setObjectName("gridLayout")
        self.label_2 = QLabel(self)
        self.label_2.setMaximumSize(QSize(100, 16777215))
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
        self.cbo_source_field = QComboBox(self)
        self.cbo_source_field.setMinimumSize(QSize(0, 30))
        self.cbo_source_field.setObjectName("cbo_source_field")
        self.gridLayout.addWidget(self.cbo_source_field, 2, 1, 1, 1)
        self.label = QLabel(self)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
        self.label_3 = QLabel(self)
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 3, 0, 1, 1)
        self.cbo_referencing_col = QComboBox(self)
        self.cbo_referencing_col.setMinimumSize(QSize(0, 30))
        self.cbo_referencing_col.setObjectName("cbo_referencing_col")
        self.gridLayout.addWidget(self.cbo_referencing_col, 3, 1, 1, 1)
        self.cbo_ref_table = QComboBox(self)
        self.cbo_ref_table.setMinimumSize(QSize(0, 30))
        self.cbo_ref_table.setObjectName("cbo_ref_table")
        self.gridLayout.addWidget(self.cbo_ref_table, 1, 1, 1, 1)

        self.label_2.setText(
            QApplication.translate("ReferencedTableEditor", "References"))
        self.label.setText(
            QApplication.translate("ReferencedTableEditor",
                                   "Data source field"))
        self.label_3.setText(
            QApplication.translate("ReferencedTableEditor", "Referencing"))

        self._current_profile = current_profile()
        self._current_profile_tables = []
        if not self._current_profile is None:
            self._current_profile_tables = self._current_profile.table_names()

        #Connect signals
        QMetaObject.connectSlotsByName(self)
        self.cbo_ref_table.currentIndexChanged[str].connect(
            self._load_source_table_fields)

    @pyqtSlot(str)
    def on_data_source_changed(self, data_source_name):
        """
        Loads data source fields for the given data source name.
        """
        self.load_data_source_fields(data_source_name)

    def _on_ref_table_changed(self, table):
        """
        Raise signal when the referenced table changes.
        :param table: Selected table name.
        :type table: str
        """
        self.referenced_table_changed.emit(table)

    def properties(self):
        """
        :returns: Returns the user-defined mapping of linked table and column
        pairings.
        :rtype: LinkedTableProps
        """
        l_table = self.cbo_ref_table.currentText()
        s_field = self.cbo_source_field.currentText()
        l_field = self.cbo_referencing_col.currentText()

        return LinkedTableProps(linked_table=l_table,
                                source_field=s_field,
                                linked_field=l_field)

    def set_properties(self, table_props):
        """
        Sets the combo selection based on the text in the linked table
        object properties.
        :param table_props: Object containing the linked table information.
        :type table_props: LinkedTableProps
        """
        setComboCurrentIndexWithText(self.cbo_ref_table,
                                     table_props.linked_table)
        setComboCurrentIndexWithText(self.cbo_referencing_col,
                                     table_props.linked_field)
        setComboCurrentIndexWithText(self.cbo_source_field,
                                     table_props.source_field)

    def load_data_source_fields(self, data_source_name):
        """
        Load fields/columns of the given data source.
        """
        if data_source_name == "":
            self.clear()

            return

        columns_names = table_column_names(data_source_name)

        if len(columns_names) == 0:
            return

        self.cbo_source_field.clear()
        self.cbo_source_field.addItem("")
        self.cbo_source_field.addItems(columns_names)

    def clear(self):
        """
        Resets combo box selections.
        """
        self._reset_combo_index(self.cbo_ref_table)
        self._reset_combo_index(self.cbo_referencing_col)
        self._reset_combo_index(self.cbo_source_field)

    def _reset_combo_index(self, combo):
        if combo.count > 0:
            combo.setCurrentIndex(0)

    def reset_referenced_table(self):
        self._reset_combo_index(self.cbo_ref_table)

    def load_link_tables(self, reg_exp=None, source=TABLES | VIEWS):
        self.cbo_ref_table.clear()
        self.cbo_ref_table.addItem("")

        ref_tables = []
        source_tables = []
        #Table source
        if (TABLES & source) == TABLES:
            ref_tables.extend(pg_tables(exclude_lookups=True))

            for t in ref_tables:
                #Ensure we are dealing with tables in the current profile
                if not t in self._current_profile_tables:
                    continue

                #Assert if the table is in the list of omitted tables
                if t in self._omit_ref_tables:
                    continue

                if not reg_exp is None:
                    if reg_exp.indexIn(t) >= 0:
                        source_tables.append(t)
                else:
                    source_tables.append(t)

        # View source
        if (VIEWS & source) == VIEWS:
            profile_user_views = profile_and_user_views(self._current_profile)
            source_tables = source_tables + profile_user_views

        self.cbo_ref_table.addItems(source_tables)

    def _load_source_table_fields(self, sel):
        self.cbo_referencing_col.clear()
        data_source_index = self.cbo_source_field.currentIndex()
        self.on_data_source_changed(
            self.cbo_source_field.itemData(data_source_index))

        if not sel:
            return

        columns_names = table_column_names(sel)

        self.cbo_referencing_col.clear()
        self.cbo_referencing_col.addItem("")
        self.cbo_referencing_col.addItems(columns_names)
Beispiel #42
0
class SupportingDocumentsWidget(QWidget):
    """
    Widget for managing an entity's supporting documents. It enables listing
    of documents grouped by tabs depending on type.
    """
    def __init__(self,
                 entity_supporting_document,
                 supporting_doc_model_cls,
                 parent=None):
        """
        Class constructor.
        :param entity_supporting_document: Object containing information
        pertaining to document types, parent entity etc.
        :type entity_supporting_document: EntitySupportingDocument
        :param supporting_doc_model_cls: Class representing the data model
        corresponding to the entity supporting document object.
        :type supporting_doc_model_cls: object
        :param parent: Parent container widget.
        :type parent: QWidget
        """
        QWidget.__init__(self, parent)

        self._init_gui()

        self._entity_supporting_doc = entity_supporting_document

        #Container for document type widgets based on lookup id
        self._doc_type_widgets = {}

        #Init document manager
        self.source_document_manager = SourceDocumentManager(
            self._entity_supporting_doc, supporting_doc_model_cls, self)

        self._load_document_types()

        #Connect signals
        self._btn_add_document.clicked.connect(
            self._on_add_supporting_document)
        self._cbo_doc_type.currentIndexChanged.connect(
            self.on_doc_type_changed)
        self._doc_tab_container.currentChanged.connect(
            self.on_tab_doc_type_changed)

    def _init_gui(self):
        self._gl = QGridLayout(self)
        self._label = QLabel(self)
        self._label.setText(self.tr('Select document type'))
        self._gl.addWidget(self._label, 0, 0, 1, 1)
        self._cbo_doc_type = QComboBox(self)
        self._gl.addWidget(self._cbo_doc_type, 0, 1, 1, 1)
        self._btn_add_document = QPushButton(self)
        doc_ico = QIcon(':/plugins/stdm/images/icons/document.png')
        self._btn_add_document.setIcon(doc_ico)
        self._btn_add_document.setText(self.tr('Add document...'))
        self._btn_add_document.setMaximumWidth(200)
        self._gl.addWidget(self._btn_add_document, 0, 2, 1, 1)
        self._doc_tab_container = QTabWidget(self)
        self._gl.addWidget(self._doc_tab_container, 1, 0, 1, 3)

        self.setMinimumHeight(140)

    def on_doc_type_changed(self, idx):
        """
        Slot raised when the document types changes. The corresponding
        widget in the tab container is also selected.
        :param idx: Item index in the combobox.
        :type idx: int
        """
        if idx == -1:
            return

        self._doc_tab_container.setCurrentIndex(idx)

    def on_tab_doc_type_changed(self, idx):
        """
        Slot raised when the document types changes. The corresponding
        widget in the tab container is also selected.
        :param idx: Item index in the tab widget.
        :type idx: int
        """
        if idx == -1:
            return

        self._cbo_doc_type.setCurrentIndex(idx)

    def current_document_type(self):
        """
        :return: Returns the currently selected document type in the combobox.
        :rtype: str
        """
        return self._cbo_doc_type.currentText()

    def current_document_type_id(self):
        """
        :return: Returns the primary key/id of the currently selected
        document type in the combobox, else -1 if there is not current
        item in the combobox
        :rtype: int
        """
        if not self.current_document_type():
            return -1

        curr_idx = self._cbo_doc_type.currentIndex()

        return self._cbo_doc_type.itemData(curr_idx)

    def count(self):
        """
        :return: Returns the number of document types supported by this
        widget.
        :rtype: int
        """
        return self._cbo_doc_type.count()

    def document_type_containers(self):
        """
        :return: Returns a list of document container widgets for all
        registered document types.
        :rtype: list
        """
        return self.source_document_manager.containers.values()

    def document_type_widget(self, name):
        """
        Searches for the document type widget that corresponds to the given
        name.
        :param name: Name of the document type.
        :type name: str
        :return: Returns the document widget corresponding to the given type
        name.
        :rtype: QWidget
        """
        idx = self._cbo_doc_type.findText(name)

        if idx == -1:
            return None

        rec_id = self._cbo_doc_type.itemData(idx)

        return self._doc_type_widgets.get(rec_id, None)

    def _load_document_types(self):
        #Load document types in the combobox and tab widget
        vl_cls = entity_model(self._entity_supporting_doc.document_type_entity,
                              entity_only=True)

        vl_obj = vl_cls()
        res = vl_obj.queryObject().all()
        for r in res:
            #Add to combo
            self._cbo_doc_type.addItem(r.value, r.id)

            #Add to tab widget
            doc_type_widget = _DocumentTypeContainer(self)
            self._doc_tab_container.addTab(doc_type_widget, r.value)
            self._doc_type_widgets[r.id] = doc_type_widget

            #Register container
            self.source_document_manager.registerContainer(
                doc_type_widget.container, r.id)

    def _on_add_supporting_document(self):
        #Slot raised when the user select to add a supporting document
        if self.count == 0:
            return

        select = self.tr('Select')
        supporting_docs_str = 'Supporting Documents'
        title = u'{0} {1} {2}'.format(select, self.current_document_type(),
                                      supporting_docs_str)

        filter_str = u'{0} (*.jpg *.jpeg *.png *.bmp *.tiff *.svg *.pdf)'.format(
            supporting_docs_str)

        #Get last path for supporting documents
        last_path = last_document_path()
        if last_path is None:
            last_path = '/home'

        else:
            dir = QDir(last_path)
            if not dir.exists():
                last_path = '/home'

        source_docs = QFileDialog.getOpenFileNames(self, title, last_path,
                                                   filter_str)

        doc_type_id = self._cbo_doc_type.itemData(
            self._cbo_doc_type.currentIndex())
        parent_entity = self._entity_supporting_doc.parent_entity

        for doc in source_docs:
            self.source_document_manager.insertDocumentFromFile(
                doc, doc_type_id, parent_entity)

        #Set last path
        if len(source_docs) > 0:
            doc = source_docs[0]
            fi = QFileInfo(doc)
            dir_path = fi.absolutePath()
            set_last_document_path(dir_path)
class NumericParameterWidget(GenericParameterWidget):
    """Widget class for Numeric parameter."""
    def __init__(self, parameter, parent=None):
        """Constructor

        .. versionadded:: 2.2

        :param parameter: A NumericParameter object.
        :type parameter: NumericParameter

        """
        super(NumericParameterWidget, self).__init__(parameter, parent)

        self._input = QWidget()

        self._unit_widget = QLabel()
        self.set_unit()

        # Size policy
        self._spin_box_size_policy = QSizePolicy(
            QSizePolicy.Fixed, QSizePolicy.Fixed)

        label_policy = QSizePolicy(
            QSizePolicy.Minimum, QSizePolicy.Fixed)
        self._unit_widget.setSizePolicy(label_policy)

        # Add unit description to description
        description = self.help_label.text()
        if self._parameter.allowed_units:
            description += '<br><br>Available units:'
            description += '<ul>'
            for allowed_unit in self._parameter.allowed_units:
                description += '<li>'
                description += '<b>' + allowed_unit.name + '</b>: '
                description += allowed_unit.description or ''
                description += '</li>'
            description += '</ul>'
        self.help_label.setText(description)

    def get_parameter(self):
        """Obtain numeric parameter object from the current widget state.

        :returns: A NumericParameter from the current state of widget

        """
        self._parameter.value = self._input.value()
        if len(self._parameter.allowed_units) > 1:
            current_index = self._unit_widget.currentIndex()
            unit = self._unit_widget.itemData(current_index, Qt.UserRole)
            if hasattr(unit, 'toPyObject'):
                unit = unit.toPyObject()
            self._parameter.unit = unit
        return self._parameter

    def set_unit(self):
        """Set up label or combo box for unit."""
        if len(self._parameter.allowed_units) == 1:
            self._unit_widget = QLabel(self._parameter.unit.name)
            self._unit_widget.setToolTip(self._parameter.unit.help_text)
        elif len(self._parameter.allowed_units) > 1:
            self._unit_widget = QComboBox()
            index = -1
            current_index = -1
            for allowed_unit in self._parameter.allowed_units:
                name = allowed_unit.name
                tooltip = allowed_unit.help_text
                index += 1
                if allowed_unit.guid == self._parameter.unit.guid:
                    current_index = index
                self._unit_widget.addItem(name)
                self._unit_widget.setItemData(index, tooltip, Qt.ToolTipRole)
                self._unit_widget.setItemData(index, allowed_unit, Qt.UserRole)
            self._unit_widget.setCurrentIndex(current_index)
            self._unit_widget.setToolTip('Select your preferred unit')
            self._unit_widget.currentIndex()

    def set_value(self, value):
        """Set the value of the input

        :param value: The new value
        :type value: int, float
        """
        self._input.setValue(value)
Beispiel #44
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """
    def __init__(self, main_combo=False):
        super(ActionBar, self).__init__()
        self.setObjectName("actionbar")
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(1, 1, 1, 1)
        hbox.setSpacing(1)

        self.lbl_checks = QLabel('')
        self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.lbl_checks.setFixedWidth(48)
        self.lbl_checks.setVisible(False)
        hbox.addWidget(self.lbl_checks)

        self.combo = QComboBox()
        #model = QStandardItemModel()
        #self.combo.setModel(model)
        #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove)
        self.combo.setMaximumWidth(300)
        self.combo.setObjectName("combotab")
        self.connect(self.combo, SIGNAL("currentIndexChanged(int)"),
                     self.current_changed)
        self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP)
        self.combo.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.combo,
                     SIGNAL("customContextMenuRequested(const QPoint &)"),
                     self._context_menu_requested)
        hbox.addWidget(self.combo)

        self.symbols_combo = QComboBox()
        self.symbols_combo.setObjectName("combo_symbols")
        self.connect(self.symbols_combo, SIGNAL("activated(int)"),
                     self.current_symbol_changed)
        hbox.addWidget(self.symbols_combo)

        self.code_navigator = CodeNavigator()
        hbox.addWidget(self.code_navigator)

        self._pos_text = "Line: %d, Col: %d"
        self.lbl_position = QLabel(self._pos_text % (0, 0))
        self.lbl_position.setObjectName("position")
        self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_position)

        self.btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        if main_combo:
            self.btn_close.setObjectName('navigation_button')
            self.btn_close.setToolTip(translations.TR_CLOSE_FILE)
            self.connect(self.btn_close, SIGNAL("clicked()"),
                         self.about_to_close_file)
        else:
            self.btn_close.setObjectName('close_split')
            self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
            self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split)
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.btn_close)

    def resizeEvent(self, event):
        super(ActionBar, self).resizeEvent(event)
        if event.size().width() < 350:
            self.symbols_combo.hide()
            self.code_navigator.hide()
            self.lbl_position.hide()
        else:
            self.symbols_combo.show()
            self.code_navigator.show()
            self.lbl_position.show()

    def add_item(self, text, neditable):
        """Add a new item to the combo and add the neditable data."""
        self.combo.addItem(text, neditable)
        self.combo.setCurrentIndex(self.combo.count() - 1)

    def get_editables(self):
        editables = []
        for index in range(self.combo.count()):
            neditable = self.combo.itemData(index)
            editables.append(neditable)
        return editables

    def add_symbols(self, symbols):
        """Add the symbols to the symbols's combo."""
        self.symbols_combo.clear()
        for symbol in symbols:
            data = symbol[1]
            if data[1] == 'f':
                icon = QIcon(":img/function")
            else:
                icon = QIcon(":img/class")
            self.symbols_combo.addItem(icon, data[0])

    def set_current_symbol(self, index):
        self.symbols_combo.setCurrentIndex(index)

    def update_item_icon(self, neditable, icon):
        index = self.combo.findData(neditable)
        self.combo.setItemIcon(index, icon)

    def update_item_text(self, neditable, text):
        index = self.combo.findData(neditable)
        self.combo.setItemText(index, text)

    def current_changed(self, index):
        """Change the current item in the combo."""
        neditable = self.combo.itemData(index)
        self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable,
                  index)

    def current_symbol_changed(self, index):
        """Change the current symbol in the combo."""
        self.emit(SIGNAL("goToSymbol(int)"), index)

    def update_line_col(self, line, col):
        """Update the line and column position."""
        self.lbl_position.setText(self._pos_text % (line, col))

    def _context_menu_requested(self, point):
        """Display context menu for the combo file."""
        if self.combo.count() == 0:
            # If there is not an Editor opened, don't show the menu
            return
        menu = QMenu()
        actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT)
        actionRun = menu.addAction(translations.TR_RUN_FILE)
        menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX)
        self._create_menu_syntax(menuSyntax)
        menu.addSeparator()
        actionClose = menu.addAction(translations.TR_CLOSE_FILE)
        actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES)
        actionCloseAllNotThis = menu.addAction(
            translations.TR_CLOSE_OTHER_FILES)
        menu.addSeparator()
        actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY)
        actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY)
        menu.addSeparator()
        actionCopyPath = menu.addAction(
            translations.TR_COPY_FILE_PATH_TO_CLIPBOARD)
        actionReopen = menu.addAction(translations.TR_REOPEN_FILE)
        actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR)
        if len(settings.LAST_OPENED_FILES) == 0:
            actionReopen.setEnabled(False)
        #Connect actions
        self.connect(actionSplitH, SIGNAL("triggered()"),
                     lambda: self._split(False))
        self.connect(actionSplitV, SIGNAL("triggered()"),
                     lambda: self._split(True))
        self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file)
        self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project)
        self.connect(actionClose, SIGNAL("triggered()"),
                     self.about_to_close_file)
        self.connect(actionCloseAllNotThis, SIGNAL("triggered()"),
                     self._close_all_files_except_this)
        self.connect(actionCloseAll, SIGNAL("triggered()"),
                     self._close_all_files)
        self.connect(actionCopyPath, SIGNAL("triggered()"),
                     self._copy_file_location)
        self.connect(actionReopen, SIGNAL("triggered()"),
                     self._reopen_last_tab)
        self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor)

        menu.exec_(QCursor.pos())

    def _create_menu_syntax(self, menuSyntax):
        """Create Menu with the list of syntax supported."""
        syntax = list(settings.SYNTAX.keys())
        syntax.sort()
        for syn in syntax:
            menuSyntax.addAction(syn)
            self.connect(menuSyntax, SIGNAL("triggered(QAction*)"),
                         self._reapply_syntax)

    def _reapply_syntax(self, syntaxAction):
        #TODO
        if [self.currentIndex(), syntaxAction] != self._resyntax:
            self._resyntax = [self.currentIndex(), syntaxAction]
            self.emit(SIGNAL("syntaxChanged(QWidget, QString)"),
                      self.currentWidget(), syntaxAction.text())

    def set_current_file(self, neditable):
        index = self.combo.findData(neditable)
        self.combo.setCurrentIndex(index)

    def set_current_by_index(self, index):
        self.combo.setCurrentIndex(index)

    def about_to_close_file(self, index=None):
        """Close the NFile object."""
        if index is None:
            index = self.combo.currentIndex()
        neditable = self.combo.itemData(index)
        if neditable:
            neditable.nfile.close()

    def close_split(self):
        self.emit(SIGNAL("closeSplit()"))

    def close_file(self, neditable):
        """Receive the confirmation to close the file."""
        index = self.combo.findData(neditable)
        self.combo.removeItem(index)
        return index

    def _run_this_file(self):
        """Execute the current file."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("runFile(QString)"), neditable.file_path)

    def _add_to_project(self):
        """Emit a signal to let someone handle the inclusion of the file
        inside a project."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("addToProject(QString)"), neditable.file_path)

    def _reopen_last_tab(self):
        self.emit(SIGNAL("reopenTab(QString)"),
                  settings.LAST_OPENED_FILES.pop())
        self.emit(SIGNAL("recentTabsModified()"))

    def _undock_editor(self):
        self.emit(SIGNAL("undockEditor()"))

    def _split(self, orientation):
        self.emit(SIGNAL("splitEditor(bool)"), orientation)

    def _copy_file_location(self):
        """Copy the path of the current opened file to the clipboard."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        QApplication.clipboard().setText(neditable.file_path,
                                         QClipboard.Clipboard)

    def _close_all_files(self):
        """Close all the files opened."""
        for i in range(self.combo.count()):
            self.about_to_close_file(0)

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        for i in reversed(list(range(self.combo.count()))):
            ne = self.combo.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
class ResolutionSettingWidget(QWidget):
        
    def __init__(self, app, parent = None):
        super(ResolutionSettingWidget,self).__init__(parent)
        self.setStyleSheet("font-size : 16px;")
        self.app = app
        CDLL("libjson-c.so", mode=RTLD_GLOBAL)
        self.jytcapi = cdll.LoadLibrary('../lib/libjytcapi.so')
        self.jytcapi.jyinittcapi()
        self.resolutionLabel = QLabel(self.tr("Resolution setting"))
        
        self.resolutionCombox = QComboBox()
        self.resolutionCombox.setFixedSize(300, 30)
        
        self.saveBtn = QPushButton(self.tr("Save"))
        self.saveBtn.setStyleSheet("background: rgb(7,87,198); color: white; width: 90px; height: 30px;font-size : 16px;")
      
        gridLayout = QGridLayout()
        gridLayout.setSpacing(15)
        gridLayout.setMargin(10)
        gridLayout.addWidget(self.resolutionLabel, 0, 0, 1, 1)
        gridLayout.addWidget(self.resolutionCombox, 0, 1, 1, 1)
        
        topLayout = QHBoxLayout()
        topLayout.addStretch()
        topLayout.addSpacing(50)
        topLayout.addLayout(gridLayout)
        topLayout.addStretch(1)
        
        bottomHLayout = QHBoxLayout()
        bottomHLayout.addStretch()
        bottomHLayout.addWidget(self.saveBtn)
        bottomHLayout.addStretch()
        
        vLayout = QVBoxLayout()
        vLayout.addStretch()
        vLayout.addSpacing(50)
        vLayout.addLayout(topLayout)
        vLayout.addStretch(2)
        vLayout.addSpacing(10)
        vLayout.addLayout(bottomHLayout)
        
        self.setLayout(vLayout)
        
        self.updateResolutionCombox()
        
        self.timer = QTimer()
        self.timer.setSingleShot(True)
        self.connect(self.timer,SIGNAL("timeout()"),self.resetScreenResolution);
        
        self.connect(self.saveBtn, SIGNAL("clicked()"),self.slotSave)
    
    def updateWindow(self):
        self.resolutionLabel.setText(self.tr(self.tr("Resolution setting")))
        self.saveBtn.setText(self.tr("Save"))
        
        
    def getCmdExecValue(self, cmd):
        statusOutput = commands.getstatusoutput(cmd)
        monitorList = statusOutput[1].split("\n")
        return monitorList
    def getCmdExecValueT(self, cmd):
        """得到命令执行的结果"""
        statusOutput = commands.getstatusoutput(cmd)
        monitorList = statusOutput[1].split("\n")
        return monitorList
    
    def showCurrentScreenResolution(self, curResolutionValue):
        """显示当前屏幕的分辨率"""
        count = self.resolutionCombox.count()
        for i in range(count):
            if self.resolutionCombox.itemText(i) == curResolutionValue:
                self.resolutionCombox.setCurrentIndex(i)
                return
            
        self.resolutionCombox.setCurrentIndex(-1)
        
    def getCurrentScreenResolution(self, screenName):
        currentSolution = "10"
        reSolution = "auto"
        solutionMap = {"0":"800x600","1":"1024x768","2":"1280x720","3":"1440x900","4":"1600x1020","5":"1920x1080","6":"1280x1024","7":"1366x768","8":"1600x900","10":"auto"}
        cmd = "../lib/ccr_jytcapi current_display"
        value =  self.getCmdExecValueT(cmd)
        for i in range(len(value)):
            LogRecord.instance().logger.info("#".join(value))
            if len(value[i].split(":"))==2 and value[i].split(":")[0]=="res" and value[i].split(":")[1] !="auto":
                currentSolution = value[i].split(":")[1]
                break
        if solutionMap.has_key(currentSolution):
            reSolution = solutionMap[currentSolution]
        return reSolution
        
    def updateResolutionCombox(self):
        """更新分辨率下拉框的内容"""
        #得到屏幕支持的分辨率
        self.resolutionCombox.clear()
        resolutionmMap = self.getScreenResolution()
        if resolutionmMap:
            screenName = resolutionmMap.keys()[0]
            for resolution in resolutionmMap[screenName]:
                if resolution == "800x600":
                    pass
                else:
                    self.resolutionCombox.addItem(resolution)
            self.resolutionCombox.setItemData(0, screenName, Qt.UserRole + 1);
        
        #获取当前屏幕的分辨率
        self.curResolutionValue = self.getCurrentScreenResolution(screenName)
        
        #显示当前屏幕的分辨率
        self.showCurrentScreenResolution(self.curResolutionValue)
        
    def getScreenResolution(self):
        """得到屏幕支持的分辨率"""
        #获得显示器名称,连接状态及行号
        Monitors = self.getCmdExecValueT("../lib/ccr_jytcapi display");

        #根据组合列表把显示器名称和支持的分辨率放入到一个字典中
        resolutionMap = {}
        resolutionList = []
        count = len(Monitors)
        for i in range(count):
            if len(Monitors[i].split(":"))<2:
                continue
            valueName = Monitors[i].split(":")[0]
            valueValue = Monitors[i].split(":")[1]
            
            if valueName == "value":
                resolutionList.append(valueValue)
      
        resolutionMap["monitorName"] = resolutionList
          
        return resolutionMap
    
    
        
    def slotSave(self):
        language = StoreInfoParser.instance().getLanguage()
        m_pTranslator = QTranslator()
        exePath = "./"
        if language == "chinese":
            QmName = "zh_CN.qm"
        else:
            QmName = "en_US.qm"
        if(m_pTranslator.load(QmName, exePath)):
            QCoreApplication.instance().installTranslator(m_pTranslator)
            
        """改变当前的分辨率"""
        screenName = self.resolutionCombox.itemData(0, Qt.UserRole + 1).toString()
        if not screenName.isEmpty() and not screenName.isNull():
            self.curResolutionValue = self.getCurrentScreenResolution(str(screenName))
            if self.curResolutionValue:
                reScreen = self.resolutionCombox.currentText()
                if reScreen == "800x600":
                   pass 
                else:
                   pass
                #弹出提示框,默认为取消
                rb = MessageBox(self.tr("making sure set the resolution to current"), self).exec_()
                if rb == QDialog.Accepted:
                   self.jytcapi.jysetdispconf(str(reScreen))
                elif rb == QDialog.Rejected:
                   pass
                    
    def resetScreenResolution(self):
        """还原分辨率"""
        #关闭提示窗口
        children = self.children()
        count = len(children)
        for i in range(count):
            if isinstance(children[i], MessageBox):
                children[i].close()
        
        #还原之前的分辨率
        if self.jytcapi.jysetdispconf(self.curResolutionValue) != 0:
#             QMessageBox.information(None,u"错误",u'还原分辨率失败')
            InfoHintDialog(self.tr("reserve failed")).exec_()
            return
        
        #刷新分辨率下拉框
        self.updateResolutionCombox()
        
        if QString(self.curResolutionValue).contains("x"):
            width = self.curResolutionValue.split("x")[0]
            height = self.curResolutionValue.split("x")[1]
            self.emit(SIGNAL("resizePosition"), width, height)
            
        #刷新屏幕
        self.app.slotRefreshVMList()
    
    def writeConfigFile(self, curResolution):
        """记录修改后的配置文件"""
        StoreInfoParser.instance().setResolutionValue(curResolution)
Beispiel #46
0
class AmbientLightV2(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAmbientLightV2, *args)

        self.al = self.device

        self.has_clamped_output = self.firmware_version >= (2, 0, 2)

        self.cbe_illuminance = CallbackEmulator(self.al.get_illuminance,
                                                self.cb_illuminance,
                                                self.increase_error_count)

        self.illuminance_label = IlluminanceLabel('Illuminance: ')
        self.alf = AmbientLightFrame()
        self.out_of_range_label = QLabel('out-of-range')
        self.saturated_label = QLabel('sensor saturated')

        self.out_of_range_label.hide()
        self.out_of_range_label.setStyleSheet('QLabel { color: red }')
        self.saturated_label.hide()
        self.saturated_label.setStyleSheet('QLabel { color: magenta }')

        self.current_value = None

        plot_list = [['', Qt.red, self.get_current_value]]
        self.plot_widget = PlotWidget('Illuminance [lx]', plot_list)

        layout_h = QHBoxLayout()
        layout_h.addStretch()
        layout_h.addWidget(self.illuminance_label)
        layout_h.addWidget(self.out_of_range_label)
        layout_h.addWidget(self.saturated_label)
        layout_h.addWidget(self.alf)
        layout_h.addStretch()
        
        self.range_label = QLabel('Illuminance Range: ')
        self.range_combo = QComboBox()
        if self.has_clamped_output: # Also means that the unlimited range is available
            self.range_combo.addItem("Unlimited", BrickletAmbientLightV2.ILLUMINANCE_RANGE_UNLIMITED)
        self.range_combo.addItem("0 - 64000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX)
        self.range_combo.addItem("0 - 32000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX)
        self.range_combo.addItem("0 - 16000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX)
        self.range_combo.addItem("0 - 8000 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX)
        self.range_combo.addItem("0 - 1300 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX)
        self.range_combo.addItem("0 - 600 Lux", BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX)
        self.range_combo.currentIndexChanged.connect(self.new_config)
        
        self.time_label = QLabel('Integration Time: ')
        self.time_combo = QComboBox()
        self.time_combo.addItem("50ms", BrickletAmbientLightV2.INTEGRATION_TIME_50MS)
        self.time_combo.addItem("100ms", BrickletAmbientLightV2.INTEGRATION_TIME_100MS)
        self.time_combo.addItem("150ms", BrickletAmbientLightV2.INTEGRATION_TIME_150MS)
        self.time_combo.addItem("200ms", BrickletAmbientLightV2.INTEGRATION_TIME_200MS)
        self.time_combo.addItem("250ms", BrickletAmbientLightV2.INTEGRATION_TIME_250MS)
        self.time_combo.addItem("300ms", BrickletAmbientLightV2.INTEGRATION_TIME_300MS)
        self.time_combo.addItem("350ms", BrickletAmbientLightV2.INTEGRATION_TIME_350MS)
        self.time_combo.addItem("400ms", BrickletAmbientLightV2.INTEGRATION_TIME_400MS)
        self.time_combo.currentIndexChanged.connect(self.new_config)
        
        layout_hc = QHBoxLayout()
        layout_hc.addStretch()
        layout_hc.addWidget(self.range_label)
        layout_hc.addWidget(self.range_combo)
        layout_hc.addStretch()
        layout_hc.addWidget(self.time_label)
        layout_hc.addWidget(self.time_combo)
        layout_hc.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h)
        layout.addWidget(self.plot_widget)
        layout.addLayout(layout_hc)

    def start(self):
        async_call(self.al.get_configuration, None, self.get_configucation_async, self.increase_error_count)
        async_call(self.al.get_illuminance, None, self.cb_illuminance, self.increase_error_count)
        self.cbe_illuminance.set_period(100)

        self.plot_widget.stop = False

    def stop(self):
        self.cbe_illuminance.set_period(0)

        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'ambient_light_v2'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAmbientLightV2.DEVICE_IDENTIFIER
    
    def get_configucation_async(self, conf):
        self.range_combo.setCurrentIndex(self.range_combo.findData(conf.illuminance_range))
        self.time_combo.setCurrentIndex(self.time_combo.findData(conf.integration_time))
        
    def new_config(self, value):
        try:
            self.al.set_configuration(self.range_combo.itemData(self.range_combo.currentIndex()),
                                      self.time_combo.itemData(self.time_combo.currentIndex()))
        except:
            pass

    def get_current_value(self):
        return self.current_value

    def cb_illuminance(self, illuminance):
        self.current_value = illuminance/100.0
        self.illuminance_label.setText(illuminance)

        max_illuminance = 12000000 # Approximation for unlimited range
        current_range = self.range_combo.itemData(self.range_combo.currentIndex())
        if current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_64000LUX:
            max_illuminance = 6400001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_32000LUX:
            max_illuminance = 3200001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_16000LUX:
            max_illuminance = 1600001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_8000LUX:
            max_illuminance = 800001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_1300LUX:
            max_illuminance = 130001
        elif current_range == BrickletAmbientLightV2.ILLUMINANCE_RANGE_600LUX:
            max_illuminance = 60001

        if self.has_clamped_output: # Also means that the unlimited range is available
            if illuminance == 0:
                self.illuminance_label.setStyleSheet('QLabel { color: magenta }')
                self.out_of_range_label.hide()
                self.saturated_label.show()
            elif illuminance >= max_illuminance:
                self.illuminance_label.setStyleSheet('QLabel { color: red }')
                self.out_of_range_label.show()
                self.saturated_label.hide()
            else:
                self.illuminance_label.setStyleSheet('')
                self.out_of_range_label.hide()
                self.saturated_label.hide()

        value = min(max(illuminance*255/max_illuminance, 0), 255)
        self.alf.set_color(value, value, value)
Beispiel #47
0
class HydraulicsDialog(QDialog):
    def __init__(self, parent, params, new_proj=False):
        QDialog.__init__(self, parent)

        self.parent = parent
        self.params = params
        self.new_proj = new_proj

        self.setMinimumWidth(min_width)
        # self.setMinimumHeight(min_height)

        # Build dialog
        self.setWindowTitle('Options - Hydraulics')  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.fra_form = QFrame(self)
        fra_form_lay = QFormLayout(self.fra_form)
        fra_form_lay.setContentsMargins(10, 10, 10, 10)

        self.lbl_units = QLabel('Units system:')  # TODO: softocode
        self.cbo_units = QComboBox()
        fra_form_lay.addRow(self.lbl_units, self.cbo_units)

        self.lbl_flow_units = QLabel('Flow units:')  # TODO: softocode
        self.cbo_flow_units = QComboBox()
        fra_form_lay.addRow(self.lbl_flow_units, self.cbo_flow_units)

        self.lbl_headloss = QLabel('Head loss:')  # TODO: softocode
        self.cbo_headloss = QComboBox()
        fra_form_lay.addRow(self.lbl_headloss, self.cbo_headloss)

        self.chk_hydraulics = QCheckBox('Hydraulics:')  # TODO: softcode
        self.cbo_hydraulics = QComboBox()
        fra_form_lay.addRow(self.chk_hydraulics, self.cbo_hydraulics)

        self.txt_hydraulics_file = QLineEdit()
        fra_form_lay.addRow(None, self.txt_hydraulics_file)

        self.btn_hydraulics_file = QPushButton('File...')  # TODO: softcode
        fra_form_lay.addRow(None, self.btn_hydraulics_file)

        self.lbl_viscosity = QLabel('Viscosity:')  # TODO: softocode
        self.txt_viscosity = QLineEdit()
        fra_form_lay.addRow(self.lbl_viscosity, self.txt_viscosity)

        self.lbl_diffusivity = QLabel('Diffusivity:')  # TODO: softocode
        self.txt_diffusivity = QLineEdit()
        fra_form_lay.addRow(self.lbl_diffusivity, self.txt_diffusivity)

        self.lbl_spec_gravity = QLabel('Specific gravity:')  # TODO: softocode
        self.txt_spec_gravity = QLineEdit()
        fra_form_lay.addRow(self.lbl_spec_gravity, self.txt_spec_gravity)

        self.lbl_max_trials = QLabel('Max trials:')  # TODO: softocode
        self.txt_max_trials = QLineEdit()
        fra_form_lay.addRow(self.lbl_max_trials, self.txt_max_trials)

        self.lbl_accuracy = QLabel('Accuracy:')  # TODO: softocode
        self.txt_accuracy = QLineEdit()
        fra_form_lay.addRow(self.lbl_accuracy, self.txt_accuracy)

        self.lbl_unbalanced = QLabel('Unbalanced:')  # TODO: softcode
        self.fra_unbalanced = QFrame(self)
        fra_unbalanced_lay = QHBoxLayout(self.fra_unbalanced)
        fra_unbalanced_lay.setContentsMargins(0, 0, 0, 0)
        self.cbo_unbalanced = QComboBox()
        self.txt_unbalanced = QLineEdit()
        fra_unbalanced_lay.addWidget(self.cbo_unbalanced)
        fra_unbalanced_lay.addWidget(self.txt_unbalanced)
        fra_form_lay.addRow(self.lbl_unbalanced, self.fra_unbalanced)

        self.lbl_pattern = QLabel('Pattern:')  # TODO: softocode
        self.cbo_pattern = QComboBox()
        fra_form_lay.addRow(self.lbl_pattern, self.cbo_pattern)

        self.lbl_demand_mult = QLabel('Demand multiplier:')  # TODO: softocode
        self.txt_demand_mult = QLineEdit()
        fra_form_lay.addRow(self.lbl_demand_mult, self.txt_demand_mult)

        self.lbl_emitter_exp = QLabel('Emitter exponent:')  # TODO: softocode
        self.txt_emitter_exp = QLineEdit()
        fra_form_lay.addRow(self.lbl_emitter_exp, self.txt_emitter_exp)

        self.lbl_tolerance = QLabel('Tolerance:')  # TODO: softocode
        self.txt_tolerance = QLineEdit()
        fra_form_lay.addRow(self.lbl_tolerance, self.txt_tolerance)

        # Buttons
        self.fra_buttons = QFrame(self)
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        self.btn_Cancel = QPushButton('Cancel')
        self.btn_Ok = QPushButton('OK')
        fra_buttons_lay.addWidget(self.btn_Ok)
        fra_buttons_lay.addWidget(self.btn_Cancel)

        # Add to main
        fra_main_lay = QVBoxLayout(self)
        fra_main_lay.setContentsMargins(0, 0, 0, 0)
        fra_main_lay.addWidget(self.fra_form)
        fra_main_lay.addWidget(self.fra_buttons)

        self.setup()

    def setup(self):

        # Fill units system combo box
        for unit in self.params.options.units_sys:
            self.cbo_units.addItem(self.params.options.units_sys_text[unit],
                                   unit)

        # Fill flow units combo box
        for fu in Options.units_flow[self.params.options.units]:
            self.cbo_flow_units.addItem(Options.units_flow_text[fu], fu)

        self.cbo_units.activated.connect(self.cbo_units_activated)
        # self.cbo_flow_units.activated.connect(self.cbo_flow_units_activated)

        for key, value in self.params.options.headlosses_text.iteritems():
            self.cbo_headloss.addItem(value, key)

        self.cbo_headloss.activated.connect(self.cbo_headloss_activated)

        self.chk_hydraulics.stateChanged.connect(self.chk_hydraulics_changed)
        self.btn_hydraulics_file.clicked.connect(self.btn_hydraulics_clicked)
        self.cbo_hydraulics.addItem(
            self.params.options.hydraulics.action_names[
                self.params.options.hydraulics.action_use],
            self.params.options.hydraulics.action_use)
        self.cbo_hydraulics.addItem(
            self.params.options.hydraulics.action_names[
                self.params.options.hydraulics.action_save],
            self.params.options.hydraulics.action_save)
        self.txt_hydraulics_file.setReadOnly(True)

        # - Unbalanced
        for id, text in self.params.options.unbalanced.unb_text.iteritems():
            self.cbo_unbalanced.addItem(text, id)

        self.cbo_unbalanced.activated.connect(self.cbo_unbalanced_changed)
        self.txt_unbalanced.setValidator(RegExValidators.get_pos_int_no_zero())
        self.txt_unbalanced.setText('1')

        # - Pattern
        self.cbo_pattern.addItem('None (=1.0)', None)
        for pattern_id, pattern in self.params.patterns.iteritems():
            self.cbo_pattern.addItem(pattern_id, pattern)

        # Buttons
        self.btn_Cancel.clicked.connect(self.btn_cancel_clicked)
        self.btn_Ok.clicked.connect(self.btn_ok_clicked)

        # Validators
        self.txt_viscosity.setValidator(RegExValidators.get_pos_decimals())
        self.txt_diffusivity.setValidator(RegExValidators.get_pos_decimals())
        self.txt_spec_gravity.setValidator(RegExValidators.get_pos_decimals())
        self.txt_max_trials.setValidator(RegExValidators.get_pos_int_no_zero())
        self.txt_accuracy.setValidator(RegExValidators.get_pos_decimals())
        self.txt_demand_mult.setValidator(RegExValidators.get_pos_decimals())
        self.txt_emitter_exp.setValidator(RegExValidators.get_pos_decimals())
        self.txt_tolerance.setValidator(RegExValidators.get_pos_decimals())

    def show(self):
        super(HydraulicsDialog, self).show()

        self.cbo_units.setCurrentIndex(
            self.cbo_units.findData(self.params.options.units))
        self.cbo_flow_units.setCurrentIndex(
            self.cbo_flow_units.findData(self.params.options.flow_units))
        self.cbo_headloss.setCurrentIndex(
            self.cbo_headloss.findData(self.params.options.headloss))

        self.chk_hydraulics.setChecked(
            self.params.options.hydraulics.use_hydraulics)
        self.btn_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked())
        self.cbo_hydraulics.setEnabled(self.chk_hydraulics.isChecked())
        self.txt_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked())

        if self.params.options.hydraulics.action is not None:
            self.cbo_hydraulics.setCurrentIndex(
                self.cbo_hydraulics.findData(
                    self.params.options.hydraulics.action))
        if self.params.options.hydraulics.file is not None:
            self.txt_hydraulics_file.setText(
                self.params.options.hydraulics.file)

        self.txt_viscosity.setText(str(self.params.options.viscosity))
        self.txt_diffusivity.setText(str(self.params.options.diffusivity))
        self.txt_spec_gravity.setText(str(self.params.options.spec_gravity))
        self.txt_max_trials.setText(str(self.params.options.trials))
        self.txt_accuracy.setText(str(self.params.options.accuracy))

        self.cbo_unbalanced.setCurrentIndex(
            self.cbo_unbalanced.findData(
                self.params.options.unbalanced.unbalanced))
        self.txt_unbalanced.setEnabled(self.cbo_unbalanced.currentIndex() != 0)
        self.txt_unbalanced.setText(str(self.params.options.unbalanced.trials))

        # Patterns
        if self.params.options.pattern is not None:
            if self.params.options.pattern is None:
                self.cbo_pattern.setCurrentIndex(0)
            else:
                for i in range(self.cbo_pattern.count()):
                    if self.params.options.pattern.id == self.cbo_pattern.itemText(
                            i):
                        self.cbo_pattern.setCurrentIndex(i)
                        break

        self.txt_demand_mult.setText(str(self.params.options.demand_mult))
        self.txt_emitter_exp.setText(str(self.params.options.emitter_exp))
        self.txt_tolerance.setText(str(self.params.options.tolerance))

    def cbo_units_activated(self):

        self.params.options.units = self.cbo_units.itemData(
            self.cbo_units.currentIndex())

        # Parameters combo box
        self.cbo_flow_units.clear()
        for fu in Options.units_flow[self.params.options.units]:
            self.cbo_flow_units.addItem(Options.units_flow_text[fu], fu)

    def cbo_headloss_activated(self):

        # Warning
        if not self.new_proj:
            QMessageBox.warning(
                self, Parameters.plug_in_name,
                u'Head loss units changed: the head loss values already present might need to be reviewed.',
                QMessageBox.Ok)

    def chk_hydraulics_changed(self):

        self.btn_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked())
        self.cbo_hydraulics.setEnabled(self.chk_hydraulics.isChecked())
        self.txt_hydraulics_file.setEnabled(self.chk_hydraulics.isChecked())

    def btn_hydraulics_clicked(self):
        file_dialog = QFileDialog(self, 'Select hydraulics file')
        file_dialog.setLabelText(QFileDialog.Accept, 'Select')
        file_dialog.setLabelText(QFileDialog.Reject, 'Cancel')
        file_dialog.setFileMode(QFileDialog.AnyFile)

        file_dialog.exec_()

        hydraulics_file_path = file_dialog.selectedFiles()

        if not hydraulics_file_path or hydraulics_file_path[
                0] is None or hydraulics_file_path[0] == '':
            return

        self.txt_hydraulics_file.setText(hydraulics_file_path[0])

    def cbo_unbalanced_changed(self):
        self.txt_unbalanced.setEnabled(
            self.cbo_unbalanced.itemData(self.cbo_unbalanced.currentIndex()) ==
            self.params.options.unbalanced.unb_continue)

    def btn_cancel_clicked(self):
        self.setVisible(False)

    def btn_ok_clicked(self):

        if not self.check_params():
            return

        # Update parameters and options
        self.params.options.units = self.cbo_units.itemData(
            self.cbo_units.currentIndex())
        self.params.options.flow_units = self.cbo_flow_units.itemData(
            self.cbo_flow_units.currentIndex())
        self.params.options.headloss = self.cbo_headloss.itemData(
            self.cbo_headloss.currentIndex())
        self.params.options.hydraulics.use_hydraulics = self.chk_hydraulics.isChecked(
        )

        if self.params.options.hydraulics.action is not None:
            self.params.options.hydraulics.action = self.cbo_hydraulics.itemData(
                self.cbo_hydraulics.currentIndex())
            self.params.options.hydraulics.file = self.txt_hydraulics_file.text(
            )

        self.params.options.viscosity = float(self.txt_viscosity.text())
        self.params.options.diffusivity = float(self.txt_diffusivity.text())
        self.params.options.spec_gravity = float(self.txt_spec_gravity.text())
        self.params.options.trials = float(self.txt_max_trials.text())
        self.params.options.accuracy = float(self.txt_accuracy.text())

        self.params.options.unbalanced.unbalanced = self.cbo_unbalanced.itemData(
            self.cbo_unbalanced.currentIndex())
        self.params.options.unbalanced.trials = int(self.txt_unbalanced.text())

        self.params.options.pattern = self.cbo_pattern.itemData(
            self.cbo_pattern.currentIndex())
        self.params.options.demand_mult = float(self.txt_demand_mult.text())
        self.params.options.emitter_exp = float(self.txt_emitter_exp.text())
        self.params.options.tolerance = float(self.txt_tolerance.text())

        # Junctions
        self.parent.lbl_junction_demand.setText(
            pre_l('Demand', Options.units_flow[self.params.options.units]
                  [0]))  # TODO: softcode
        self.parent.lbl_junction_deltaz.setText(
            pre_l('Delta Z', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode

        # Reservoirs
        self.parent.lbl_reservoir_deltaz.setText(
            pre_l('Delta Z', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_reservoir_pressure_head.setText(
            pre_l('Pressure head', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode

        # Tanks
        self.parent.lbl_tank_deltaz.setText(
            pre_l('Delta Z', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_level_init.setText(
            pre_l('Level init.', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_level_min.setText(
            pre_l('Level min', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_level_max.setText(
            pre_l('Level max', Options.units_deltaz[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_diameter.setText(
            pre_l('Diameter', Options.units_diameter_tanks[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_tank_vol_min.setText(
            pre_l('Volume min', Options.units_volume[
                self.params.options.units]))  # TODO: softcode

        # Pipes
        self.parent.lbl_pipe_demand.setText(
            pre_l('Demand', Options.units_flow[self.params.options.units]
                  [0]))  # TODO: softcode
        self.parent.lbl_pipe_diameter.setText(
            pre_l('Diameter', Options.units_diameter_pipes[
                self.params.options.units]))  # TODO: softcode
        self.parent.lbl_pipe_roughness_val.setText(
            pre_l(
                'Value', Options.units_roughness[self.params.options.units][
                    self.params.options.headloss]))  # TODO: softcode

        self.params.options.headloss_units = self.cbo_headloss.itemData(
            self.cbo_headloss.currentIndex())

        self.parent.update_roughness_params(
            self.parent.cbo_pipe_roughness.itemData(
                self.parent.cbo_pipe_roughness.currentIndex())[
                    self.params.options.headloss])

        # self.parent.lbl_pipe_roughness.setText(
        #     pre_l(
        #         'Roughness',
        #         self.params.options.units_roughness[self.params.options.units][self.params.options.headloss_units]))

        # Pumps
        self.parent.lbl_pump_head.setText(
            pre_l('Head',
                  self.params.options.units_deltaz[self.params.options.units]))
        self.parent.lbl_pump_power.setText(
            pre_l('Power',
                  self.params.options.units_power[self.params.options.units]))

        # Valves
        valve_type = self.parent.cbo_valve_type.itemData(
            self.parent.cbo_valve_type.currentIndex())

        # Pressure valves
        if valve_type == Valve.type_psv or valve_type == Valve.type_prv or valve_type == Valve.type_pbv:
            self.parent.lbl_valve_setting.setText(
                pre_l(
                    'Pressure', self.params.options.units_pressure[
                        self.params.options.units]))
        # FCV valve: Flow
        if valve_type == Valve.type_fcv:
            self.parent.lbl_valve_setting.setText(
                pre_l('Flow', self.params.options.flow_units))
        # Throttle control valve
        elif valve_type == Valve.type_tcv:
            self.parent.lbl_valve_setting.setText(pre_l('Loss coeff.', '-'))
        # self.parent.lbl_valve_diameter.setText(pre_l('Pressure', self.params.options.units_diameter_pipes[self.params.options.units]))

        # Flow units
        units = self.cbo_flow_units.itemData(
            self.cbo_flow_units.currentIndex())
        self.parent.lbl_junction_demand.setText(pre_l('Demand',
                                                      units))  # TODO: softcode
        self.parent.lbl_pipe_demand.setText(pre_l('Demand',
                                                  units))  # TODO: softcode

        self.setVisible(False)

    def check_params(self):

        if self.chk_hydraulics.isChecked():
            if not os.path.isfile(self.txt_hydraulics_file.text()):
                QMessageBox.warning(
                    self, Parameters.plug_in_name,
                    u'Hydraulics option slected, but no valid file specified.',
                    QMessageBox.Ok)
                return False

        return True
Beispiel #48
0
class SchemeSelector(QWidget):

    currentChanged = pyqtSignal()
    changed = pyqtSignal()

    def __init__(self, parent=None):
        super(SchemeSelector, self).__init__(parent)
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        self.label = QLabel()
        self.scheme = QComboBox()
        self.menuButton = QPushButton(flat=True)
        menu = QMenu(self.menuButton)
        self.menuButton.setMenu(menu)
        layout.addWidget(self.label)
        layout.addWidget(self.scheme)
        layout.addWidget(self.menuButton)
        layout.addStretch(1)

        # action generator
        def act(slot, icon=None):
            a = QAction(self, triggered=slot)
            self.addAction(a)
            icon and a.setIcon(icons.get(icon))
            return a

        # add action
        a = self.addAction_ = act(self.slotAdd, 'list-add')
        menu.addAction(a)

        # remove action
        a = self.removeAction = act(self.slotRemove, 'list-remove')
        menu.addAction(a)

        # rename action
        a = self.renameAction = act(self.slotRename, 'document-edit')
        menu.addAction(a)

        menu.addSeparator()

        # import action
        a = self.importAction = act(self.slotImport, 'document-open')
        menu.addAction(a)

        # export action
        a = self.exportAction = act(self.slotExport, 'document-save-as')
        menu.addAction(a)

        self.scheme.currentIndexChanged.connect(self.slotSchemeChanged)
        app.translateUI(self)

    def translateUI(self):
        self.label.setText(_("Scheme:"))
        self.menuButton.setText(_("&Menu"))
        self.addAction_.setText(_("&Add..."))
        self.removeAction.setText(_("&Remove"))
        self.renameAction.setText(_("Re&name..."))
        self.importAction.setText(_("&Import..."))
        self.exportAction.setText(_("&Export..."))

    def slotSchemeChanged(self, index):
        """Called when the Scheme combobox is changed by the user."""
        self.disableDefault(self.scheme.itemData(index) == 'default')
        self.currentChanged.emit()
        self.changed.emit()

    def disableDefault(self, val):
        self.removeAction.setDisabled(val)
        self.renameAction.setDisabled(val)

    def schemes(self):
        """Returns the list with internal names of currently available schemes."""
        return [self.scheme.itemData(i) for i in range(self.scheme.count())]

    def currentScheme(self):
        """Returns the internal name of the currently selected scheme"""
        return self.scheme.itemData(self.scheme.currentIndex())

    def insertSchemeItem(self, name, scheme):
        for i in range(1, self.scheme.count()):
            n = self.scheme.itemText(i)
            if n.lower() > name.lower():
                self.scheme.insertItem(i, name, scheme)
                break
        else:
            self.scheme.addItem(name, scheme)

    def addScheme(self, name):
        num, key = 1, 'user1'
        while key in self.schemes() or key in self._schemesToRemove:
            num += 1
            key = 'user{0}'.format(num)
        self.insertSchemeItem(name, key)
        self.scheme.setCurrentIndex(self.scheme.findData(key))
        return key

    def slotAdd(self):
        name, ok = QInputDialog.getText(
            self, app.caption(_("Add Scheme")),
            _("Please enter a name for the new scheme:"))
        if ok:
            self.addScheme(name)

    def slotRemove(self):
        index = self.scheme.currentIndex()
        scheme = self.scheme.itemData(index)
        if scheme == 'default':
            return  # default can not be removed

        self._schemesToRemove.add(scheme)
        self.scheme.removeItem(index)

    def slotRename(self):
        index = self.scheme.currentIndex()
        name = self.scheme.itemText(index)
        scheme = self.scheme.itemData(index)
        newName, ok = QInputDialog.getText(self,
                                           _("Rename"),
                                           _("New name:"),
                                           text=name)
        if ok:
            self.scheme.blockSignals(True)
            self.scheme.removeItem(index)
            self.insertSchemeItem(newName, scheme)
            self.scheme.setCurrentIndex(self.scheme.findData(scheme))
            self.scheme.blockSignals(False)
            self.changed.emit()

    def slotImport(self):
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"),
                                                  _("All Files"))
        caption = app.caption(_("dialog title", "Import color theme"))
        filename = QFileDialog.getOpenFileName(self, caption, QDir.homePath(),
                                               filetypes)
        if filename:
            self.parent().import_(filename)

    def slotExport(self):
        name = self.scheme.currentText()
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"),
                                                  _("All Files"))
        caption = app.caption(
            _("dialog title", "Export {name}").format(name=name))
        path = os.path.join(QDir.homePath(), name + '.xml')
        filename = QFileDialog.getSaveFileName(self, caption, path, filetypes)
        if filename:
            if os.path.splitext(filename)[1] != '.xml':
                filename += '.xml'
            self.parent().export(name, filename)

    def loadSettings(self, currentKey, namesGroup):
        # don't mark schemes for removal anymore
        self._schemesToRemove = set()

        s = QSettings()
        cur = s.value(currentKey, "default", type(""))

        # load the names for the shortcut schemes
        s.beginGroup(namesGroup)
        block = self.scheme.blockSignals(True)
        self.scheme.clear()
        self.scheme.addItem(_("Default"), "default")
        lst = [(s.value(key, key, type("")), key) for key in s.childKeys()]
        for name, key in sorted(lst, key=lambda f: f[0].lower()):
            self.scheme.addItem(name, key)

        # find out index
        index = self.scheme.findData(cur)
        self.disableDefault(cur == 'default')
        self.scheme.setCurrentIndex(index)
        self.scheme.blockSignals(block)
        self.currentChanged.emit()

    def saveSettings(self, currentKey, namesGroup, removePrefix=None):
        # first save new scheme names
        s = QSettings()
        s.beginGroup(namesGroup)
        for i in range(self.scheme.count()):
            if self.scheme.itemData(i) != 'default':
                s.setValue(self.scheme.itemData(i), self.scheme.itemText(i))

        for scheme in self._schemesToRemove:
            s.remove(scheme)
        s.endGroup()
        if removePrefix:
            for scheme in self._schemesToRemove:
                s.remove("{0}/{1}".format(removePrefix, scheme))
        # then save current
        scheme = self.currentScheme()
        s.setValue(currentKey, scheme)
        # clean up
        self._schemesToRemove = set()
Beispiel #49
0
class TimesDialog(QDialog):
    def __init__(self, parent, params):

        QDialog.__init__(self, parent)

        self.parent = parent
        self.params = params

        self.setMinimumWidth(min_width)

        # Build dialog
        self.setWindowTitle('Options - Times')  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.fra_form = QFrame(self)
        fra_form_lay = QFormLayout(self.fra_form)
        fra_form_lay.setContentsMargins(10, 10, 10, 10)

        self.lbl_units = QLabel('Units:')  # TODO: softocode
        self.cbo_units = QComboBox()
        fra_form_lay.addRow(self.lbl_units, self.cbo_units)

        self.lbl_duration = QLabel('Duration:')  # TODO: softocode
        self.txt_duration = QLineEdit()
        fra_form_lay.addRow(self.lbl_duration, self.txt_duration)

        self.lbl_hydraulic_timestep = QLabel(
            'Hydraulic timestep:')  # TODO: softocode
        self.txt_hydraulic_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_hydraulic_timestep,
                            self.txt_hydraulic_timestep)

        self.lbl_quality_timestep = QLabel(
            'Quality timestep:')  # TODO: softocode
        self.txt_quality_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_quality_timestep,
                            self.txt_quality_timestep)

        self.lbl_rule_timestep = QLabel('Rule timestep:')  # TODO: softocode
        self.txt_rule_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_rule_timestep, self.txt_rule_timestep)

        self.lbl_pattern_timestep = QLabel(
            'Pattern timestep:')  # TODO: softocode
        self.txt_pattern_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_pattern_timestep,
                            self.txt_pattern_timestep)

        self.lbl_pattern_start = QLabel('Pattern start:')  # TODO: softocode
        self.txt_pattern_start = QLineEdit()
        fra_form_lay.addRow(self.lbl_pattern_start, self.txt_pattern_start)

        self.lbl_report_timestep = QLabel(
            'Report timestep:')  # TODO: softocode
        self.txt_report_timestep = QLineEdit()
        fra_form_lay.addRow(self.lbl_report_timestep, self.txt_report_timestep)

        self.lbl_report_start = QLabel('Report start:')  # TODO: softocode
        self.txt_report_start = QLineEdit()
        fra_form_lay.addRow(self.lbl_report_start, self.txt_report_start)

        self.lbl_clock_time_start = QLabel(
            'Clock start time:')  # TODO: softocode
        self.txt_clock_time_start = QLineEdit()
        fra_form_lay.addRow(self.lbl_clock_time_start,
                            self.txt_clock_time_start)

        self.lbl_statistic = QLabel('Statistic:')  # TODO: softocode
        self.cbo_statistic = QComboBox()
        fra_form_lay.addRow(self.lbl_statistic, self.cbo_statistic)

        # Buttons
        self.fra_buttons = QFrame(self)
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        self.btn_Ok = QPushButton('OK')
        self.btn_Cancel = QPushButton('Cancel')
        fra_buttons_lay.addWidget(self.btn_Ok)
        fra_buttons_lay.addWidget(self.btn_Cancel)

        # Add to main
        fra_main_lay = QVBoxLayout(self)
        fra_main_lay.setContentsMargins(0, 0, 0, 0)
        fra_main_lay.addWidget(self.fra_form)
        fra_main_lay.addWidget(self.fra_buttons)

        self.setup()

    def setup(self):

        for key, text in self.params.times.unit_text.iteritems():
            self.cbo_units.addItem(text, key)

        # Buttons
        self.btn_Cancel.clicked.connect(self.btn_cancel_clicked)
        self.btn_Ok.clicked.connect(self.btn_ok_clicked)

        # Validators
        self.txt_duration.setValidator(RegExValidators.get_pos_int())

        self.txt_duration.setInputMask('0009:99')
        self.txt_duration.setValidator(RegExValidators.get_time_hs_mm())

        self.txt_hydraulic_timestep.setInputMask('009:99')
        self.txt_hydraulic_timestep.setValidator(
            RegExValidators.get_time_hs_mm())

        self.txt_quality_timestep.setInputMask('009:99')
        self.txt_quality_timestep.setValidator(
            RegExValidators.get_time_hs_mm())

        self.txt_rule_timestep.setInputMask('009:99')
        self.txt_rule_timestep.setValidator(RegExValidators.get_time_hs_mm())

        self.txt_pattern_timestep.setInputMask('009:99')
        self.txt_pattern_timestep.setValidator(
            RegExValidators.get_time_hs_mm())

        self.txt_pattern_start.setInputMask('09:99')
        self.txt_pattern_start.setValidator(RegExValidators.get_time_hh_mm())

        self.txt_report_timestep.setInputMask('009:99')
        self.txt_report_timestep.setValidator(RegExValidators.get_time_hs_mm())

        self.txt_report_start.setInputMask('09:99')
        self.txt_report_start.setValidator(RegExValidators.get_time_hh_mm())

        self.txt_clock_time_start.setInputMask('09:99')
        self.txt_clock_time_start.setValidator(
            RegExValidators.get_time_hh_mm())

        for key, text in self.params.times.stats_text.iteritems():
            self.cbo_statistic.addItem(text, key)

    def show(self):
        super(TimesDialog, self).show()

        self.cbo_units.setCurrentIndex(
            self.cbo_units.findData(self.params.times.units))
        self.txt_duration.setText(self.params.times.duration.get_as_text(4))
        self.txt_hydraulic_timestep.setText(
            self.params.times.hydraulic_timestep.get_as_text(3))
        self.txt_quality_timestep.setText(
            self.params.times.quality_timestep.get_as_text(3))
        self.txt_rule_timestep.setText(
            self.params.times.rule_timestep.get_as_text(3))
        self.txt_pattern_timestep.setText(
            self.params.times.pattern_timestep.get_as_text(3))
        self.txt_pattern_start.setText(
            self.params.times.pattern_start.get_as_text())
        self.txt_report_timestep.setText(
            self.params.times.report_timestep.get_as_text(3))
        self.txt_report_start.setText(
            self.params.times.report_start.get_as_text())
        self.txt_clock_time_start.setText(
            self.params.times.clocktime_start.get_as_text())
        self.cbo_statistic.setCurrentIndex(
            self.cbo_statistic.findData(self.params.times.statistic))

    def btn_cancel_clicked(self):
        self.setVisible(False)

    def btn_ok_clicked(self):

        # Update parameters and options
        self.params.times.units = self.cbo_units.itemData(
            self.cbo_units.currentIndex())
        self.params.times.duration = Hour.from_string(self.txt_duration.text())
        self.params.times.hydraulic_timestep = Hour.from_string(
            self.txt_hydraulic_timestep.text())
        self.params.times.quality_timestep = Hour.from_string(
            self.txt_quality_timestep.text())
        self.params.times.rule_timestep = Hour.from_string(
            self.txt_rule_timestep.text())
        self.params.times.pattern_timestep = Hour.from_string(
            self.txt_pattern_timestep.text())
        self.params.times.pattern_start = Hour.from_string(
            self.txt_pattern_start.text())
        self.params.times.report_timestep = Hour.from_string(
            self.txt_report_timestep.text())
        self.params.times.report_start = Hour.from_string(
            self.txt_report_start.text())
        self.params.times.clocktime_start = Hour.from_string(
            self.txt_clock_time_start.text())
        self.params.times.statistic = self.cbo_statistic.currentIndex()

        self.setVisible(False)
class UpdateIntervalDialog(QDialog):

    def __init__(self, parent, updater):

        QDialog.__init__(self, parent)

        self.updater = updater
        self.prop = MaeMoneyProperties.instance()
        self.setupUi()

    def setupUi(self):
        self.setWindowModality(Qt.WindowModal)

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.btnPauseUpdate = QPushButton()
        self.setPauseUpdateButtonStatus()
        self.layout.addWidget(self.btnPauseUpdate)

        self.comboBoxUpdInterval = QComboBox()
        self.comboBoxUpdInterval.addItem(self.tr("Pause update"), 0)
        self.comboBoxUpdInterval.addItem(
                self.tr("Update interval - %1s").arg(Properties.DEFAULT_UPDATE_INTERVAL),
                Properties.DEFAULT_UPDATE_INTERVAL)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 25s"), 25)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 1 min"), 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 5 min"), 5 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 15 min"), 15 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 30 min"), 30 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 45 min"), 45 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 1 hr"), 1 * 60 * 60)
        self.comboBoxUpdInterval.addItem(self.tr("Update interval - 2 hr"), 2 * 60 * 60)
        self.setCurrentComboBoxUpdInterval()
        self.setComboBoxStatus()
        self.layout.addWidget(self.comboBoxUpdInterval)

        self.btnBackToMainApp = QPushButton(self.tr("Back to Main Application"))
        self.layout.addWidget(self.btnBackToMainApp)

        self.setWindowTitle(self.tr("Update Interval"))

        self.connect(self.btnPauseUpdate, SIGNAL("clicked()"), self.pauseUpdate)
        self.connect(self.comboBoxUpdInterval, SIGNAL("activated(int)"), self.updateIntervalSelected)
        self.connect(self.btnBackToMainApp, SIGNAL("clicked()"), self.accept)

    def setCurrentComboBoxUpdInterval(self):
        curInterval = self.prop.getUpdateInterval()
        index = self.comboBoxUpdInterval.findData(curInterval)
        if index >= 0:
            self.comboBoxUpdInterval.setCurrentIndex(index)
        else:
            qWarning("Update interval of %ds is not available." %(curInterval))
            qWarning("Resetting to default of %ds" %(Properties.DEFAULT_UPDATE_INTERVAL))
            self.prop.setUpdateInterval(Properties.DEFAULT_UPDATE_INTERVAL)
            self.setCurrentComboBoxUpdInterval()

    def updateIntervalSelected(self, index):
        if self.updater is not None:
            intervalSelected = self.comboBoxUpdInterval.itemData(index).toInt()[0]
            self.prop.setUpdateInterval(intervalSelected)
            if intervalSelected == 0:
                self.pauseUpdate()
            else:
                self.updater.terminate()
                self.updater.start()
                self.updater.setUpdateInterval(intervalSelected)
                self.setPauseUpdateButtonStatus()

    def pauseUpdate(self):
        if self.updater is not None:
            self.updater.terminate()
            self.setPauseUpdateButtonStatus()
            pauseInterval = 0
            index = self.comboBoxUpdInterval.findData(pauseInterval)
            self.comboBoxUpdInterval.setCurrentIndex(index)
            self.prop.setUpdateInterval(pauseInterval)

    def setPauseUpdateButtonStatus(self):
        if self.btnPauseUpdate is not None:
            if self.updater is not None and self.updater.isRunning():
                self.btnPauseUpdate.setText(self.tr("Timer currently active. Click to pause update"))
                self.btnPauseUpdate.setEnabled(True)
            else:
                self.btnPauseUpdate.setText(self.tr("Update not running"))
                self.btnPauseUpdate.setEnabled(False)

    def setComboBoxStatus(self):
        if self.comboBoxUpdInterval is not None:
            if self.updater is None:
                self.comboBoxUpdInterval.setEnabled(False)
            else:
                self.comboBoxUpdInterval.setEnabled(True)
Beispiel #51
0
class I4CheckWindow(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setup_model()

        self.tableview = QTableView()
        self.tableview.setSelectionMode(QAbstractItemView.NoSelection)
        self.tableview.setEditTriggers(QAbstractItemView.DoubleClicked)
        self.cbdelegate = CheckBoxDelegate()
        self.tableview.setItemDelegate(self.cbdelegate)
        self.tableview.setAutoScroll(False)
        self.tableview.setModel(self.model)
        self.tableview.sortByColumn(0, Qt.AscendingOrder)
        self.adjust_headers()

        #self.model.setHeaderData(0, Qt.Horizontal, u"")
        #self.model.setHeaderData(1, Qt.Horizontal, u"Title")

        self.radio_all = QRadioButton("All")
        self.radio_all.setChecked(True)
        self.radio_need = QRadioButton("Need")
        self.connect(self.radio_all, SIGNAL("toggled(bool)"), self.set_show_all)

        label = QLabel("DB:")
        label.setFixedWidth(40)
        label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

        self.db_combo = QComboBox()
        self.populate_db_combo()
        self.connect(
            self.db_combo, SIGNAL("currentIndexChanged(int)"),
            self.db_index_changed)

        self.new_button = QPushButton("New")
        self.connect(self.new_button, SIGNAL("clicked()"), self.new_item)

        self.box = QVBoxLayout(self)
        self.box.addWidget(self.tableview)
        self.button_box = QHBoxLayout()
        self.button_box.setSpacing(0)
        self.button_box.addWidget(self.new_button)
        self.button_box.addWidget(self.radio_all)
        self.button_box.addWidget(self.radio_need)
        self.button_box.addWidget(label)
        self.button_box.addWidget(self.db_combo)
        self.box.addLayout(self.button_box)

        # self.setStyleSheet("""
        # QComboBox {
        #     font-size: 16px;
        # }
        # """)

        self.dwim_after_load()

    def dwim_after_load(self):
        if self.model.need_anything():
            self.radio_need.setChecked(True)
            return
        self.radio_all.setChecked(True)
        if self.model.model.rowCount() == 0:
            edit_index = self.model.new()
            self.tableview.setCurrentIndex(edit_index)
            self.tableview.scrollTo(edit_index)
            self.tableview.edit(edit_index)

    def adjust_headers(self):
        log.debug("adjust_sizes()")
        self.tableview.horizontalHeader().setResizeMode(0, QHeaderView.Stretch)
        self.tableview.setColumnWidth(0, 1)
        self.tableview.verticalHeader().setDefaultSectionSize(ITEM_HEIGHT)
        self.tableview.verticalHeader().hide()
        self.tableview.horizontalHeader().hide()

    def setup_model(self):
        self.model = CheckListModel()

    def new_item(self):
        index = self.model.new()
        self.tableview.setCurrentIndex(index)
        self.tableview.resizeRowToContents(index.row())
        self.tableview.scrollTo(index)
        self.tableview.edit(index)

    def set_show_all(self, show_all):
        if self.model.show_all == show_all:
            return
        self.model.set_show_all(show_all)
        self.tableview.resizeRowsToContents()

    def save(self):
        self.model.save()

    def checkout(self):
        if QMessageBox.question(
            self, "Checkout", "Are you sure you want to check out?",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == \
            QMessageBox.Yes:
            self.model.checkout()

    def reset_items(self):
        if QMessageBox.question(
            self, "Checkout", "Are you sure you want to reset the list?",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == \
            QMessageBox.Yes:
            self.model.reset_items()
            self.radio_all.setChecked(True)

    def delete_database(self):
        if QMessageBox.question(
            self, "Delete database",
            "Are you sure you want to delete the current database?",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == \
            QMessageBox.Yes:
            self.model.delete_database()
            self.populate_db_combo()
            self.dwim_after_load()

    _loading_db_combo = False

    def populate_db_combo(self):
        self._loading_db_combo = True
        try:
            self.db_combo.clear()
            for db_name in self.model.databases:
                self.db_combo.addItem(re.sub("\\.org$", "", db_name), db_name)
            self.db_combo.addItem("New database...", "")
            self.db_combo.setCurrentIndex(
                self.model.databases.index(self.model.current_db))
        finally:
            self._loading_db_combo = False

    def db_index_changed(self, index):
        if self._loading_db_combo:
            return
        db_name = str(self.db_combo.itemData(index).toPyObject())
        if db_name == self.model.current_db:
            return

        self.model.save()

        if db_name:
            self.model.load(db_name)
            self.dwim_after_load()
            return

        db_name, ok = QInputDialog.getText(
            self, "New Database", "Enter database name")
        if ok:
            if not re.match(r"^[\w-]+$", db_name):
                QMessageBox.critical(
                    self, "Error",
                    "Database name must contain only the following chars: "
                    "A-Z a-z 0-9 _ -")
                ok = False
            elif db_name in self.model.databases:
                QMessageBox.critical(
                    self, "Error", "Database '%s' already exists" % db_name)
                ok = False
        if not ok:
            self.db_combo.setCurrentIndex(
                self.model.databases.index(self.model.current_db))
            return
        db_name = str(db_name) + ".org"
        self.model.load(db_name)
        self.populate_db_combo()
        self.dwim_after_load()
class ModelerParameterDefinitionDialog(QDialog):

    PARAMETER_NUMBER = 'Number'
    PARAMETER_RASTER = 'Raster layer'
    PARAMETER_TABLE = 'Table'
    PARAMETER_VECTOR = 'Vector layer'
    PARAMETER_STRING = 'String'
    PARAMETER_BOOLEAN = 'Boolean'
    PARAMETER_TABLE_FIELD = 'Table field'
    PARAMETER_EXTENT = 'Extent'
    PARAMETER_FILE = 'File'

    # To add
    PARAMETER_MULTIPLE = 'Multiple input'
    PARAMETER_FIXED_TABLE = 'Fixed table'

    paramTypes = [
        PARAMETER_BOOLEAN,
        PARAMETER_EXTENT,
        PARAMETER_FILE,
        PARAMETER_NUMBER,
        PARAMETER_RASTER,
        PARAMETER_STRING,
        PARAMETER_TABLE,
        PARAMETER_TABLE_FIELD,
        PARAMETER_VECTOR,
    ]

    def __init__(self, alg, paramType=None, param=None):
        self.alg = alg
        self.paramType = paramType
        self.param = param
        QDialog.__init__(self)
        self.setModal(True)
        self.setupUi()

    def setupUi(self):
        self.setWindowTitle(self.tr('Parameter definition'))

        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setSpacing(40)
        self.verticalLayout.setMargin(20)

        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setSpacing(2)
        self.horizontalLayout.setMargin(0)
        self.label = QLabel(self.tr('Parameter name'))
        self.horizontalLayout.addWidget(self.label)
        self.nameTextBox = QLineEdit()
        self.horizontalLayout.addWidget(self.nameTextBox)
        self.verticalLayout.addLayout(self.horizontalLayout)

        self.horizontalLayout2 = QHBoxLayout(self)
        self.horizontalLayout2.setSpacing(2)
        self.horizontalLayout2.setMargin(0)
        self.horizontalLayout3 = QHBoxLayout(self)
        self.horizontalLayout3.setSpacing(2)
        self.horizontalLayout3.setMargin(0)

        if isinstance(self.param, Parameter):
            self.nameTextBox.setText(self.param.description)

        if self.paramType == ModelerParameterDefinitionDialog.PARAMETER_BOOLEAN or \
           isinstance(self.param, ParameterBoolean):
            self.state = QCheckBox()
            self.state.setText(self.tr('Checked'))
            self.state.setChecked(False)
            if self.param is not None:
                self.state.setChecked(True if self.param.value else False)
            self.horizontalLayout2.addWidget(self.state)
            self.verticalLayout.addLayout(self.horizontalLayout2)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE_FIELD or \
                isinstance(self.param, ParameterTableField):
            self.horizontalLayout2.addWidget(QLabel(self.tr('Parent layer')))
            self.parentCombo = QComboBox()
            idx = 0
            for param in self.alg.inputs.values():
                if isinstance(param.param, (ParameterVector, ParameterTable)):
                    self.parentCombo.addItem(param.param.description,
                                             param.param.name)
                    if self.param is not None:
                        if self.param.parent == param.param.name:
                            self.parentCombo.setCurrentIndex(idx)
                    idx += 1
            self.horizontalLayout2.addWidget(self.parentCombo)
            self.verticalLayout.addLayout(self.horizontalLayout2)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_RASTER or \
                isinstance(self.param, ParameterRaster):
            self.horizontalLayout2.addWidget(QLabel(self.tr('Required')))
            self.yesNoCombo = QComboBox()
            self.yesNoCombo.addItem(self.tr('Yes'))
            self.yesNoCombo.addItem(self.tr('No'))
            if self.param is not None:
                self.yesNoCombo.setCurrentIndex(
                    1 if self.param.optional else 0)
            self.horizontalLayout2.addWidget(self.yesNoCombo)
            self.verticalLayout.addLayout(self.horizontalLayout2)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE or \
                isinstance(self.param, ParameterTable):
            self.horizontalLayout2.addWidget(QLabel(self.tr('Required')))
            self.yesNoCombo = QComboBox()
            self.yesNoCombo.addItem(self.tr('Yes'))
            self.yesNoCombo.addItem(self.tr('No'))
            if self.param is not None:
                self.yesNoCombo.setCurrentIndex(
                    1 if self.param.optional else 0)
            self.horizontalLayout2.addWidget(self.yesNoCombo)
            self.verticalLayout.addLayout(self.horizontalLayout2)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_VECTOR or \
                isinstance(self.param, ParameterVector):
            self.horizontalLayout2.addWidget(QLabel(self.tr('Required')))
            self.yesNoCombo = QComboBox()
            self.yesNoCombo.addItem(self.tr('Yes'))
            self.yesNoCombo.addItem(self.tr('No'))
            self.horizontalLayout2.addWidget(self.yesNoCombo)
            self.horizontalLayout3.addWidget(QLabel(self.tr('Shape type')))
            self.shapetypeCombo = QComboBox()
            self.shapetypeCombo.addItem(self.tr('Any'))
            self.shapetypeCombo.addItem(self.tr('Point'))
            self.shapetypeCombo.addItem(self.tr('Line'))
            self.shapetypeCombo.addItem(self.tr('Polygon'))
            if self.param is not None:
                self.yesNoCombo.setCurrentIndex(
                    1 if self.param.optional else 0)
                self.shapetypeCombo.setCurrentIndex(self.param.shapetype[0] +
                                                    1)
            self.horizontalLayout3.addWidget(self.shapetypeCombo)
            self.verticalLayout.addLayout(self.horizontalLayout3)
            self.verticalLayout.addLayout(self.horizontalLayout2)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_MULTIPLE or \
                isinstance(self.param, ParameterMultipleInput):
            self.horizontalLayout2.addWidget(QLabel(self.tr('Mandatory')))
            self.yesNoCombo = QComboBox()
            self.yesNoCombo.addItem(self.tr('Yes'))
            self.yesNoCombo.addItem(self.tr('No'))
            self.horizontalLayout2.addWidget(self.yesNoCombo)
            self.horizontalLayout3.addWidget(QLabel(self.tr('Data type')))
            self.datatypeCombo = QComboBox()
            self.datatypeCombo.addItem(self.tr('Vector (any)'))
            self.datatypeCombo.addItem(self.tr('Vector (point)'))
            self.datatypeCombo.addItem(self.tr('Vector (line)'))
            self.datatypeCombo.addItem(self.tr('Vector (polygon)'))
            self.datatypeCombo.addItem(self.tr('Raster'))
            self.datatypeCombo.addItem(self.tr('Table'))
            if self.param is not None:
                self.yesNoCombo.setCurrentIndex(
                    1 if self.param.optional else 0)
                self.datatypeCombo.setCurrentIndex(self.param.datatype + 1)
            self.horizontalLayout3.addWidget(self.datatypeCombo)
            self.verticalLayout.addLayout(self.horizontalLayout3)
            self.verticalLayout.addLayout(self.horizontalLayout2)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_NUMBER or \
                isinstance(self.param, ParameterNumber):
            self.horizontalLayout2.addWidget(QLabel(self.tr('Min/Max values')))
            self.minTextBox = QLineEdit()
            self.maxTextBox = QLineEdit()
            if self.param is not None:
                self.minTextBox.setText(unicode(self.param.min))
                self.maxTextBox.setText(unicode(self.param.max))
            self.horizontalLayout2.addWidget(self.minTextBox)
            self.horizontalLayout2.addWidget(self.maxTextBox)
            self.verticalLayout.addLayout(self.horizontalLayout2)
            self.horizontalLayout3.addWidget(QLabel(self.tr('Default value')))
            self.defaultTextBox = QLineEdit()
            self.defaultTextBox.setText(self.tr('0'))
            if self.param is not None:
                default = self.param.default
                if self.param.isInteger:
                    default = int(math.floor(default))
                self.defaultTextBox.setText(unicode(default))
            self.horizontalLayout3.addWidget(self.defaultTextBox)
            self.verticalLayout.addLayout(self.horizontalLayout3)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_STRING or \
                isinstance(self.param, ParameterString):
            self.horizontalLayout2.addWidget(QLabel(self.tr('Default value')))
            self.defaultTextBox = QLineEdit()
            if self.param is not None:
                self.defaultTextBox.setText(self.param.default)
            self.horizontalLayout2.addWidget(self.defaultTextBox)
            self.verticalLayout.addLayout(self.horizontalLayout2)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_FILE or \
                isinstance(self.param, ParameterFile):
            self.horizontalLayout2.addWidget(QLabel(self.tr('Type')))
            self.fileFolderCombo = QComboBox()
            self.fileFolderCombo.addItem(self.tr('File'))
            self.fileFolderCombo.addItem(self.tr('Folder'))
            if self.param is not None:
                self.fileFolderCombo.setCurrentIndex(
                    1 if self.param.isFolder else 0)
            self.horizontalLayout2.addWidget(self.fileFolderCombo)
            self.verticalLayout.addLayout(self.horizontalLayout2)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName('buttonBox')
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)

        self.verticalLayout.addWidget(self.buttonBox)

        self.setLayout(self.verticalLayout)

    def okPressed(self):
        description = unicode(self.nameTextBox.text())
        if description.strip() == '':
            QMessageBox.warning(self, self.tr('Unable to define parameter'),
                                self.tr('Invalid parameter name'))
            return
        if self.param is None:
            validChars = \
                'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
            safeName = ''.join(c for c in description if c in validChars)
            name = self.paramType.upper().replace(' ', '') + '_' \
                + safeName.upper()
        else:
            name = self.param.name
        if self.paramType \
                == ModelerParameterDefinitionDialog.PARAMETER_BOOLEAN \
                or isinstance(self.param, ParameterBoolean):
            self.param = ParameterBoolean(name, description,
                                          self.state.isChecked())
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE_FIELD or \
                isinstance(self.param, ParameterTableField):
            if self.parentCombo.currentIndex() < 0:
                QMessageBox.warning(
                    self, self.tr('Unable to define parameter'),
                    self.tr('Wrong or missing parameter values'))
                return
            parent = self.parentCombo.itemData(self.parentCombo.currentIndex())
            self.param = ParameterTableField(name, description, parent)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_RASTER or \
                isinstance(self.param, ParameterRaster):
            self.param = ParameterRaster(name, description,
                                         self.yesNoCombo.currentIndex() == 1)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE or \
                isinstance(self.param, ParameterTable):
            self.param = ParameterTable(name, description,
                                        self.yesNoCombo.currentIndex() == 1)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_VECTOR or \
                isinstance(self.param, ParameterVector):
            self.param = ParameterVector(
                name, description, [self.shapetypeCombo.currentIndex() - 1],
                self.yesNoCombo.currentIndex() == 1)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_MULTIPLE or \
                isinstance(self.param, ParameterMultipleInput):
            self.param = ParameterMultipleInput(
                name, description,
                self.datatypeCombo.currentIndex() - 1,
                self.yesNoCombo.currentIndex() == 1)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_NUMBER or \
                isinstance(self.param, ParameterNumber):
            try:
                vmin = unicode(self.minTextBox.text()).strip()
                if vmin == '':
                    vmin = None
                else:
                    vmin = float(vmin)
                vmax = unicode(self.maxTextBox.text()).strip()
                if vmax == '':
                    vmax = None
                else:
                    vmax = float(vmax)
                self.param = ParameterNumber(
                    name, description, vmin, vmax,
                    unicode(self.defaultTextBox.text()))
            except:
                QMessageBox.warning(
                    self, self.tr('Unable to define parameter'),
                    self.tr('Wrong or missing parameter values'))
                return
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_STRING or \
                isinstance(self.param, ParameterString):
            self.param = ParameterString(name, description,
                                         unicode(self.defaultTextBox.text()))
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_EXTENT or \
                isinstance(self.param, ParameterExtent):
            self.param = ParameterExtent(name, description)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_FILE or \
                isinstance(self.param, ParameterFile):
            isFolder = self.fileFolderCombo.currentIndex() == 1
            self.param = ParameterFile(name, description, isFolder=isFolder)
        self.close()

    def cancelPressed(self):
        self.param = None
        self.close()
Beispiel #53
0
class AnalogIn(PluginBase):
    def __init__(self, *args):
        PluginBase.__init__(self, BrickletAnalogIn, *args)
        
        self.ai = self.device

        self.cbe_voltage = CallbackEmulator(self.ai.get_voltage,
                                            self.cb_voltage,
                                            self.increase_error_count)

        self.voltage_label = VoltageLabel('Voltage: ')
        
        self.current_value = None
        
        plot_list = [['', Qt.red, self.get_current_value]]
        self.plot_widget = PlotWidget('Voltage [mV]', plot_list)

        layout_h2 = QHBoxLayout()
        layout_h2.addStretch()
        layout_h2.addWidget(self.voltage_label)
        layout_h2.addStretch()

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h2)
        layout.addWidget(self.plot_widget)

        if self.firmware_version >= (2, 0, 1):
            self.combo_range = QComboBox()
            self.combo_range.addItem('Automatic', BrickletAnalogIn.RANGE_AUTOMATIC)
            if self.firmware_version >= (2, 0, 3):
                self.combo_range.addItem('0V - 3.30V', BrickletAnalogIn.RANGE_UP_TO_3V)
            self.combo_range.addItem('0V - 6.05V', BrickletAnalogIn.RANGE_UP_TO_6V)
            self.combo_range.addItem('0V - 10.32V', BrickletAnalogIn.RANGE_UP_TO_10V)
            self.combo_range.addItem('0V - 36.30V', BrickletAnalogIn.RANGE_UP_TO_36V)
            self.combo_range.addItem('0V - 45.00V', BrickletAnalogIn.RANGE_UP_TO_45V)
            self.combo_range.currentIndexChanged.connect(self.range_changed)

            layout_h1 = QHBoxLayout()
            layout_h1.addStretch()
            layout_h1.addWidget(QLabel('Range:'))
            layout_h1.addWidget(self.combo_range)

            if self.firmware_version >= (2, 0, 3):
                self.spin_average = QSpinBox()
                self.spin_average.setMinimum(0)
                self.spin_average.setMaximum(255)
                self.spin_average.setSingleStep(1)
                self.spin_average.setValue(50)
                self.spin_average.editingFinished.connect(self.spin_average_finished)

                layout_h1.addStretch()
                layout_h1.addWidget(QLabel('Average Length:'))
                layout_h1.addWidget(self.spin_average)

            layout_h1.addStretch()
            layout.addLayout(layout_h1)

    def get_range_async(self, range_):
        self.combo_range.setCurrentIndex(self.combo_range.findData(range_))

    def get_averaging_async(self, average):
        self.spin_average.setValue(average)

    def start(self):
        if self.firmware_version >= (2, 0, 1):
            async_call(self.ai.get_range, None, self.get_range_async, self.increase_error_count)
        if self.firmware_version >= (2, 0, 3):
            async_call(self.ai.get_averaging, None, self.get_averaging_async, self.increase_error_count)
        async_call(self.ai.get_voltage, None, self.cb_voltage, self.increase_error_count)
        self.cbe_voltage.set_period(100)
        
        self.plot_widget.stop = False
        
    def stop(self):
        self.cbe_voltage.set_period(0)
        
        self.plot_widget.stop = True

    def destroy(self):
        pass

    def get_url_part(self):
        return 'analog_in'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletAnalogIn.DEVICE_IDENTIFIER

    def get_current_value(self):
        return self.current_value

    def cb_voltage(self, voltage):
        self.current_value = voltage
        self.voltage_label.setText(str(voltage/1000.0))

    def range_changed(self, index):
        if index >= 0 and self.firmware_version >= (2, 0, 1):
            range_ = self.combo_range.itemData(index)
            async_call(self.ai.set_range, range_, None, self.increase_error_count)

    def spin_average_finished(self):
        self.ai.set_averaging(self.spin_average.value())
class ModelerParameterDefinitionDialog(QDialog):

    PARAMETER_NUMBER = 'Number'
    PARAMETER_RASTER = 'Raster layer'
    PARAMETER_TABLE = 'Table'
    PARAMETER_VECTOR = 'Vector layer'
    PARAMETER_STRING = 'String'
    PARAMETER_BOOLEAN = 'Boolean'
    PARAMETER_TABLE_FIELD = 'Table field'
    PARAMETER_EXTENT = 'Extent'
    PARAMETER_FILE = 'File'
    PARAMETER_POINT = 'Point'

    # To add
    PARAMETER_MULTIPLE = 'Multiple input'
    PARAMETER_FIXED_TABLE = 'Fixed table'

    paramTypes = [
        PARAMETER_BOOLEAN,
        PARAMETER_EXTENT,
        PARAMETER_FILE,
        PARAMETER_NUMBER,
        PARAMETER_RASTER,
        PARAMETER_STRING,
        PARAMETER_TABLE,
        PARAMETER_TABLE_FIELD,
        PARAMETER_VECTOR,
        PARAMETER_POINT
    ]

    def __init__(self, alg, paramType=None, param=None):
        self.alg = alg
        self.paramType = paramType
        self.param = param
        QDialog.__init__(self)
        self.setModal(True)
        self.setupUi()

    def setupUi(self):
        self.setWindowTitle(self.tr('Parameter definition'))

        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setSpacing(40)
        self.verticalLayout.setMargin(20)

        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setSpacing(2)
        self.horizontalLayout.setMargin(0)
        self.label = QLabel(self.tr('Parameter name'))
        self.horizontalLayout.addWidget(self.label)
        self.nameTextBox = QLineEdit()
        self.horizontalLayout.addWidget(self.nameTextBox)
        self.verticalLayout.addLayout(self.horizontalLayout)

        self.horizontalLayout2 = QHBoxLayout(self)
        self.horizontalLayout2.setSpacing(2)
        self.horizontalLayout2.setMargin(0)
        self.horizontalLayout3 = QHBoxLayout(self)
        self.horizontalLayout3.setSpacing(2)
        self.horizontalLayout3.setMargin(0)
        self.horizontalLayout4 = QHBoxLayout(self)
        self.horizontalLayout4.setSpacing(2)
        self.horizontalLayout4.setMargin(0)

        if isinstance(self.param, Parameter):
            self.nameTextBox.setText(self.param.description)

        if self.paramType == ModelerParameterDefinitionDialog.PARAMETER_BOOLEAN or \
           isinstance(self.param, ParameterBoolean):
            self.state = QCheckBox()
            self.state.setText(self.tr('Checked'))
            self.state.setChecked(False)
            if self.param is not None:
                self.state.setChecked(True if self.param.value else False)
            self.horizontalLayout3.addWidget(self.state)
            self.verticalLayout.addLayout(self.horizontalLayout3)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE_FIELD or \
                isinstance(self.param, ParameterTableField):
            self.horizontalLayout3.addWidget(QLabel(self.tr('Parent layer')))
            self.parentCombo = QComboBox()
            idx = 0
            for param in self.alg.inputs.values():
                if isinstance(param.param, (ParameterVector, ParameterTable)):
                    self.parentCombo.addItem(param.param.description, param.param.name)
                    if self.param is not None:
                        if self.param.parent == param.param.name:
                            self.parentCombo.setCurrentIndex(idx)
                    idx += 1
            self.horizontalLayout3.addWidget(self.parentCombo)
            self.verticalLayout.addLayout(self.horizontalLayout3)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_VECTOR or \
                isinstance(self.param, ParameterVector):
            self.horizontalLayout3.addWidget(QLabel(self.tr('Shape type')))
            self.shapetypeCombo = QComboBox()
            self.shapetypeCombo.addItem(self.tr('Any'))
            self.shapetypeCombo.addItem(self.tr('Point'))
            self.shapetypeCombo.addItem(self.tr('Line'))
            self.shapetypeCombo.addItem(self.tr('Polygon'))
            if self.param is not None:
                self.shapetypeCombo.setCurrentIndex(self.param.shapetype[0] + 1)
            self.horizontalLayout3.addWidget(self.shapetypeCombo)
            self.verticalLayout.addLayout(self.horizontalLayout3)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_MULTIPLE or \
                isinstance(self.param, ParameterMultipleInput):
            self.horizontalLayout3.addWidget(QLabel(self.tr('Data type')))
            self.datatypeCombo = QComboBox()
            self.datatypeCombo.addItem(self.tr('Vector (any)'))
            self.datatypeCombo.addItem(self.tr('Vector (point)'))
            self.datatypeCombo.addItem(self.tr('Vector (line)'))
            self.datatypeCombo.addItem(self.tr('Vector (polygon)'))
            self.datatypeCombo.addItem(self.tr('Raster'))
            self.datatypeCombo.addItem(self.tr('Table'))
            if self.param is not None:
                self.datatypeCombo.setCurrentIndex(self.param.datatype + 1)
            self.horizontalLayout3.addWidget(self.datatypeCombo)
            self.verticalLayout.addLayout(self.horizontalLayout3)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_NUMBER or \
                isinstance(self.param, ParameterNumber):
            self.horizontalLayout3.addWidget(QLabel(self.tr('Min/Max values')))
            self.minTextBox = QLineEdit()
            self.maxTextBox = QLineEdit()
            if self.param is not None:
                self.minTextBox.setText(unicode(self.param.min))
                self.maxTextBox.setText(unicode(self.param.max))
            self.horizontalLayout3.addWidget(self.minTextBox)
            self.horizontalLayout3.addWidget(self.maxTextBox)
            self.verticalLayout.addLayout(self.horizontalLayout3)
            self.horizontalLayout4.addWidget(QLabel(self.tr('Default value')))
            self.defaultTextBox = QLineEdit()
            self.defaultTextBox.setText(self.tr('0'))
            if self.param is not None:
                default = self.param.default
                if self.param.isInteger:
                    default = int(math.floor(default))
                self.defaultTextBox.setText(unicode(default))
            self.horizontalLayout4.addWidget(self.defaultTextBox)
            self.verticalLayout.addLayout(self.horizontalLayout4)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_STRING or \
                isinstance(self.param, ParameterString):
            self.horizontalLayout3.addWidget(QLabel(self.tr('Default value')))
            self.defaultTextBox = QLineEdit()
            if self.param is not None:
                self.defaultTextBox.setText(self.param.default)
            self.horizontalLayout3.addWidget(self.defaultTextBox)
            self.verticalLayout.addLayout(self.horizontalLayout3)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_FILE or \
                isinstance(self.param, ParameterFile):
            self.horizontalLayout3.addWidget(QLabel(self.tr('Type')))
            self.fileFolderCombo = QComboBox()
            self.fileFolderCombo.addItem(self.tr('File'))
            self.fileFolderCombo.addItem(self.tr('Folder'))
            if self.param is not None:
                self.fileFolderCombo.setCurrentIndex(
                    1 if self.param.isFolder else 0)
            self.horizontalLayout3.addWidget(self.fileFolderCombo)
            self.verticalLayout.addLayout(self.horizontalLayout3)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_POINT or \
                isinstance(self.param, ParameterPoint):
            self.horizontalLayout3.addWidget(QLabel(self.tr('Default value')))
            self.defaultTextBox = QLineEdit()
            if self.param is not None:
                self.defaultTextBox.setText(self.param.default)
            self.horizontalLayout3.addWidget(self.defaultTextBox)
            self.verticalLayout.addLayout(self.horizontalLayout3)

        self.horizontalLayout2.addWidget(QLabel(self.tr('Required')))
        self.yesNoCombo = QComboBox()
        self.yesNoCombo.addItem(self.tr('Yes'))
        self.yesNoCombo.addItem(self.tr('No'))
        self.horizontalLayout2.addWidget(self.yesNoCombo)
        if self.param is not None:
            self.yesNoCombo.setCurrentIndex(
                1 if self.param.optional else 0)
        self.verticalLayout.addLayout(self.horizontalLayout2)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName('buttonBox')
        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)

        self.verticalLayout.addWidget(self.buttonBox)

        self.setLayout(self.verticalLayout)

    def okPressed(self):
        description = unicode(self.nameTextBox.text())
        if description.strip() == '':
            QMessageBox.warning(self, self.tr('Unable to define parameter'),
                                self.tr('Invalid parameter name'))
            return
        if self.param is None:
            validChars = \
                'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
            safeName = ''.join(c for c in description if c in validChars)
            name = safeName.lower()
            i = 2
            while name in self.alg.inputs:
                name = safeName.lower() + str(i)
        else:
            name = self.param.name
        if self.paramType \
                == ModelerParameterDefinitionDialog.PARAMETER_BOOLEAN \
                or isinstance(self.param, ParameterBoolean):
            self.param = ParameterBoolean(name, description,
                                          self.state.isChecked())
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE_FIELD or \
                isinstance(self.param, ParameterTableField):
            if self.parentCombo.currentIndex() < 0:
                QMessageBox.warning(self, self.tr('Unable to define parameter'),
                                    self.tr('Wrong or missing parameter values'))
                return
            parent = self.parentCombo.itemData(self.parentCombo.currentIndex())
            self.param = ParameterTableField(name, description, parent)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_RASTER or \
                isinstance(self.param, ParameterRaster):
            self.param = ParameterRaster(
                name, description,
                self.yesNoCombo.currentIndex() == 1)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE or \
                isinstance(self.param, ParameterTable):
            self.param = ParameterTable(
                name, description,
                self.yesNoCombo.currentIndex() == 1)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_VECTOR or \
                isinstance(self.param, ParameterVector):
            self.param = ParameterVector(
                name, description,
                [self.shapetypeCombo.currentIndex() - 1],
                self.yesNoCombo.currentIndex() == 1)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_MULTIPLE or \
                isinstance(self.param, ParameterMultipleInput):
            self.param = ParameterMultipleInput(
                name, description,
                self.datatypeCombo.currentIndex() - 1,
                self.yesNoCombo.currentIndex() == 1)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_NUMBER or \
                isinstance(self.param, ParameterNumber):
            try:
                vmin = unicode(self.minTextBox.text()).strip()
                if vmin == '':
                    vmin = None
                else:
                    vmin = float(vmin)
                vmax = unicode(self.maxTextBox.text()).strip()
                if vmax == '':
                    vmax = None
                else:
                    vmax = float(vmax)
                self.param = ParameterNumber(name, description, vmin, vmax,
                                             unicode(self.defaultTextBox.text()))
            except:
                QMessageBox.warning(self, self.tr('Unable to define parameter'),
                                    self.tr('Wrong or missing parameter values'))
                return
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_STRING or \
                isinstance(self.param, ParameterString):
            self.param = ParameterString(name, description,
                                         unicode(self.defaultTextBox.text()))
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_EXTENT or \
                isinstance(self.param, ParameterExtent):
            self.param = ParameterExtent(name, description)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_FILE or \
                isinstance(self.param, ParameterFile):
            isFolder = self.fileFolderCombo.currentIndex() == 1
            self.param = ParameterFile(name, description, isFolder=isFolder)
        elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_POINT or \
                isinstance(self.param, ParameterPoint):
            self.param = ParameterPoint(name, description,
                                        unicode(self.defaultTextBox.text()))
        self.param.optional = self.yesNoCombo.currentIndex() == 1
        self.close()

    def cancelPressed(self):
        self.param = None
        self.close()
Beispiel #55
0
class EditDialog(QDialog):
    pagetitle = "Edit Term's Assessment"
    holdc = {}

    def __init__(self, sid, mid, parent=None):
        super(EditDialog, self).__init__(parent)
        self.sid = sid
        self.mid = mid

        displayInfo = self.pullSubjects()

        dis = self.pullOne(self.mid)

        self.l1 = QLabel("Assessment Types")
        self.le = QComboBox()
        for dd in displayInfo:
            self.le.addItem(str(dd['name']).upper(), dd['id'])

        self.le.setObjectName("name")
        #self.le.setCurrentIndex(2)

        self.l2 = QLabel("Max Score")
        self.le2 = QLineEdit()
        self.le2.setObjectName("maxscore")
        if dis:
            self.le2.setText(dis['abbrv'])
        else:
            pass

        self.pb = QPushButton()
        self.pb.setObjectName("Submit")
        self.pb.setText("Submit")

        self.pb1 = QPushButton()
        self.pb1.setObjectName("Cancel")
        self.pb1.setText("Cancel")

        layout = QFormLayout()
        layout.addRow(self.l1, self.le)
        layout.addRow(self.l2, self.le2)
        layout.addRow(self.pb1, self.pb)

        groupBox = QGroupBox('Add Assessment')
        groupBox.setLayout(layout)

        grid = QGridLayout()
        grid.addWidget(groupBox, 0, 0)
        self.setLayout(grid)
        self.connect(self.pb, SIGNAL("clicked()"),
                     lambda: self.button_click(self))
        self.connect(self.pb1, SIGNAL("clicked()"),
                     lambda: self.button_close(self))

        self.setWindowTitle(self.pagetitle)

    def pullSubjects(self):
        cn = Db()
        arr = cn.selectn('datas', '', '', {'pubID': 7})
        return arr

    def pullOne(self, b):
        cn = Db()
        arr = cn.selectn('datas', '', 1, {'id': b})
        return arr

    def button_close(self, a):
        a.close()
        self.lunchForm()

    def lunchForm(self):
        sid = self.sid
        form = TermCaDialog(sid)
        form.show()

    def button_click(self, b):
        # shost is a QString object
        b.close()
        sid = self.sid
        mid = self.mid
        s2 = self.le2.text()
        s1 = self.le.itemData(self.le.currentIndex())
        g = Db()
        try:
            if (int(s2) > 0):
                y = {'name': s1, 'abbrv': s2}
                z = {'id': mid}
                g.update('datas', y, z)

            else:
                pass
        except:
            pass

        try:
            self.lunchForm()
        except:
            pass
        try:
            self.close()
        except:
            pass
Beispiel #56
0
class StyleChooser(QWidget):

    def __init__(self, area_supported=False):
        QWidget.__init__(self)
        self._style = PlotStyle("StyleChooser Internal Style")
        self._styles = STYLES if area_supported else STYLES_LINE_ONLY

        self.setMinimumWidth(140)
        self.setMaximumHeight(25)

        layout = QHBoxLayout()
        layout.setMargin(0)
        layout.setSpacing(2)

        self.line_chooser = QComboBox()
        self.line_chooser.setToolTip("Select line style.")
        for style in self._styles:
            self.line_chooser.addItem(*style)

        self.marker_chooser = QComboBox()
        self.marker_chooser.setToolTip("Select marker style.")
        for marker in MARKERS:
            self.marker_chooser.addItem(*marker)

        self.thickness_spinner = QDoubleSpinBox()
        self.thickness_spinner.setToolTip("Line thickness")
        self.thickness_spinner.setMinimum(0.1)
        self.thickness_spinner.setDecimals(1)
        self.thickness_spinner.setSingleStep(0.1)

        self.size_spinner = QDoubleSpinBox()
        self.size_spinner.setToolTip("Marker Size")
        self.size_spinner.setMinimum(0.1)
        self.size_spinner.setDecimals(1)
        self.size_spinner.setSingleStep(0.1)

        layout.addWidget(self.line_chooser)
        layout.addWidget(self.thickness_spinner)
        layout.addWidget(self.marker_chooser)
        layout.addWidget(self.size_spinner)

        self.setLayout(layout)

        self.line_chooser.currentIndexChanged.connect(self._updateStyle)
        self.marker_chooser.currentIndexChanged.connect(self._updateStyle)
        self.thickness_spinner.valueChanged.connect(self._updateStyle)
        self.size_spinner.valueChanged.connect(self._updateStyle)

        self._updateLineStyleAndMarker(self._style.line_style, self._style.marker, self._style.width, self._style.size)
        self._layout = layout

    def getItemSizes(self):
        line_style_combo_width = self._layout.itemAt(0).sizeHint().width()
        thickness_spinner_width = self._layout.itemAt(1).sizeHint().width()
        marker_combo_width = self._layout.itemAt(2).sizeHint().width()
        size_spinner_width = self._layout.itemAt(3).sizeHint().width()
        return line_style_combo_width, thickness_spinner_width, marker_combo_width, size_spinner_width

    def _findLineStyleIndex(self, line_style):
        for index, style in enumerate(self._styles):
            if style[1] == line_style:
                return index
            elif style[1] is None and line_style == "":
                return index
        return -1

    def _findMarkerStyleIndex(self, marker):
        for index, style in enumerate(MARKERS):
            if style[1] == marker:
                return index
            elif style[1] is None and marker == "":
                return index
        return -1

    def _updateLineStyleAndMarker(self, line_style, marker, thickness, size):
        self.line_chooser.setCurrentIndex(self._findLineStyleIndex(line_style))
        self.marker_chooser.setCurrentIndex(self._findMarkerStyleIndex(marker))
        self.thickness_spinner.setValue(thickness)
        self.size_spinner.setValue(size)

    def _updateStyle(self):
        self.marker_chooser.setEnabled(self.line_chooser.currentText() != "Area")

        line_style = self.line_chooser.itemData(self.line_chooser.currentIndex())
        marker_style = self.marker_chooser.itemData(self.marker_chooser.currentIndex())
        thickness = float(self.thickness_spinner.value())
        size = float(self.size_spinner.value())

        self._style.line_style = str(line_style.toString())
        self._style.marker = str(marker_style.toString())
        self._style.width = thickness
        self._style.size = size

    def setStyle(self, style):
        """ @type style: PlotStyle """
        self._style.copyStyleFrom(style)
        self._updateLineStyleAndMarker(style.line_style, style.marker, style.width, style.size)

    def getStyle(self):
        """ @rtype: PlotStyle """
        style = PlotStyle("Generated Style from StyleChooser")
        style.copyStyleFrom(self._style)
        return style

    def createLabelLayout(self, layout=None):
        if layout is None:
            layout = QHBoxLayout()

        titles = ["Line Style", "Width", "Marker Style", "Size"]
        sizes = self.getItemSizes()
        for title, size in zip(titles, sizes):
            label = QLabel(title)
            label.setFixedWidth(size)
            layout.addWidget(label)

        return layout
Beispiel #57
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """

    def __init__(self, main_combo=False):
        super(ActionBar, self).__init__()
        self.setObjectName("actionbar")
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(1, 1, 1, 1)
        hbox.setSpacing(1)

        self.lbl_checks = QLabel('')
        self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.lbl_checks.setFixedWidth(48)
        self.lbl_checks.setVisible(False)
        hbox.addWidget(self.lbl_checks)

        self.combo = QComboBox()
        self.combo.setIconSize(QSize(16, 16))
        #model = QStandardItemModel()
        #self.combo.setModel(model)
        #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove)
        self.combo.setMaximumWidth(300)
        self.combo.setObjectName("combotab")
        self.connect(self.combo, SIGNAL("currentIndexChanged(int)"),
            self.current_changed)
        self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP)
        self.combo.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.combo, SIGNAL(
            "customContextMenuRequested(const QPoint &)"),
            self._context_menu_requested)
        hbox.addWidget(self.combo)

        self.symbols_combo = QComboBox()
        self.symbols_combo.setIconSize(QSize(16, 16))
        self.symbols_combo.setObjectName("combo_symbols")
        self.connect(self.symbols_combo, SIGNAL("activated(int)"),
            self.current_symbol_changed)
        hbox.addWidget(self.symbols_combo)

        self.code_navigator = CodeNavigator()
        hbox.addWidget(self.code_navigator)

        self._pos_text = "Line: %d, Col: %d"
        self.lbl_position = QLabel(self._pos_text % (0, 0))
        self.lbl_position.setObjectName("position")
        self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_position)

        self.btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.btn_close.setIconSize(QSize(16, 16))
        if main_combo:
            self.btn_close.setObjectName('navigation_button')
            self.btn_close.setToolTip(translations.TR_CLOSE_FILE)
            self.connect(self.btn_close, SIGNAL("clicked()"),
                self.about_to_close_file)
        else:
            self.btn_close.setObjectName('close_split')
            self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
            self.connect(self.btn_close, SIGNAL("clicked()"),
                self.close_split)
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.btn_close)

    def resizeEvent(self, event):
        super(ActionBar, self).resizeEvent(event)
        if event.size().width() < 350:
            self.symbols_combo.hide()
            self.code_navigator.hide()
            self.lbl_position.hide()
        else:
            self.symbols_combo.show()
            self.code_navigator.show()
            self.lbl_position.show()

    def add_item(self, text, neditable):
        """Add a new item to the combo and add the neditable data."""
        self.combo.addItem(text, neditable)
        self.combo.setCurrentIndex(self.combo.count() - 1)

    def get_editables(self):
        editables = []
        for index in range(self.combo.count()):
            neditable = self.combo.itemData(index)
            editables.append(neditable)
        return editables

    def add_symbols(self, symbols):
        """Add the symbols to the symbols's combo."""
        self.symbols_combo.clear()
        for symbol in symbols:
            data = symbol[1]
            if data[1] == 'f':
                icon = QIcon(":img/function")
            else:
                icon = QIcon(":img/class")
            self.symbols_combo.addItem(icon, data[0])

    def set_current_symbol(self, index):
        self.symbols_combo.setCurrentIndex(index)

    def update_item_icon(self, neditable, icon):
        index = self.combo.findData(neditable)
        self.combo.setItemIcon(index, icon)

    def update_item_text(self, neditable, text):
        index = self.combo.findData(neditable)
        self.combo.setItemText(index, text)

    def current_changed(self, index):
        """Change the current item in the combo."""
        neditable = self.combo.itemData(index)
        self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index)

    def current_symbol_changed(self, index):
        """Change the current symbol in the combo."""
        self.emit(SIGNAL("goToSymbol(int)"), index)

    def update_line_col(self, line, col):
        """Update the line and column position."""
        self.lbl_position.setText(self._pos_text % (line, col))

    def _context_menu_requested(self, point):
        """Display context menu for the combo file."""
        if self.combo.count() == 0:
            # If there is not an Editor opened, don't show the menu
            return
        menu = QMenu()
        actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT)
        actionRun = menu.addAction(translations.TR_RUN_FILE)
        menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX)
        self._create_menu_syntax(menuSyntax)
        menu.addSeparator()
        actionClose = menu.addAction(translations.TR_CLOSE_FILE)
        actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES)
        actionCloseAllNotThis = menu.addAction(
            translations.TR_CLOSE_OTHER_FILES)
        menu.addSeparator()
        actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY)
        actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY)
        menu.addSeparator()
        actionCopyPath = menu.addAction(
            translations.TR_COPY_FILE_PATH_TO_CLIPBOARD)
        actionReopen = menu.addAction(translations.TR_REOPEN_FILE)
        actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR)
        if len(settings.LAST_OPENED_FILES) == 0:
            actionReopen.setEnabled(False)
        #Connect actions
        self.connect(actionSplitH, SIGNAL("triggered()"),
            lambda: self._split(False))
        self.connect(actionSplitV, SIGNAL("triggered()"),
            lambda: self._split(True))
        self.connect(actionRun, SIGNAL("triggered()"),
            self._run_this_file)
        self.connect(actionAdd, SIGNAL("triggered()"),
            self._add_to_project)
        self.connect(actionClose, SIGNAL("triggered()"),
            self.about_to_close_file)
        self.connect(actionCloseAllNotThis, SIGNAL("triggered()"),
            self._close_all_files_except_this)
        self.connect(actionCloseAll, SIGNAL("triggered()"),
            self._close_all_files)
        self.connect(actionCopyPath, SIGNAL("triggered()"),
            self._copy_file_location)
        self.connect(actionReopen, SIGNAL("triggered()"),
            self._reopen_last_tab)
        self.connect(actionUndock, SIGNAL("triggered()"),
            self._undock_editor)

        menu.exec_(QCursor.pos())

    def _create_menu_syntax(self, menuSyntax):
        """Create Menu with the list of syntax supported."""
        syntax = list(settings.SYNTAX.keys())
        syntax.sort()
        for syn in syntax:
            menuSyntax.addAction(syn)
            self.connect(menuSyntax, SIGNAL("triggered(QAction*)"),
                self._reapply_syntax)

    def _reapply_syntax(self, syntaxAction):
        #TODO
        if [self.currentIndex(), syntaxAction] != self._resyntax:
            self._resyntax = [self.currentIndex(), syntaxAction]
            self.emit(SIGNAL("syntaxChanged(QWidget, QString)"),
                self.currentWidget(), syntaxAction.text())

    def set_current_file(self, neditable):
        index = self.combo.findData(neditable)
        self.combo.setCurrentIndex(index)

    def set_current_by_index(self, index):
        self.combo.setCurrentIndex(index)

    def about_to_close_file(self, index=None):
        """Close the NFile object."""
        if index is None:
            index = self.combo.currentIndex()
        neditable = self.combo.itemData(index)
        if neditable:
            neditable.nfile.close()

    def close_split(self):
        self.emit(SIGNAL("closeSplit()"))

    def close_file(self, neditable):
        """Receive the confirmation to close the file."""
        index = self.combo.findData(neditable)
        self.combo.removeItem(index)
        return index

    def _run_this_file(self):
        """Execute the current file."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("runFile(QString)"), neditable.file_path)

    def _add_to_project(self):
        """Emit a signal to let someone handle the inclusion of the file
        inside a project."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.emit(SIGNAL("addToProject(QString)"), neditable.file_path)

    def _reopen_last_tab(self):
        self.emit(SIGNAL("reopenTab(QString)"),
            settings.LAST_OPENED_FILES.pop())
        self.emit(SIGNAL("recentTabsModified()"))

    def _undock_editor(self):
        self.emit(SIGNAL("undockEditor()"))

    def _split(self, orientation):
        self.emit(SIGNAL("splitEditor(bool)"), orientation)

    def _copy_file_location(self):
        """Copy the path of the current opened file to the clipboard."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        QApplication.clipboard().setText(neditable.file_path,
            QClipboard.Clipboard)

    def _close_all_files(self):
        """Close all the files opened."""
        for i in range(self.combo.count()):
            self.about_to_close_file(0)

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        for i in reversed(list(range(self.combo.count()))):
            ne = self.combo.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
Beispiel #58
0
class BarometerV2(COMCUPluginBase):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletBarometerV2, *args)

        self.barometer = self.device

        self.cbe_air_pressure = CallbackEmulator(
            self.barometer.get_air_pressure, self.cb_get_air_pressure,
            self.increase_error_count)

        self.cbe_altitude = CallbackEmulator(self.barometer.get_altitude,
                                             self.cb_get_altitude,
                                             self.increase_error_count)

        self.cbe_temperature = CallbackEmulator(self.barometer.get_temperature,
                                                self.cb_get_temperature,
                                                self.increase_error_count)

        self.current_altitude = None
        self.current_temperature = None
        self.current_air_pressure = None

        self.calibration = None
        self.btn_clear_graphs = QPushButton('Clear Graphs')
        self.btn_calibration = QPushButton('Calibration...')
        self.btn_calibration.clicked.connect(self.btn_calibration_clicked)

        self.lbl_temperature_value = QLabel('-')

        self.sbox_reference_air_pressure = QDoubleSpinBox()
        self.sbox_reference_air_pressure.setMinimum(260)
        self.sbox_reference_air_pressure.setMaximum(1260)
        self.sbox_reference_air_pressure.setDecimals(3)
        self.sbox_reference_air_pressure.setValue(1013.25)
        self.sbox_reference_air_pressure.setSingleStep(1)
        self.btn_use_current = QPushButton('Use Current')
        self.btn_use_current.clicked.connect(self.btn_use_current_clicked)
        self.sbox_reference_air_pressure.editingFinished.connect(
            self.sbox_reference_air_pressure_editing_finished)

        self.sbox_moving_avg_len_air_pressure = QSpinBox()
        self.sbox_moving_avg_len_air_pressure.setMinimum(1)
        self.sbox_moving_avg_len_air_pressure.setMaximum(1000)
        self.sbox_moving_avg_len_air_pressure.setSingleStep(1)
        self.sbox_moving_avg_len_air_pressure.setValue(100)
        self.sbox_moving_avg_len_air_pressure.editingFinished.connect(
            self.sbox_moving_avg_len_editing_finished)

        self.sbox_moving_avg_len_temperature = QSpinBox()
        self.sbox_moving_avg_len_temperature.setMinimum(1)
        self.sbox_moving_avg_len_temperature.setMaximum(1000)
        self.sbox_moving_avg_len_temperature.setSingleStep(1)
        self.sbox_moving_avg_len_temperature.setValue(100)
        self.sbox_moving_avg_len_temperature.editingFinished.connect(
            self.sbox_moving_avg_len_editing_finished)

        plot_config_air_pressure = [
            ('Air Pressure', Qt.red, lambda: self.current_air_pressure,
             '{:.3f} mbar (QFE)'.format)
        ]

        plot_config_altitude = [(
            'Altitude', Qt.darkGreen, lambda: self.current_altitude,
            lambda value: '{:.3f} m ({:.3f} ft)'.format(value, value / 0.3048))
                                ]

        self.plot_widget_air_pressure = PlotWidget('Air Pressure [mbar]',
                                                   plot_config_air_pressure,
                                                   self.btn_clear_graphs)

        self.plot_widget_altitude = PlotWidget('Altitude [m]',
                                               plot_config_altitude,
                                               self.btn_clear_graphs)

        self.combo_data_rate = QComboBox()
        self.combo_data_rate.addItem('Off', BrickletBarometerV2.DATA_RATE_OFF)
        self.combo_data_rate.addItem('1 Hz', BrickletBarometerV2.DATA_RATE_1HZ)
        self.combo_data_rate.addItem('10 Hz',
                                     BrickletBarometerV2.DATA_RATE_10HZ)
        self.combo_data_rate.addItem('25 Hz',
                                     BrickletBarometerV2.DATA_RATE_25HZ)
        self.combo_data_rate.addItem('50 Hz',
                                     BrickletBarometerV2.DATA_RATE_50HZ)
        self.combo_data_rate.addItem('75 Hz',
                                     BrickletBarometerV2.DATA_RATE_75HZ)
        self.combo_data_rate.currentIndexChanged.connect(
            self.new_sensor_config)

        self.combo_air_pressure_low_pass_filter = QComboBox()
        self.combo_air_pressure_low_pass_filter.addItem(
            'Off', BrickletBarometerV2.LOW_PASS_FILTER_OFF)
        self.combo_air_pressure_low_pass_filter.addItem(
            '1/9th', BrickletBarometerV2.LOW_PASS_FILTER_1_9TH)
        self.combo_air_pressure_low_pass_filter.addItem(
            '1/20th', BrickletBarometerV2.LOW_PASS_FILTER_1_20TH)
        self.combo_air_pressure_low_pass_filter.currentIndexChanged.connect(
            self.new_sensor_config)

        # Layout
        layout_h1 = QHBoxLayout()
        layout_h1.addWidget(self.plot_widget_air_pressure)
        layout_h1.addWidget(self.plot_widget_altitude)

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h1)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout.addWidget(line)

        layout_h2 = QHBoxLayout()
        layout_h2.addWidget(QLabel('Reference Air Pressure [mbar]:'))
        layout_h2.addWidget(self.sbox_reference_air_pressure)
        layout_h2.addWidget(self.btn_use_current)
        layout_h2.addStretch()
        layout_h2.addWidget(QLabel('Temperature:'))
        layout_h2.addWidget(self.lbl_temperature_value)
        layout_h2.addStretch()
        layout_h2.addWidget(self.btn_clear_graphs)

        layout.addLayout(layout_h2)

        layout_h3 = QHBoxLayout()
        layout_h3.addWidget(QLabel('Air Pressure Moving Average Length:'))
        layout_h3.addWidget(self.sbox_moving_avg_len_air_pressure)
        layout_h3.addStretch()
        layout_h3.addWidget(QLabel('Temperature Moving Average Length:'))
        layout_h3.addWidget(self.sbox_moving_avg_len_temperature)

        layout.addLayout(layout_h3)

        layout_h4 = QHBoxLayout()
        layout_h4.addWidget(QLabel('Data Rate:'))
        layout_h4.addWidget(self.combo_data_rate)
        layout_h4.addStretch()
        layout_h4.addWidget(QLabel('Air Pressure Low Pass Filter:'))
        layout_h4.addWidget(self.combo_air_pressure_low_pass_filter)
        layout_h4.addStretch()
        layout_h4.addWidget(self.btn_calibration)

        layout.addLayout(layout_h4)

    def start(self):
        async_call(self.barometer.get_air_pressure, None,
                   self.cb_get_air_pressure, self.increase_error_count)

        async_call(self.barometer.get_altitude, None, self.cb_get_altitude,
                   self.increase_error_count)

        async_call(self.barometer.get_temperature, None,
                   self.cb_get_temperature, self.increase_error_count)

        async_call(self.barometer.get_reference_air_pressure, None,
                   self.get_reference_air_pressure_async,
                   self.increase_error_count)

        async_call(self.barometer.get_moving_average_configuration, None,
                   self.get_moving_average_configuration_async,
                   self.increase_error_count)

        async_call(self.barometer.get_sensor_configuration, None,
                   self.get_sensor_configuration_async,
                   self.increase_error_count)

        self.cbe_air_pressure.set_period(50)
        self.cbe_altitude.set_period(50)
        self.cbe_temperature.set_period(100)

        self.plot_widget_air_pressure.stop = False
        self.plot_widget_altitude.stop = False

    def stop(self):
        self.cbe_air_pressure.set_period(0)
        self.cbe_altitude.set_period(0)
        self.cbe_temperature.set_period(0)

        self.plot_widget_air_pressure.stop = True
        self.plot_widget_altitude.stop = True

    def destroy(self):
        if self.calibration != None:
            self.calibration.close()

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletBarometerV2.DEVICE_IDENTIFIER

    def cb_get_air_pressure(self, air_pressure):
        self.current_air_pressure = air_pressure / 1000.0

    def cb_get_altitude(self, altitude):
        self.current_altitude = altitude / 1000.0

    def cb_get_temperature(self, temperature):
        self.current_temperature = temperature / 100.0
        self.lbl_temperature_value.setText(u'{:.2f} °C'.format(
            self.current_temperature))

    def get_reference_air_pressure_async(self, air_pressure):
        self.sbox_reference_air_pressure.setValue(air_pressure / 1000.0)

    def btn_use_current_clicked(self):
        self.barometer.set_reference_air_pressure(0)
        async_call(self.barometer.get_reference_air_pressure, None,
                   self.get_reference_air_pressure_async,
                   self.increase_error_count)

    def sbox_reference_air_pressure_editing_finished(self):
        self.barometer.set_reference_air_pressure(
            self.sbox_reference_air_pressure.value() * 1000.0)

    def get_moving_average_configuration_async(self, avg):
        m_avg_air_pressure, m_avg_temperature = avg

        self.sbox_moving_avg_len_air_pressure.setValue(m_avg_air_pressure)
        self.sbox_moving_avg_len_temperature.setValue(m_avg_temperature)

    def sbox_moving_avg_len_editing_finished(self):
        self.barometer.set_moving_average_configuration(
            self.sbox_moving_avg_len_air_pressure.value(),
            self.sbox_moving_avg_len_temperature.value())

    def get_sensor_configuration_async(self, config):
        data_rate, air_pressure_low_pass_filter = config

        self.combo_data_rate.setCurrentIndex(
            self.combo_data_rate.findData(data_rate))
        self.combo_air_pressure_low_pass_filter.setCurrentIndex(
            self.combo_air_pressure_low_pass_filter.findData(
                air_pressure_low_pass_filter))

    def new_sensor_config(self):
        data_rate = self.combo_data_rate.itemData(
            self.combo_data_rate.currentIndex())
        air_pressure_low_pass_filter = self.combo_air_pressure_low_pass_filter.itemData(
            self.combo_air_pressure_low_pass_filter.currentIndex())

        self.barometer.set_sensor_configuration(data_rate,
                                                air_pressure_low_pass_filter)

    def btn_calibration_clicked(self):
        if self.calibration == None:
            self.calibration = Calibration(self)

        self.btn_calibration.setEnabled(False)
        self.calibration.show()