Exemplo n.º 1
0
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        self.l = QHBoxLayout()
        self.layout.addLayout(self.l)

        self.l = QHBoxLayout()
        self.layout.addLayout(self.l)
        self.label = QLabel('epub tag')
        self.l.addWidget(self.label)

        self.tags = QLineEdit(self)
        self.tags.setText(prefs['tags'])
        self.l.addWidget(self.tags)
        self.label.setBuddy(self.tags)

        self.l = QHBoxLayout()
        self.layout.addLayout(self.l)
        self.label = QLabel('search result limit:')
        self.l.addWidget(self.label)

        self.search_result_count = QLineEdit(self)
        self.search_result_count.setValidator(
            QIntValidator(self.search_result_count))
        self.search_result_count.setText(prefs['search_result_count'])
        self.l.addWidget(self.search_result_count)
        self.label.setBuddy(self.search_result_count)

    def save_settings(self):
        prefs['tags'] = self.tags.text()
        prefs['search_result_count'] = self.search_result_count.text()
Exemplo n.º 2
0
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.label = QLabel("Voice")
        self.l.addWidget(self.label)

        self.voiceOptions = QComboBox()
        self.l.addWidget(self.voiceOptions)

        self.rateLabel = QLabel("Rate (-10 to 10)")
        self.l.addWidget(self.rateLabel)

        self.rateEdit = QLineEdit()
        self.rateEdit.setValidator(QIntValidator(-10, 10))
        self.rateEdit.setText(str(prefs['rate']))

        self.l.addWidget(self.rateEdit)

        self.volumeLabel = QLabel("Volume (0 to 100)")
        self.volumeEdit = QLineEdit()
        self.volumeEdit.setValidator(QIntValidator(0, 100))
        self.volumeEdit.setText(str(prefs['volume']))
        self.l.addWidget(self.volumeLabel)
        self.l.addWidget(self.volumeEdit)

        import win32com.client
        self.spVoice = win32com.client.Dispatch("SAPI.SpVoice")
        voices = self.spVoice.GetVoices("", "")

        for i in range(voices.Count):
            self.voiceOptions.addItem(voices.Item(i).GetDescription())

            if voices.Item(i).GetDescription() == prefs['voice']:
                self.voiceOptions.setCurrentIndex(i)

        self.pauseHotKey = HotkeyWidget(prefs, "pause",
                                        "Enable Pause/Play hotkey")
        self.l.addWidget(self.pauseHotKey)

        self.stopHotKey = HotkeyWidget(prefs, "stop", "Enable Stop hotkey")
        self.l.addWidget(self.stopHotKey)

        self.selectHotKey = HotkeyWidget(prefs, "select",
                                         "Enable Select Mode hotkey")
        self.l.addWidget(self.selectHotKey)

    def save_settings(self):
        from calibre_plugins.tts_ebook_viewer.hotkeys import keycodes

        prefs['voice'] = unicode(self.voiceOptions.currentText())
        prefs['rate'] = int(self.rateEdit.text())
        prefs['volume'] = int(self.volumeEdit.text())

        self.pauseHotKey.save_settings(prefs)
        self.stopHotKey.save_settings(prefs)
        self.selectHotKey.save_settings(prefs)
Exemplo n.º 3
0
class CountSelectorWidget(QWidget):
    def __init__(self, parent, minimum, maximum, initial=0):
        QWidget.__init__(self, parent)

        self._slider = QScrollBar(Qt.Horizontal, self)
        self._slider.setMinimum(minimum)
        self._slider.setMaximum(maximum)
        self._slider.setSingleStep(1)
        # self._slider.setTickInterval(1)

        self._linedit = QLineEdit(self)
        self._linedit.setValidator(QIntValidator(minimum, maximum, self))
        self._linedit.setMinimumWidth(20)

        self._layout = QHBoxLayout(self)
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.addWidget(self._slider, 4)
        self._layout.addWidget(self._linedit, 1)

        self._slider.valueChanged.connect(self._update_value)
        self._linedit.textChanged.connect(self._update_value)
        self._update_value(initial)

    valueChanged = pyqtSignal(int)

    def _update_value(self, value):
        value = int(value) if value else 0
        self.value = value
        self.valueChanged.emit(value)

    @property
    def value(self):
        return self._slider.value()

    @value.setter
    def value(self, value):
        if self._slider.value() != value:
            self._slider.setValue(value)
        self._linedit.setText(str(value))
Exemplo n.º 4
0
class ConditionEditor(QWidget):  # {{{

    ACTION_MAP = {
            'bool' : (
                    (_('is true'), 'is true',),
                    (_('is false'), 'is false'),
                    (_('is undefined'), 'is undefined')
            ),
            'ondevice' : (
                    (_('is true'), 'is set',),
                    (_('is false'), 'is not set'),
            ),
            'identifiers' : (
                (_('has id'), 'has id'),
                (_('does not have id'), 'does not have id'),
            ),
            'int' : (
                (_('is equal to'), 'eq'),
                (_('is less than'), 'lt'),
                (_('is greater than'), 'gt')
            ),
            'datetime' : (
                (_('is equal to'), 'eq'),
                (_('is less than'), 'lt'),
                (_('is greater than'), 'gt'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
                (_('is more days ago than'), 'older count days'),
                (_('is fewer days ago than'), 'count_days'),
                (_('is more days from now than'), 'newer future days'),
                (_('is fewer days from now than'), 'older future days')
            ),
            'multiple' : (
                (_('has'), 'has'),
                (_('does not have'), 'does not have'),
                (_('has pattern'), 'has pattern'),
                (_('does not have pattern'), 'does not have pattern'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
            ),
            'single'   : (
                (_('is'), 'is'),
                (_('is not'), 'is not'),
                (_('contains'), 'contains'),
                (_('does not contain'), 'does not contain'),
                (_('matches pattern'), 'matches pattern'),
                (_('does not match pattern'), 'does not match pattern'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
            ),
    }

    for x in ('float', 'rating'):
        ACTION_MAP[x] = ACTION_MAP['int']

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

        self.action_map = self.ACTION_MAP

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        texts = _('If the ___ column ___ values')
        try:
            one, two, three = texts.split('___')
        except:
            one, two, three = 'If the ', ' column ', ' value '

        self.l1 = l1 = QLabel(one)
        l.addWidget(l1, 0, 0)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 0, 1)

        self.l2 = l2 = QLabel(two)
        l.addWidget(l2, 0, 2)

        self.action_box = QComboBox(self)
        l.addWidget(self.action_box, 0, 3)

        self.l3 = l3 = QLabel(three)
        l.addWidget(l3, 0, 4)

        self.value_box = QLineEdit(self)
        l.addWidget(self.value_box, 0, 5)

        self.column_box.addItem('', '')
        for key in sorted(
                conditionable_columns(fm),
                key=lambda key: sort_key(fm[key]['name'])):
            self.column_box.addItem(fm[key]['name'], key)
        self.column_box.setCurrentIndex(0)

        self.column_box.currentIndexChanged.connect(self.init_action_box)
        self.action_box.currentIndexChanged.connect(self.init_value_box)

        for b in (self.column_box, self.action_box):
            b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
            b.setMinimumContentsLength(20)

    @dynamic_property
    def current_col(self):
        def fget(self):
            idx = self.column_box.currentIndex()
            return unicode_type(self.column_box.itemData(idx) or '')

        def fset(self, val):
            for idx in range(self.column_box.count()):
                c = unicode_type(self.column_box.itemData(idx) or '')
                if c == val:
                    self.column_box.setCurrentIndex(idx)
                    return
            raise ValueError('Column %r not found'%val)
        return property(fget=fget, fset=fset)

    @dynamic_property
    def current_action(self):
        def fget(self):
            idx = self.action_box.currentIndex()
            return unicode_type(self.action_box.itemData(idx) or '')

        def fset(self, val):
            for idx in range(self.action_box.count()):
                c = unicode_type(self.action_box.itemData(idx) or '')
                if c == val:
                    self.action_box.setCurrentIndex(idx)
                    return
            raise ValueError('Action %r not valid for current column'%val)
        return property(fget=fget, fset=fset)

    @property
    def current_val(self):
        ans = unicode_type(self.value_box.text()).strip()
        if self.current_col == 'languages':
            rmap = {lower(v):k for k, v in lang_map().iteritems()}
            ans = rmap.get(lower(ans), ans)
        return ans

    @dynamic_property
    def condition(self):

        def fget(self):
            c, a, v = (self.current_col, self.current_action,
                    self.current_val)
            if not c or not a:
                return None
            return (c, a, v)

        def fset(self, condition):
            c, a, v = condition
            if not v:
                v = ''
            v = v.strip()
            self.current_col = c
            self.current_action = a
            self.value_box.setText(v)

        return property(fget=fget, fset=fset)

    def init_action_box(self):
        self.action_box.blockSignals(True)
        self.action_box.clear()
        self.action_box.addItem('', '')
        col = self.current_col
        if col:
            m = self.fm[col]
            dt = m['datatype']
            if dt in self.action_map:
                actions = self.action_map[dt]
            else:
                if col == 'ondevice':
                    k = 'ondevice'
                elif col == 'identifiers':
                    k = 'identifiers'
                else:
                    k = 'multiple' if m['is_multiple'] else 'single'
                actions = self.action_map[k]

            for text, key in actions:
                self.action_box.addItem(text, key)
        self.action_box.setCurrentIndex(0)
        self.action_box.blockSignals(False)
        self.init_value_box()

    def init_value_box(self):
        self.value_box.setEnabled(True)
        self.value_box.setText('')
        self.value_box.setInputMask('')
        self.value_box.setValidator(None)
        col = self.current_col
        if not col:
            return
        action = self.current_action
        if not action:
            return
        m = self.fm[col]
        dt = m['datatype']
        tt = ''
        if col == 'identifiers':
            tt = _('Enter either an identifier type or an '
                    'identifier type and value of the form identifier:value')
        elif col == 'languages':
            tt = _('Enter a 3 letter ISO language code, like fra for French'
                    ' or deu for German or eng for English. You can also use'
                    ' the full language name, in which case calibre will try to'
                    ' automatically convert it to the language code.')
        elif dt in ('int', 'float', 'rating'):
            tt = _('Enter a number')
            v = QIntValidator if dt == 'int' else QDoubleValidator
            self.value_box.setValidator(v(self.value_box))
        elif dt == 'datetime':
            if action == 'count_days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the maximum days old the item can be. Zero is today. '
                       'Dates in the future always match')
            elif action == 'older count days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the minimum days old the item can be. Zero is today. '
                       'Dates in the future never match')
            elif action == 'older future days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the maximum days in the future the item can be. '
                       'Zero is today. Dates in the past always match')
            elif action == 'newer future days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the minimum days in the future the item can be. '
                       'Zero is today. Dates in the past never match')
            else:
                self.value_box.setInputMask('9999-99-99')
                tt = _('Enter a date in the format YYYY-MM-DD')
        else:
            tt = _('Enter a string.')
            if 'pattern' in action:
                tt = _('Enter a regular expression')
            elif m.get('is_multiple', False):
                tt += '\n' + _('You can match multiple values by separating'
                        ' them with %s')%m['is_multiple']['ui_to_list']
        self.value_box.setToolTip(tt)
        if action in ('is set', 'is not set', 'is true', 'is false',
                'is undefined'):
            self.value_box.setEnabled(False)
Exemplo n.º 5
0
class ConditionEditor(QWidget):  # {{{

    ACTION_MAP = {
            'bool' : (
                    (_('is true'), 'is true',),
                    (_('is false'), 'is false'),
                    (_('is undefined'), 'is undefined')
            ),
            'ondevice' : (
                    (_('is true'), 'is set',),
                    (_('is false'), 'is not set'),
            ),
            'identifiers' : (
                (_('has id'), 'has id'),
                (_('does not have id'), 'does not have id'),
            ),
            'int' : (
                (_('is equal to'), 'eq'),
                (_('is less than'), 'lt'),
                (_('is greater than'), 'gt')
            ),
            'datetime' : (
                (_('is equal to'), 'eq'),
                (_('is less than'), 'lt'),
                (_('is greater than'), 'gt'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
                (_('is more days ago than'), 'older count days'),
                (_('is fewer days ago than'), 'count_days'),
                (_('is more days from now than'), 'newer future days'),
                (_('is fewer days from now than'), 'older future days')
            ),
            'multiple' : (
                (_('has'), 'has'),
                (_('does not have'), 'does not have'),
                (_('has pattern'), 'has pattern'),
                (_('does not have pattern'), 'does not have pattern'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
            ),
            'single'   : (
                (_('is'), 'is'),
                (_('is not'), 'is not'),
                (_('matches pattern'), 'matches pattern'),
                (_('does not match pattern'), 'does not match pattern'),
                (_('is set'), 'is set'),
                (_('is not set'), 'is not set'),
            ),
    }

    for x in ('float', 'rating'):
        ACTION_MAP[x] = ACTION_MAP['int']

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

        self.action_map = self.ACTION_MAP

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        texts = _('If the ___ column ___ values')
        try:
            one, two, three = texts.split('___')
        except:
            one, two, three = 'If the ', ' column ', ' value '

        self.l1 = l1 = QLabel(one)
        l.addWidget(l1, 0, 0)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 0, 1)

        self.l2 = l2 = QLabel(two)
        l.addWidget(l2, 0, 2)

        self.action_box = QComboBox(self)
        l.addWidget(self.action_box, 0, 3)

        self.l3 = l3 = QLabel(three)
        l.addWidget(l3, 0, 4)

        self.value_box = QLineEdit(self)
        l.addWidget(self.value_box, 0, 5)

        self.column_box.addItem('', '')
        for key in sorted(
                conditionable_columns(fm),
                key=lambda(key): sort_key(fm[key]['name'])):
            self.column_box.addItem(fm[key]['name'], key)
        self.column_box.setCurrentIndex(0)

        self.column_box.currentIndexChanged.connect(self.init_action_box)
        self.action_box.currentIndexChanged.connect(self.init_value_box)

        for b in (self.column_box, self.action_box):
            b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
            b.setMinimumContentsLength(20)

    @dynamic_property
    def current_col(self):
        def fget(self):
            idx = self.column_box.currentIndex()
            return unicode(self.column_box.itemData(idx) or '')

        def fset(self, val):
            for idx in range(self.column_box.count()):
                c = unicode(self.column_box.itemData(idx) or '')
                if c == val:
                    self.column_box.setCurrentIndex(idx)
                    return
            raise ValueError('Column %r not found'%val)
        return property(fget=fget, fset=fset)

    @dynamic_property
    def current_action(self):
        def fget(self):
            idx = self.action_box.currentIndex()
            return unicode(self.action_box.itemData(idx) or '')

        def fset(self, val):
            for idx in range(self.action_box.count()):
                c = unicode(self.action_box.itemData(idx) or '')
                if c == val:
                    self.action_box.setCurrentIndex(idx)
                    return
            raise ValueError('Action %r not valid for current column'%val)
        return property(fget=fget, fset=fset)

    @property
    def current_val(self):
        ans = unicode(self.value_box.text()).strip()
        if self.current_col == 'languages':
            rmap = {lower(v):k for k, v in lang_map().iteritems()}
            ans = rmap.get(lower(ans), ans)
        return ans

    @dynamic_property
    def condition(self):

        def fget(self):
            c, a, v = (self.current_col, self.current_action,
                    self.current_val)
            if not c or not a:
                return None
            return (c, a, v)

        def fset(self, condition):
            c, a, v = condition
            if not v:
                v = ''
            v = v.strip()
            self.current_col = c
            self.current_action = a
            self.value_box.setText(v)

        return property(fget=fget, fset=fset)

    def init_action_box(self):
        self.action_box.blockSignals(True)
        self.action_box.clear()
        self.action_box.addItem('', '')
        col = self.current_col
        if col:
            m = self.fm[col]
            dt = m['datatype']
            if dt in self.action_map:
                actions = self.action_map[dt]
            else:
                if col == 'ondevice':
                    k = 'ondevice'
                elif col == 'identifiers':
                    k = 'identifiers'
                else:
                    k = 'multiple' if m['is_multiple'] else 'single'
                actions = self.action_map[k]

            for text, key in actions:
                self.action_box.addItem(text, key)
        self.action_box.setCurrentIndex(0)
        self.action_box.blockSignals(False)
        self.init_value_box()

    def init_value_box(self):
        self.value_box.setEnabled(True)
        self.value_box.setText('')
        self.value_box.setInputMask('')
        self.value_box.setValidator(None)
        col = self.current_col
        if not col:
            return
        action = self.current_action
        if not action:
            return
        m = self.fm[col]
        dt = m['datatype']
        tt = ''
        if col == 'identifiers':
            tt = _('Enter either an identifier type or an '
                    'identifier type and value of the form identifier:value')
        elif col == 'languages':
            tt = _('Enter a 3 letter ISO language code, like fra for French'
                    ' or deu for German or eng for English. You can also use'
                    ' the full language name, in which case calibre will try to'
                    ' automatically convert it to the language code.')
        elif dt in ('int', 'float', 'rating'):
            tt = _('Enter a number')
            v = QIntValidator if dt == 'int' else QDoubleValidator
            self.value_box.setValidator(v(self.value_box))
        elif dt == 'datetime':
            if action == 'count_days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the maximum days old the item can be. Zero is today. '
                       'Dates in the future always match')
            elif action == 'older count days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the minimum days old the item can be. Zero is today. '
                       'Dates in the future never match')
            elif action == 'older future days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the maximum days in the future the item can be. '
                       'Zero is today. Dates in the past always match')
            elif action == 'newer future days':
                self.value_box.setValidator(QIntValidator(self.value_box))
                tt = _('Enter the minimum days in the future the item can be. '
                       'Zero is today. Dates in the past never match')
            else:
                self.value_box.setInputMask('9999-99-99')
                tt = _('Enter a date in the format YYYY-MM-DD')
        else:
            tt = _('Enter a string.')
            if 'pattern' in action:
                tt = _('Enter a regular expression')
            elif m.get('is_multiple', False):
                tt += '\n' + _('You can match multiple values by separating'
                        ' them with %s')%m['is_multiple']['ui_to_list']
        self.value_box.setToolTip(tt)
        if action in ('is set', 'is not set', 'is true', 'is false',
                'is undefined'):
            self.value_box.setEnabled(False)
Exemplo n.º 6
0
class OperationsPanel(QScrollArea):
    def __init__(self):
        super().__init__()

        self.app_state = AppState()
        self.setWidgetResizable(True)
        self.initUI()

    def initUI(self):
        self.container = QToolBox()
        self.setWidget(self.container)

        self.b_save_edit = QPushButton("Save current edit")
        self.b_save_edit.clicked.connect(self._applySaveEdit)
        self.container.addItem(OptionBox([self.b_save_edit]), "Save")

        self.tf_importance_point_count = QLineEdit()
        self.tf_importance_point_count.setPlaceholderText(
            "Number of Points to Sample")
        self.tf_importance_point_count.setValidator(
            QIntValidator(1, 1000000, self))
        self.b_importance_apply = QPushButton("Apply Sampling")
        self.b_importance_apply.clicked.connect(
            self._applyFaceImportanceSampling)
        self.container.addItem(
            OptionBox(
                [self.tf_importance_point_count, self.b_importance_apply]),
            "Importance Sampling (Mesh)")

        self.tf_poisson_point_count = QLineEdit()
        self.tf_poisson_point_count.setPlaceholderText(
            "Number of Points to Sample")
        self.tf_poisson_point_count.setValidator(
            QIntValidator(1, 1000000, self))
        self.tf_poisson_radius = QLineEdit()
        self.tf_poisson_radius.setPlaceholderText(
            "Radius of the poisson disks")
        self.tf_poisson_radius.setValidator(QDoubleValidator(
            0.0, 2.0, 5, self))
        self.b_poisson_apply = QPushButton("Apply Sampling")
        self.b_poisson_apply.clicked.connect(self._applyPoissonDiskSampling)
        self.container.addItem(
            OptionBox([
                self.tf_poisson_point_count, self.tf_poisson_radius,
                self.b_poisson_apply
            ]), "Poisson Sampling (Mesh)")

        self.tf_montecarlo_point_count = QLineEdit()
        self.tf_montecarlo_point_count.setPlaceholderText(
            "Number of Points to Sample")
        self.tf_montecarlo_point_count.setValidator(
            QIntValidator(1, 1000000, self))
        self.b_montecarlo_apply = QPushButton("Apply Sampling")
        self.b_montecarlo_apply.clicked.connect(self._applyMontecarloSampling)
        self.container.addItem(
            OptionBox(
                [self.tf_montecarlo_point_count, self.b_montecarlo_apply]),
            "Montecarlo Sampling (Mesh)")

        self.tf_centroid_count = QLineEdit()
        self.tf_centroid_count.setPlaceholderText("Centroid Count")
        self.tf_centroid_count.setValidator(QIntValidator(1, 1000000, self))
        self.b_show_centroids = QPushButton("Apply FPS")
        self.b_show_centroids.clicked.connect(self._applyFPS)
        self.container.addItem(
            OptionBox([self.tf_centroid_count, self.b_show_centroids]),
            "FPS Sampling (Point)")

        self.tf_show_pp2_centroids = QLineEdit()
        self.tf_show_pp2_centroids.setPlaceholderText("Number of Centroids")
        self.tf_show_pp2_centroids.setValidator(QIntValidator(
            1, 1000000, self))
        self.tf_show_pp2_centroids_with_ball = QLineEdit()
        self.tf_show_pp2_centroids_with_ball.setPlaceholderText(
            "Number of Centroids with plotted radius")
        self.tf_show_pp2_centroids_with_ball.setValidator(
            QIntValidator(1, 1000000, self))
        self.tf_show_pp2_radius = QLineEdit()
        self.tf_show_pp2_radius.setPlaceholderText(
            "Radius of the neighbour area")
        self.tf_show_pp2_radius.setValidator(
            QDoubleValidator(0.0, 2.0, 5, self))
        self.b_show_pp2_step = QPushButton("Apply Sampling")
        self.b_show_pp2_step.clicked.connect(self._show_pp2_step)
        self.container.addItem(
            OptionBox([
                self.tf_show_pp2_centroids,
                self.tf_show_pp2_centroids_with_ball, self.tf_show_pp2_radius,
                self.b_show_pp2_step
            ]), "Show PointNet2 sampling")

    #Event Handlers
    def _applyFPS(self, event):
        item = self.app_state.current_item
        if (item is None or item.data is None):
            return

        if (item.type != item.TypePointCloud):
            self.app_state.showError(
                'This operation can only be applyed to a Point Clouds.')
            return

        if (len(self.tf_centroid_count.text()) <= 0):
            return

        count = int(self.tf_centroid_count.text())
        rateo = count / item.data.pos.size(0)
        if (rateo >= 1):
            self.app_state.showError(
                'The number of point to select with FPS({}) have to be less than the total number of points({}).'
                .format(count, item.data.pos.size(0)))
            return

        item.data.pos = item.data.pos.double()
        idx = FPS(item.data.pos,
                  torch.zeros(item.data.pos.size(0)).long(), rateo)

        new_item = Item(name='{}-FPS'.format(item.name),
                        data=Data(pos=item.data.pos[idx]),
                        type=Item.TypePointCloud)
        self.app_state.setNewItem(new_item)

    def _applyPoissonDiskSampling(self, event):
        item = self.app_state.current_item
        if (item is None or item.data is None):
            return

        if (item.type != item.TypeMesh):
            self.app_state.showError(
                'This operation can only be applyed to be a Mesh object.')
            return

        if (len(self.tf_poisson_point_count.text()) <= 0
                or len(self.tf_poisson_radius.text()) <= 0):
            return

        count = int(self.tf_poisson_point_count.text())
        radio = float(self.tf_poisson_radius.text())

        item.data.pos = item.data.pos.float()
        new_data = PoissonDiskSampling(count, radio)(item.data)
        new_item = Item(name='{}-Poisson'.format(item.name),
                        data=new_data,
                        type=Item.TypePointCloud)
        self.app_state.setNewItem(new_item)

    def _applyMontecarloSampling(self, event):
        item = self.app_state.current_item
        if (item is None or item.data is None):
            return

        if (item.type != item.TypeMesh):
            self.app_state.showError(
                'This operation can only be applyed to be a Mesh object.')
            return

        if (len(self.tf_montecarlo_point_count.text()) <= 0):
            return

        count = int(self.tf_montecarlo_point_count.text())

        item.data.pos = item.data.pos.float()
        new_data = MontecarloSampling(count)(item.data)
        new_item = Item(name='{}-Montecarlo'.format(item.name),
                        data=new_data,
                        type=Item.TypePointCloud)
        self.app_state.setNewItem(new_item)

    def _applyFaceImportanceSampling(self, event):
        item = self.app_state.current_item
        if (item is None or item.data is None):
            return

        if (item.type != item.TypeMesh):
            self.app_state.showError(
                'This operation can only be applyed to be a Mesh object.')
            return

        if (len(self.tf_importance_point_count.text()) <= 0):
            return

        count = int(self.tf_importance_point_count.text())

        item.data.pos = item.data.pos.float()
        new_data = SamplePoints(count)(item.data)
        new_item = Item(name='{}-ImportanceSamped'.format(item.name),
                        data=new_data,
                        type=Item.TypePointCloud)
        self.app_state.setNewItem(new_item)

    def _show_pp2_step(self, event):
        item = self.app_state.current_item
        if (item is None or item.data is None):
            return

        if (item.type != item.TypePointCloud):
            self.app_state.showError(
                'This operation can only be applyed to a Point Clouds.')
            return

        if (len(self.tf_show_pp2_centroids.text()) <= 0
                or len(self.tf_show_pp2_centroids_with_ball.text()) <= 0):
            return

        count = int(self.tf_show_pp2_centroids.text())
        rateo = count / item.data.pos.size(0)
        if (rateo >= 1):
            self.app_state.showError(
                'The number of point to select with FPS({}) have to be less than the total number of points({}).'
                .format(count, item.data.pos.size(0)))
            return

        with_ball = int(self.tf_show_pp2_centroids_with_ball.text())
        if (with_ball > count):
            self.app_state.showError(
                'The number of point for which plot the radius({}), have to be less than the sampled ammount({}).'
                .format(with_ball, count))
            return

        item.data.pos = item.data.pos.double()
        idx = FPS(item.data.pos,
                  torch.zeros(item.data.pos.size(0)).long(), rateo)

        radius = 0.0 if len(self.tf_show_pp2_radius.text()) <=0 \
         else float(self.tf_show_pp2_radius.text())

        render = CenterAndRadious(item.data.pos.size(0),
                                  centroids_idx=idx,
                                  centroid_to_draw=with_ball,
                                  radius=radius)

        self.app_state.setNewItem(item, render)

    def _applySaveEdit(self, event):
        sourceItem = self.app_state.current_item

        item = Item(data=sourceItem.data,
                    name=sourceItem.name,
                    type=sourceItem.type)

        self.app_state.addItem(item)
Exemplo n.º 7
0
    def request_octo_init_settings(self, wizard, method):
        vbox = QVBoxLayout()
        next_enabled = True
        label = QLabel(_("Enter a label to name your device:"))
        name = QLineEdit()
        hl = QHBoxLayout()
        hl.addWidget(label)
        hl.addWidget(name)
        hl.addStretch(1)
        vbox.addLayout(hl)

        def clean_text(widget):
            text = widget.toPlainText().strip()
            return ' '.join(text.split())

        if method in [TIM_NEW, TIM_RECOVER]:
            gb = QGroupBox()
            hbox1 = QHBoxLayout()
            gb.setLayout(hbox1)
            vbox.addWidget(gb)
            gb.setTitle(_("Select your seed length:"))
            bg_numwords = QButtonGroup()
            for i, count in enumerate([12, 18, 24]):
                rb = QRadioButton(gb)
                rb.setText(_("%d words") % count)
                bg_numwords.addButton(rb)
                bg_numwords.setId(rb, i)
                hbox1.addWidget(rb)
                rb.setChecked(True)
            cb_pin = QCheckBox(_('Enable PIN protection'))
            cb_pin.setChecked(True)
        else:
            text = QTextEdit()
            text.setMaximumHeight(60)
            if method == TIM_MNEMONIC:
                msg = _("Enter your BIP39 mnemonic:")
            else:
                msg = _("Enter the master private key beginning with xprv:")

                def set_enabled():
                    from electrum.keystore import is_xprv
                    wizard.next_button.setEnabled(is_xprv(clean_text(text)))

                text.textChanged.connect(set_enabled)
                next_enabled = False

            vbox.addWidget(QLabel(msg))
            vbox.addWidget(text)
            pin = QLineEdit()
            pin.setValidator(QRegExpValidator(QRegExp('[1-9]{0,9}')))
            pin.setMaximumWidth(100)
            hbox_pin = QHBoxLayout()
            hbox_pin.addWidget(QLabel(_("Enter your PIN (digits 1-9):")))
            hbox_pin.addWidget(pin)
            hbox_pin.addStretch(1)

        if method in [TIM_NEW, TIM_RECOVER]:
            vbox.addWidget(WWLabel(RECOMMEND_PIN))
            vbox.addWidget(cb_pin)
        else:
            vbox.addLayout(hbox_pin)

        passphrase_msg = WWLabel(PASSPHRASE_HELP_SHORT)
        passphrase_warning = WWLabel(PASSPHRASE_NOT_PIN)
        passphrase_warning.setStyleSheet("color: red")
        cb_phrase = QCheckBox(_('Enable passphrases'))
        cb_phrase.setChecked(False)
        vbox.addWidget(passphrase_msg)
        vbox.addWidget(passphrase_warning)
        vbox.addWidget(cb_phrase)

        # ask for recovery type (random word order OR matrix)
        if method == TIM_RECOVER:
            gb_rectype = QGroupBox()
            hbox_rectype = QHBoxLayout()
            gb_rectype.setLayout(hbox_rectype)
            vbox.addWidget(gb_rectype)
            gb_rectype.setTitle(_("Select recovery type:"))
            bg_rectype = QButtonGroup()

            rb1 = QRadioButton(gb_rectype)
            rb1.setText(_('Scrambled words'))
            bg_rectype.addButton(rb1)
            bg_rectype.setId(rb1, RECOVERY_TYPE_SCRAMBLED_WORDS)
            hbox_rectype.addWidget(rb1)
            rb1.setChecked(True)

            rb2 = QRadioButton(gb_rectype)
            rb2.setText(_('Matrix'))
            bg_rectype.addButton(rb2)
            bg_rectype.setId(rb2, RECOVERY_TYPE_MATRIX)
            hbox_rectype.addWidget(rb2)
        else:
            bg_rectype = None

        wizard.exec_layout(vbox, next_enabled=next_enabled)

        if method in [TIM_NEW, TIM_RECOVER]:
            item = bg_numwords.checkedId()
            pin = cb_pin.isChecked()
            recovery_type = bg_rectype.checkedId() if bg_rectype else None
        else:
            item = ' '.join(str(clean_text(text)).split())
            pin = str(pin.text())
            recovery_type = None

        return (item, name.text(), pin, cb_phrase.isChecked(), recovery_type)
Exemplo n.º 8
0
class ParameterPanel(EditionWidget, WidgetController):
    """Edition Panel implementation."""
    def __init__(self, astergui, parent=None):
        """
        Create panel.

        Arguments:
            astergui (AsterGui): AsterGui instance.
            parent (Optional[QWidget]): Parent widget.
        """
        super(ParameterPanel,
              self).__init__(parent=parent,
                             name=translate("ParameterPanel", "Edit command"),
                             astergui=astergui)
        self.setPixmap(load_pixmap("as_pic_edit_command.png"))

        self._files_model = astergui.study().dataFilesModel()
        self._unit_model = None

        self._command = None
        self.title = ParameterTitle(self)
        self.title.installEventFilter(self)
        self._name = QLineEdit(self)
        self.views = QStackedWidget(self)
        v_layout = QVBoxLayout(self)
        v_layout.setContentsMargins(0, 0, 0, 0)
        v_layout.setSpacing(5)
        v_layout.addWidget(self.title)
        v_layout.addWidget(HLine(self))

        n_layout = QHBoxLayout()
        v_layout.addLayout(n_layout)
        n_layout.addWidget(QLabel(translate("ParameterPanel", "Name"), self))
        n_layout.addWidget(self._name)
        # force to be a valid identifier + length <= 8
        self._name.setValidator(QRegExpValidator(QRegExp(r"[a-zA-Z]\w{1,7}")))

        # create toolbar
        tbar = QToolBar(self)
        tbar.setToolButtonStyle(Qt.ToolButtonIconOnly)
        # - Edit comment
        edit_comment = QAction(translate("AsterStudy", "Edit &Comment"), self)
        edit_comment.setToolTip(translate("AsterStudy", "Edit comment"))
        edit_comment.setStatusTip(
            translate("AsterStudy", "Edit comment for the "
                      "selected object"))
        edit_comment.setIcon(load_icon("as_pic_edit_comment.png"))
        connect(edit_comment.triggered, self._editComment)
        tbar.addAction(edit_comment)
        # - Switch on/off business-translations
        title = translate("AsterStudy", "Use Business-Oriented Translations")
        self.use_translations = QAction(title, self)
        title = translate("AsterStudy", "Use business-oriented translations")
        self.use_translations.setToolTip(title)
        self.use_translations.setStatusTip(title)
        self.use_translations.setIcon(load_icon("as_pic_use_translations.png"))
        self.use_translations.setCheckable(True)
        if behavior().forced_native_names:
            force = behavior().force_native_names
            self.use_translations.setDisabled(True)
            is_on = not force
        else:
            is_on = behavior().use_business_translations
        Options.use_translations = is_on
        self.use_translations.setChecked(is_on)
        connect(self.use_translations.toggled, self.updateTranslations)
        tbar.addAction(self.use_translations)
        # - Hide unused
        hide_unused = astergui.action(ActionType.HideUnused)
        connect(hide_unused.toggled, self._unusedVisibility)
        tbar.addAction(hide_unused)
        # - What's this
        whats_this = QWhatsThis.createAction(tbar)
        whats_this.setToolTip(translate("AsterStudy", "What's this?"))
        whats_this.setStatusTip(
            translate("AsterStudy", "Show element's description"))
        whats_this.setIcon(load_icon("as_pic_whats_this.png"))
        tbar.addAction(whats_this)
        # - Link to doc
        tbar.addAction(astergui.action(ActionType.LinkToDoc))

        n_layout.addWidget(tbar)

        v_layout.addWidget(self.views)
        self._updateState()

    def unitModel(self):
        """
        Method that get unit model.

        Returns:
            UnitModel: Unit model.
        """
        return self._unit_model

    def command(self):
        """
        Get command being edited.

        Returns:
            Command: Command being edited.
        """
        return self._command

    def setCommand(self, command):
        """
        Set command to edit.

        Arguments:
            command (Command): Command to edit.
        """
        self.clear()
        self._command = command
        if self._command is None:
            self._name.setText("")
        else:
            self._name.setText(self._command.name)
            self._unit_model = UnitModel(command.stage)
            pview = self._createParameterView(ParameterPath(self._command), '')
            pview.view().setItemValue(command.storage)
            hide_unused = self.astergui().action(ActionType.HideUnused)
            pview.setUnusedVisibile(not hide_unused.isChecked())
            self.views.setCurrentWidget(pview)
        self._updateState()

    def currentPath(self):
        """
        Get currently edited parameter path.

        Returns:
            str: currently edited parameter path.
        """
        path = ""
        wid = self.currentParameterView()
        if wid is not None:
            path = wid.path()
        return path

    def isCurrentCommand(self):
        """
        Get true if the currently edited view contains command.

        Returns:
            bool: Current edited command flag
        """
        curpath = self.currentPath()
        return ParameterPath(self.command()).isEqual(curpath)

    def currentParameterView(self):
        """
        Get current parameter view.

        Returns:
           ParameterView: current view.
        """
        return self.views.currentWidget()

    def clear(self):
        """Remove all parameter views."""
        while self.views.count() > 0:
            wid = self.views.widget(0)
            if wid is not None:
                self.views.removeWidget(wid)
                wid.deleteLater()

    def store(self):
        """
        Save data from all parameter views.
        """
        cmd = self.command()
        if cmd is not None:
            with auto_dupl_on(self.astergui().study().activeCase):
                cmd.rename(self._name.text())
                wid = self._viewByPath(ParameterPath(cmd))
                if wid is not None:
                    cmd.init(wid.view().itemValue())

    def requiredButtons(self):
        """
        Return the combination of standard button flags required for this
        widget.

        Returns:
            int: button flags for buttons required for this widget
                 (combination of QDialogButtonBox.StandardButton flags).
        """
        if self.isCurrentCommand():
            return QDialogButtonBox.Ok | QDialogButtonBox.Apply | \
                QDialogButtonBox.Close
        else:
            return QDialogButtonBox.Ok | QDialogButtonBox.Cancel | \
                QDialogButtonBox.Abort

    def isButtonEnabled(self, button):
        """
        Return True if a particular button is enabled.

        Arguments:
            button (QDialogButtonBox.StandardButton): button flag.

        Returns:
            True: that means that all buttons should be enabled.
        """
        return True

    def perform(self, button):
        """
        Perform action on button click. Redefined method from the base class.

        Arguments:
            button (QDialogButtonBox.StandardButton): clicked button flag.
        """
        if button == QDialogButtonBox.Ok:
            self.performOk()
        elif button == QDialogButtonBox.Apply:
            self.performApply()
        elif button == QDialogButtonBox.Abort:
            self.performAbort()
        elif button == QDialogButtonBox.Close or \
                button == QDialogButtonBox.Cancel:
            self.performClose()

    def performOk(self):
        """Called when `Ok` button is clicked in Edition panel."""
        self.performChanges(True)

    def performApply(self):
        """Called when `Apply` button is clicked in Edition panel."""
        self.performChanges(False)

    def performAbort(self):
        """Called when `Abort` button is clicked in Edition panel."""
        pref_mgr = self.astergui().preferencesMgr()
        msg = translate(
            "ParameterPanel", "Command edition will be aborted and "
            "all made changes will be lost. "
            "Do you want to continue?")
        noshow = "parampanel_abort"
        ask = MessageBox.question(self.astergui().mainWindow(),
                                  translate("ParameterPanel", "Abort"),
                                  msg,
                                  QMessageBox.Yes | QMessageBox.No,
                                  QMessageBox.Yes,
                                  noshow=noshow,
                                  prefmgr=pref_mgr)
        if ask == QMessageBox.Yes:
            self.close()
            self.astergui().study().revert()

    def performClose(self):
        """Called when `Cancel` button is clicked in Edition panel."""
        has_modif = self._hasModifications()
        if has_modif:
            pref_mgr = self.astergui().preferencesMgr()
            msg = translate(
                "ParameterPanel",
                "There are some unsaved modifications will be "
                "lost. Do you want to continue?")
            noshow = "parampanel_close"
            ask = MessageBox.question(self.astergui().mainWindow(),
                                      translate("ParameterPanel", "Close"),
                                      msg,
                                      QMessageBox.Yes | QMessageBox.No,
                                      QMessageBox.Yes,
                                      noshow=noshow,
                                      prefmgr=pref_mgr)
            has_modif = ask != QMessageBox.Yes

        if not has_modif:
            self.performDissmis(True)

    def performChanges(self, close=True):
        """
        Validate and store the command into data model.
        """
        wid = self.currentParameterView()
        if wid is not None:
            view = wid.view()
            if view.validate():
                cur_path = self.currentPath()
                if self.isCurrentCommand():
                    self.store()
                    self._files_model.update()
                    if self.astergui() is not None:
                        opname = translate("ParameterPanel", "Edit command")
                        self.astergui().study().commit(opname)
                        self.astergui().update()
                    if close:
                        self.performDissmis(False)
                    msg = translate("ParameterPanel",
                                    "Command '{}' successfully stored")
                    msg = msg.format(self._name.text())
                    self.astergui().showMessage(msg)
                else:
                    child_val = view.itemValue()
                    self._removeCurrentView()
                    curview = self.currentParameterView()
                    subitem = curview.view().findItemByPath(cur_path)
                    if subitem is not None:
                        subitem.setItemValue(child_val)
        self._updateState()
        self.updateButtonStatus()

    def performDissmis(self, revert=True):
        """
        Cancel changes and revert the command changes.
        """
        if self.isCurrentCommand():
            self.close()
            if revert:
                self.astergui().study().revert()
        else:
            self._removeCurrentView()
        self._updateState()
        self.updateButtonStatus()

    def showEvent(self, event):
        """
        Reimplemented for internal reason: updates the title
        depending on read only state, etc.
        """
        title = translate("ParameterPanel", "View command") \
            if self.isReadOnly() else \
            translate("ParameterPanel", "Edit command")
        self.setWindowTitle(title)

        hide_unused = self.astergui().action(ActionType.HideUnused)
        hide_unused.setVisible(True)
        hide_unused.setChecked(self.isReadOnly())

        # update meshview
        meshes = avail_meshes_in_cmd(self.command())
        for i, mesh in enumerate(meshes):
            filename, meshname = get_cmd_mesh(mesh)
            if filename:
                if i > 0:
                    self.meshview().displayMEDFileName(filename, meshname, 1.0,
                                                       False)
                else:
                    self.meshview().displayMEDFileName(filename, meshname, 1.0,
                                                       True)

        super(ParameterPanel, self).showEvent(event)

    def hideEvent(self, event):
        """
        Reimplemented for internal reason: hides "Hide unused" action.
        """
        hide_unused = self.astergui().action(ActionType.HideUnused)
        hide_unused.setVisible(False)
        super(ParameterPanel, self).hideEvent(event)

    def updateTranslations(self):
        """
        Update translations in GUI elements.
        """
        Options.use_translations = self.use_translations.isChecked()
        self._updateState()
        for i in xrange(self.views.count()):
            view = self.views.widget(i)
            view.updateTranslations()

    def eventFilter(self, receiver, event):
        """
        Event filter; processes clicking ln links in What's This window.
        """
        if receiver == self.title and event.type() == QEvent.WhatsThisClicked:
            QDesktopServices.openUrl(QUrl(event.href()))
        return super(ParameterPanel, self).eventFilter(receiver, event)

    def _hasModifications(self):
        curview = self.currentParameterView().view() \
            if self.currentParameterView() is not None else None
        return curview.hasModifications() \
            if curview is not None else False

    def _updateState(self):
        """Update state and current title label."""
        disabled = self.command() is None
        self.setDisabled(disabled)

        if not disabled:
            disabled = self.command().gettype(ConversionLevel.NoFail) is None
        self._name.setDisabled(disabled)

        txt = []
        pview = self.currentParameterView()
        if pview is not None:
            txt = pview.path().names()

        ppath = None
        txt_list = []
        tooltip = ""
        whats_this = ""
        while len(txt) > 0:
            name = txt.pop(0)
            if ppath is None:
                ppath = ParameterPath(self.command(), name=name)
            else:
                ppath = ppath.absolutePath(name)
            if ppath.isInSequence():
                txt_list.append("[" + name + "]")
            elif get_cata_typeid(ppath.keyword()) in (IDS.simp, IDS.fact):
                # translate keyword
                kwtext = Options.translate_command(ppath.command().title, name)
                txt_list.append(kwtext)
            elif get_cata_typeid(ppath.keyword()) == IDS.command:
                # translate command
                translation = Options.translate_command(name)
                txt_list.append(translation)
                if translation != name:
                    wttext = italic(translation) + " ({})".format(bold(name))
                else:
                    wttext = bold(name)
                tooltip = preformat(wttext)
                url = self.astergui().doc_url(name)
                if url:
                    wttext += "&nbsp;"
                    wttext += href(
                        image(CFG.rcfile("as_pic_help.png"),
                              width=20,
                              height=20), url)
                wttext = preformat(wttext)
                docs = CATA.get_command_docstring(name)
                if docs:
                    wttext += "<hr>"
                    wttext += docs
                whats_this = wttext

        self.title.setTitle(txt_list)
        self.title.setToolTip(tooltip)
        self.title.setWhatsThis(whats_this)

    def _removeCurrentView(self):
        """
        Remove the parameter view for given object.

        Arguments:
            obj (Parameter): Command's parameter.
        """
        curview = self.currentParameterView()
        if curview is not None:
            master = curview.view().masterItem()
            if master is not None and master.slaveItem() == curview.view():
                master.setSlaveItem(None)
            curview.view().setMasterItem(None)
            view = self._parentView(curview)
            if view is not None:
                self.views.setCurrentWidget(view)
                hide_unused = self.astergui().action(ActionType.HideUnused)
                view.setUnusedVisibile(not hide_unused.isChecked())
            self.views.removeWidget(curview)
            curview.deleteLater()
        self._updateState()

    def _viewByPath(self, path):
        view = None
        for i in xrange(self.views.count()):
            the_view = self.views.widget(i)
            if the_view.path().isEqual(path):
                view = the_view
                break
        return view

    def _parentView(self, curview):
        view = None
        path = curview.path()
        while path is not None and view is None:
            path = path.parentPath()
            view = self._viewByPath(path)
        return view

    def _gotoParameter(self, path, link):
        """
        Activate the parameter view for object with given id.

        Arguments:
            uid (int): Object's UID.
        """
        curview = self.currentParameterView()
        act_item = curview.view().findItemByPath(path)
        child_val = None
        wid = self._createParameterView(path, link)
        if act_item is not None:
            child_val = act_item.itemValue()
            act_item.setSlaveItem(wid.view())
        wid.view().setMasterItem(act_item)
        hide_unused = self.astergui().action(ActionType.HideUnused)
        wid.setUnusedVisibile(not hide_unused.isChecked())
        self.views.setCurrentWidget(wid)
        wid.view().setItemValue(child_val)
        self._updateState()
        self.updateButtonStatus()

    def _createParameterView(self, path, link):
        """
        Create parameter view for given object.

        Arguments:
            path (ParameterPath): Path of parameter to edit.

        Returns:
            ParameterWindow: Parameter view for parameter path.
        """
        # pragma pylint: disable=redefined-variable-type
        pview = None
        if link == EditorLink.Table:
            pview = ParameterTableWindow(path, self, self.views)
        elif link == EditorLink.List:
            pview = ParameterListWindow(path, self, self.views)
        elif link == EditorLink.GrMa:
            pview = ParameterMeshGroupWindow(path, self, self.views)
        else:
            pview = ParameterFactWindow(path, self, self.views)
        connect(pview.gotoParameter, self._gotoParameter)
        self.views.addWidget(pview)
        return pview

    def _unusedVisibility(self, ison):
        """
        Invoked when 'Hide unused' button toggled
        """
        curview = self.currentParameterView()
        curview.setUnusedVisibile(not ison)

    def meshview(self):
        """
        Returns the central *MeshView* object
        """
        return self.astergui().workSpace().panels[Panel.View]

    def _editComment(self):
        """
        Invoked when 'Edit comment' button is clicked
        """
        panel = CommentPanel(self.astergui(), owner=self)
        panel.node = self.command()
        self.astergui().workSpace().panel(Panel.Edit).setEditor(panel)

    def pendingStorage(self):
        """
        Dictionnary being filled as this command is edited.
        """
        wid = self._viewByPath(ParameterPath(self.command()))
        if wid is not None:
            return wid.view().itemValue()
        return None
class ValidatorQDialog(QDialog):
    """
        Class who create Validator QDialog to edit text in Alignak-app with regexp to validate
    """

    def __init__(self, parent=None):
        super(ValidatorQDialog, self).__init__(parent)
        self.setWindowTitle('Edit Dialog')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(250, 200)
        # Fields
        self.line_edit = QLineEdit()
        self.valid_text = QLabel()
        self.validator = QRegExpValidator()
        self.old_text = ''

    def initialize(self, title, text, regexp):
        """
        Initialize QDialog for ValidatorQDialog

        :param title: title of the QDialog
        :type title: str
        :param text: text to edit
        :type text: str
        :param regexp: regular expression to validate
        :type regexp: str
        """

        self.old_text = text
        center_widget(self)

        # Main status_layout
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)

        main_layout.addWidget(get_logo_widget(self, title))

        text_title = QLabel(_("Edit your text:"))
        text_title.setObjectName('subtitle')
        main_layout.addWidget(text_title)
        main_layout.setAlignment(text_title, Qt.AlignCenter)

        main_layout.addWidget(self.get_text_widget(regexp))

    def get_text_widget(self, regexp):
        """
        Return text QWidget with QTextEdit

        :return: text QWidget
        :rtype: QWidget
        """

        text_widget = QWidget()
        text_widget.setObjectName('dialog')
        text_layout = QVBoxLayout()
        text_widget.setLayout(text_layout)

        text_layout.addWidget(self.valid_text)

        qreg_exp = QRegExp(regexp)
        self.validator.setRegExp(qreg_exp)
        self.line_edit.setPlaceholderText(_('type your text...'))
        self.line_edit.setText(self.old_text)
        self.line_edit.setValidator(self.validator)
        self.line_edit.setFixedHeight(25)
        self.line_edit.textChanged.connect(self.check_text)
        text_layout.addWidget(self.line_edit)

        # Accept button
        accept_btn = QPushButton(_('Confirm'), self)
        accept_btn.clicked.connect(self.accept_text)
        accept_btn.setObjectName('valid')
        accept_btn.setMinimumHeight(30)
        text_layout.addWidget(accept_btn)

        return text_widget

    def check_text(self):
        """
        Valid email with ``QRegExpValidator`` and inform user

        """

        state = self.validator.validate(self.line_edit.text(), 0)[0]
        if state == QRegExpValidator.Acceptable:
            text = 'Valid email'
            color = '#27ae60'  # green
        else:
            text = 'Invalid email !'
            color = '#e67e22'  # orange

        self.valid_text.setStyleSheet('QLabel { color: %s; }' % color)
        self.valid_text.setText(text)

    def accept_text(self):  # pragma: no cover
        """
        Set Edit QDialog to Rejected or Accepted (prevent to patch for nothing)

        """

        state = self.validator.validate(self.line_edit.text(), 0)[0]
        if self.old_text == self.line_edit.text():
            self.reject()
        elif not self.old_text or self.old_text.isspace():
            if not self.line_edit.text() or self.line_edit.text().isspace():
                self.reject()
            else:
                if state == QRegExpValidator.Acceptable:
                    self.accept()
                else:
                    self.reject()
        elif not self.line_edit.text() or self.line_edit.text().isspace():
            self.line_edit.setText('')
            self.accept()
        else:
            if state == QRegExpValidator.Acceptable:
                self.accept()
            else:
                self.reject()
class ValidatorQDialog(QDialog):
    """
        Class who create Validator QDialog to edit text in Alignak-app with regexp to validate
    """
    def __init__(self, parent=None):
        super(ValidatorQDialog, self).__init__(parent)
        self.setWindowTitle('Edit Dialog')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet(settings.css_style)
        self.setWindowIcon(QIcon(settings.get_image('icon')))
        self.setObjectName('dialog')
        self.setFixedSize(250, 200)
        # Fields
        self.line_edit = QLineEdit()
        self.valid_text = QLabel()
        self.validator = QRegExpValidator()
        self.old_text = ''

    def initialize(self, title, text, regexp):
        """
        Initialize QDialog for ValidatorQDialog

        :param title: title of the QDialog
        :type title: str
        :param text: text to edit
        :type text: str
        :param regexp: regular expression to validate
        :type regexp: str
        """

        self.old_text = text
        center_widget(self)

        # Main status_layout
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(main_layout)

        main_layout.addWidget(get_logo_widget(self, title))

        text_title = QLabel(_("Edit your text:"))
        text_title.setObjectName('subtitle')
        main_layout.addWidget(text_title)
        main_layout.setAlignment(text_title, Qt.AlignCenter)

        main_layout.addWidget(self.get_text_widget(regexp))

    def get_text_widget(self, regexp):
        """
        Return text QWidget with QTextEdit

        :return: text QWidget
        :rtype: QWidget
        """

        text_widget = QWidget()
        text_widget.setObjectName('dialog')
        text_layout = QVBoxLayout()
        text_widget.setLayout(text_layout)

        text_layout.addWidget(self.valid_text)

        qreg_exp = QRegExp(regexp)
        self.validator.setRegExp(qreg_exp)
        self.line_edit.setPlaceholderText(_('type your text...'))
        self.line_edit.setText(self.old_text)
        self.line_edit.setValidator(self.validator)
        self.line_edit.setFixedHeight(25)
        self.line_edit.textChanged.connect(self.check_text)
        text_layout.addWidget(self.line_edit)

        # Accept button
        accept_btn = QPushButton(_('Confirm'), self)
        accept_btn.clicked.connect(self.accept_text)
        accept_btn.setObjectName('valid')
        accept_btn.setMinimumHeight(30)
        text_layout.addWidget(accept_btn)

        return text_widget

    def check_text(self):
        """
        Valid email with ``QRegExpValidator`` and inform user

        """

        state = self.validator.validate(self.line_edit.text(), 0)[0]
        if state == QRegExpValidator.Acceptable:
            text = 'Valid email'
            color = '#27ae60'  # green
        else:
            text = 'Invalid email !'
            color = '#e67e22'  # orange

        self.valid_text.setStyleSheet('QLabel { color: %s; }' % color)
        self.valid_text.setText(text)

    def accept_text(self):  # pragma: no cover
        """
        Set Edit QDialog to Rejected or Accepted (prevent to patch for nothing)

        """

        state = self.validator.validate(self.line_edit.text(), 0)[0]
        if self.old_text == self.line_edit.text():
            self.reject()
        elif not self.old_text or self.old_text.isspace():
            if not self.line_edit.text() or self.line_edit.text().isspace():
                self.reject()
            else:
                if state == QRegExpValidator.Acceptable:
                    self.accept()
                else:
                    self.reject()
        elif not self.line_edit.text() or self.line_edit.text().isspace():
            self.line_edit.setText('')
            self.accept()
        else:
            if state == QRegExpValidator.Acceptable:
                self.accept()
            else:
                self.reject()
Exemplo n.º 11
0
class AddBrickDialog(QDialog):
    def __init__(self, parent, modal=True, flags=Qt.WindowFlags()):
        QDialog.__init__(self, parent, flags)
        self.model = None
        self._model_dir = None
        self.setModal(modal)
        self.setWindowTitle("Add FITS brick")
        lo = QVBoxLayout(self)
        lo.setContentsMargins(10, 10, 10, 10)
        lo.setSpacing(5)
        # file selector
        self.wfile = FileSelector(self,
                                  label="FITS filename:",
                                  dialog_label="FITS file",
                                  default_suffix="fits",
                                  file_types="FITS files (*.fits *.FITS)",
                                  file_mode=QFileDialog.ExistingFile)
        lo.addWidget(self.wfile)
        # overwrite or add mode
        lo1 = QGridLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        lo1.addWidget(QLabel("Padding factor:", self), 0, 0)
        self.wpad = QLineEdit("2", self)
        self.wpad.setValidator(QDoubleValidator(self))
        lo1.addWidget(self.wpad, 0, 1)
        lo1.addWidget(QLabel("Assign source name:", self), 1, 0)
        self.wname = QLineEdit(self)
        lo1.addWidget(self.wname, 1, 1)
        # OK/cancel buttons
        lo.addSpacing(10)
        lo2 = QHBoxLayout()
        lo.addLayout(lo2)
        lo2.setContentsMargins(0, 0, 0, 0)
        lo2.setContentsMargins(5, 5, 5, 5)
        self.wokbtn = QPushButton("OK", self)
        self.wokbtn.setMinimumWidth(128)
        self.wokbtn.clicked.connect(self.accept)
        self.wokbtn.setEnabled(False)
        cancelbtn = QPushButton("Cancel", self)
        cancelbtn.setMinimumWidth(128)
        cancelbtn.clicked.connect(self.reject)
        lo2.addWidget(self.wokbtn)
        lo2.addStretch(1)
        lo2.addWidget(cancelbtn)
        self.setMinimumWidth(384)
        # signals
        self.wfile.filenameSelected.connect(self._fileSelected)
        # internal state
        self.qerrmsg = QErrorMessage(self)

    def setModel(self, model):
        self.model = model
        if model.filename():
            self._model_dir = os.path.dirname(os.path.abspath(
                model.filename()))
        else:
            self._model_dir = os.path.abspath('.')
        self.wfile.setDirectory(self._model_dir)
        self._fileSelected(self.wfile.filename(), quiet=True)

    def _fileSelected(self, filename, quiet=False):
        self.wokbtn.setEnabled(False)
        if not filename:
            return None
        # check that filename matches model
        if not os.path.samefile(self._model_dir, os.path.dirname(filename)):
            self.wfile.setFilename('')
            if not quiet:
                QMessageBox.warning(
                    self, "Directory mismatch",
                    """<P>The FITS file must reside in the same directory
          as the current sky model.</P>""")
            self.wfile.setDirectory(self._model_dir)
            return None
        # if filename is not in model already, enable the "add to model" control
        for src in self.model.sources:
            if isinstance(getattr(src, 'shape', None), ModelClasses.FITSImage):
                if os.path.exists(src.shape.filename) and os.path.samefile(
                        src.shape.filename, filename):
                    if not quiet:
                        QMessageBox.warning(
                            self, "Already in model",
                            "This FITS brick is already present in the model.")
                    self.wfile.setFilename('')
                    return None
        if not str(self.wname.text()):
            self.wname.setText(
                os.path.splitext(os.path.basename(str(filename)))[0])
        self.wokbtn.setEnabled(True)
        return filename

    def accept(self):
        """Tries to add brick, and closes the dialog if successful."""
        filename = self.wfile.filename()
        # read fits file
        busy = BusyIndicator()
        try:
            input_hdu = pyfits.open(filename)[0]
        except Exception as err:
            busy.reset_cursor()
            QMessageBox.warning(
                self, "Error reading FITS",
                "Error reading FITS file %s: %s" % (filename, str(err)))
            return
        # check name
        srcname = str(self.wname.text()) or os.path.splitext(
            os.path.basename(str(filename)))[0]
        if srcname in set([src.name for src in self.model.sources]):
            QMessageBox.warning(
                self, "Already in model",
                "<p>The model already contains a source named '%s'. Please select a different name.</p>"
                % srcname)
            return
        # get image parameters
        hdr = input_hdu.header
        max_flux = float(input_hdu.data.max())
        wcs = WCS(hdr, mode='pyfits')
        # Get reference pixel coordinates
        # wcs.getCentreWCSCoords() doesn't work, as that gives us the middle of the image
        # So scan the header to get the CRPIX values
        ra0 = dec0 = 1
        for iaxis in range(hdr['NAXIS']):
            axs = str(iaxis + 1)
            name = hdr.get('CTYPE' + axs, axs).upper()
            if name.startswith("RA"):
                ra0 = hdr.get('CRPIX' + axs, 1) - 1
            elif name.startswith("DEC"):
                dec0 = hdr.get('CRPIX' + axs, 1) - 1
        # convert pixel to degrees
        #    print ra0,dec0
        ra0, dec0 = wcs.pix2wcs(ra0, dec0)
        ra0 *= DEG
        dec0 *= DEG
        #    print ModelClasses.Position.ra_hms_static(ra0)
        #    print ModelClasses.Position.dec_sdms_static(dec0)
        sx, sy = wcs.getHalfSizeDeg()
        sx *= DEG
        sy *= DEG
        nx, ny = input_hdu.data.shape[-1:-3:-1]
        pos = ModelClasses.Position(ra0, dec0)
        flux = ModelClasses.Flux(max_flux)
        shape = ModelClasses.FITSImage(sx,
                                       sy,
                                       0,
                                       os.path.basename(filename),
                                       nx,
                                       ny,
                                       pad=float(str(self.wpad.text()) or "1"))
        img_src = SkyModel.Source(srcname, pos, flux, shape=shape)
        self.model.setSources(self.model.sources + [img_src])
        self.model.emitUpdate(SkyModel.SkyModel.UpdateAll, origin=self)
        busy.reset_cursor()
        return QDialog.accept(self)
Exemplo n.º 12
0
class MainWindowMPDJ(QMainWindow):
    """Display the main window of the application where the connections
        and other stuff is edited by the user."""
    def show(self):
        """Shows this window (maximized). I will work on a better solution."""
        QMainWindow.showMaximized(self)

    def update(self):
        """Updates the view."""
        global_properties = GlobalProperties.get_instance()
        mpdj_data = global_properties.mpdj_data
        self.tf_min_per_selection.setText(
            str(mpdj_data.min_units_per_node_touch))
        self.tf_max_per_selection.setText(
            str(mpdj_data.max_units_per_node_touch))
        self.tf_min_global_song_duration.setText(
            str(mpdj_data.global_min_song_duration))
        self.tf_max_global_song_duration.setText(
            str(mpdj_data.global_max_song_duration))
        self.cb_global_limit_overflow.setChecked(
            mpdj_data.limit_overspill_global)
        self.tf_global_node_max_overflow_minutes.setText(
            str(mpdj_data.global_node_max_overspill))
        self.tf_global_node_max_overflow_minutes.setDisabled(
            not mpdj_data.limit_overspill_global)
        text_to_find = mpdj_data.unit_per_node_touch.gui_representation()
        index = self.combo_box_minutes_or_titles.findText(
            text_to_find, Qt.MatchFixedString)
        self.combo_box_minutes_or_titles.setCurrentIndex(index)
        #        self.limit_artist_play_chk_box.setChecked(
        #            global_properties.mpdj_data.limit_artist_in_node_touch)
        self.chk_box_graph_is_directed.setChecked(mpdj_data.graph_is_directed)
        self.setWindowTitle('MPDJ: {}'.format(
            global_properties.path_of_current_file))

    def write_min_global_song_duration_to_mpdj(self):
        """Writes min global song duration to mpdj."""
        global_properties = GlobalProperties.get_instance()
        global_properties.mpdj_data.global_min_song_duration = int(
            self.tf_min_global_song_duration.text())

    def write_max_global_song_duration_to_mpdj(self):
        """Writes min global song duration to mpdj."""
        global_properties = GlobalProperties.get_instance()
        global_properties.mpdj_data.global_max_song_duration = int(
            self.tf_max_global_song_duration.text())

    def write_min_per_note_to_mpdj(self):
        """Write the selected min count per node touch to the mpdj which
            is currently worked on."""
        global_properties = GlobalProperties.get_instance()
        global_properties.mpdj_data.min_units_per_node_touch = int(
            self.tf_min_per_selection.text())

    def write_max_per_note_to_mpdj(self):
        """Writes the selected max count per node touch to the mpdj which is
            currently worked on."""
        global_properties = GlobalProperties.get_instance()
        global_properties.mpdj_data.max_units_per_node_touch = int(
            self.tf_max_per_selection.text())

    def write_unit_per_node_touch_to_mpdj(self):
        """Writes the selected unit for min and max per touch to the mpdj.
            This does not do anything at the moment. Has to be
            implemented properly"""
        global_properties = GlobalProperties.get_instance()
        selection_text = self.combo_box_minutes_or_titles.currentText()
        global_properties.mpdj_data.unit_per_node_touch = UnitPerNodeTouch[
            selection_text.upper()]

    def write_limit_artists_played_to_mpdj(self):  #
        """Write to the current mpdj if the artist are limited per
            node touch."""
        global_properties = GlobalProperties.get_instance()
        state = self.limit_artist_play_chk_box.isChecked()
        global_properties.mpdj_data.limit_artists_in_node_touch = state

    def write_limit_overspill_to_mpdj(self):
        global_properties = GlobalProperties.get_instance()
        state = self.cb_global_limit_overflow.isChecked()
        global_properties.mpdj_data.limit_overspill_global = state

    def write_global_node_max_overflow_to_mpdj(self):
        global_properties = GlobalProperties.get_instance()
        global_node_max_overflow_text = self.tf_global_node_max_overflow_minutes.text(
        )
        if global_node_max_overflow_text:
            new_max_overflow = int(global_node_max_overflow_text)
            global_properties.mpdj_data.global_node_max_overspill = new_max_overflow

    def write_graph_is_directed_to_mpdj(self):
        """Write if the graph is directed to mpd, this should be
            changed somehow, since this does only concern the editing
            of the connections."""
        global_properties = GlobalProperties.get_instance()
        state = self.chk_box_graph_is_directed.isChecked()
        global_properties.mpdj_data.graph_is_directed = state

    def file_dialog(self, load_save_type=QFileDialog.AcceptSave):
        """Opens an file save dialog and returns the selected
            filename."""
        file_save_dialog = QFileDialog(self)
        file_save_dialog.setFileMode(QFileDialog.AnyFile)
        file_save_dialog.setAcceptMode(load_save_type)
        file_save_dialog.setNameFilters(
            ["MPDJ files (*.{})".format(FILE_SUFFIX)])
        file_save_dialog.selectNameFilter(
            "MPDJ files (*.{})".format(FILE_SUFFIX))
        file_save_dialog.setDefaultSuffix((FILE_SUFFIX))
        exec_value = file_save_dialog.exec()
        if exec_value == 0:
            return None
        file_names = file_save_dialog.selectedFiles()
        if len(file_names) != 1:
            message_box = QMessageBox()
            message_box.setText('Please select only one file!')
            message_box.setWindowTitle('Save error.')
            message_box.setStandardButtons(QMessageBox.Ok)
            message_box.setIcon(QMessageBox.Information)
            message_box.exec_()
            return None
        return file_names[0]

    def file_save_as(self):
        """Saves the file. opens a file_dialog which asks for the
            filename."""
        file_name = self.file_dialog(load_save_type=QFileDialog.AcceptSave)
        if file_name:
            self.save_mpdj_data_to_file(file_name)

    def save_mpdj_data_to_file(self, p_file_name: str):
        """Saves the current mpdj data to the file by the path given
            in p_file_name."""
        try:
            global_properties = GlobalProperties.get_instance()
            global_properties.save_mpdj_data_to_file(p_file_name)
            self.statusBar().showMessage('Saved to {}'.format(p_file_name),
                                         5000)
        except (OSError, IOError) as exception:
            message_box = QMessageBox()
            message_box.setText('Error saving the file: {}'.format(
                str(exception)))
            message_box.setWindowTitle('Error saving the file.')
            message_box.setStandardButtons(QMessageBox.Ok)
            message_box.setIcon(QMessageBox.Warning)
            message_box.exec_()

    def file_save(self):
        """Saves the current mpdj data to the current file."""
        global_properties = GlobalProperties.get_instance()
        if len(global_properties.path_of_current_file) > 0:
            self.save_mpdj_data_to_file(global_properties.path_of_current_file)
        else:
            self.file_save_as()

    def file_load(self):
        """Loads mpdj data from a file. Opens a file dialog which
            asks for the file to load."""
        global_properties = GlobalProperties.get_instance()
        file_name = self.file_dialog(load_save_type=QFileDialog.AcceptOpen)
        if file_name:
            if global_properties.changes_happened_since_last_save:
                retval = show_discard_data_ok_cancel_message()
            if not global_properties.changes_happened_since_last_save or retval == QMessageBox.Ok:
                try:
                    global_properties.load_mpdjdata_from_file(file_name)
                except AttributeError as err:
                    message_box = QMessageBox()
                    message_box.setText(
                        'Error reading your MPDJ-File: {}'.format(err))
                    message_box.setWindowTitle('Load error.')
                    message_box.setStandardButtons(QMessageBox.Ok)
                    message_box.setIcon(QMessageBox.Warning)
                    message_box.exec_()

    def __init__(self):
        """Constructor"""
        QMainWindow.__init__(self)
        global_properties = GlobalProperties.get_instance()
        self.connection_table = ConnectionTableWidget()
        global_properties.add_listener(self.connection_table)
        self.setCentralWidget(self.connection_table)
        self.connection_table.update()

        self.menu_bar = self.menuBar()
        self.menu_file = self.menu_bar.addMenu('File')
        self.menu_file.addAction('New', file_new_clicked)
        self.menu_file.addAction('Open', self.file_load)
        self.menu_file.addSeparator()
        self.menu_file.addAction('Save', self.file_save)
        self.menu_file.addAction('Save as', self.file_save_as)
        self.menu_file.addSeparator()
        self.menu_file.addAction('Exit', sys.exit)

        self.menu_file = self.menu_bar.addMenu('Connections')
        self.make_birectional_menu = self.menu_file.addMenu(
            'Make bidirectional')
        self.make_birectional_menu.addAction("with and",
                                             make_bidirectional_and)
        self.make_birectional_menu.addAction("with or", make_bidirectional_or)

        self.menu_selection = self.menu_bar.addMenu('Selections')
        self.action_add_selection = self.menu_selection.addAction(
            'Add Selection')
        self.action_add_selection.triggered.connect(
            create_add_selection_window)
        self.action_merge_selections = self.menu_selection.addAction(
            'Merge Selections')
        self.action_merge_selections.triggered.connect(
            create_merge_selectoon_window)
        self.setMenuBar(self.menu_bar)
        self.statusBar().showMessage('Welcome to mpdj!', 5000)

        self.mpdj_options_dock = QDockWidget("MPDJ Options Panel", self)
        self.mpdj_options_dock_layout = QFormLayout()
        self.mpdj_docked_widget = QWidget()

        self.tf_min_global_song_duration = QLineEdit()
        self.tf_min_global_song_duration.setValidator(
            QIntValidator(0, 2147483647))
        self.mpdj_options_dock_layout.addRow('Global min song duration:',
                                             self.tf_min_global_song_duration)
        self.tf_min_global_song_duration.editingFinished.connect(
            self.write_min_global_song_duration_to_mpdj)

        self.tf_max_global_song_duration = QLineEdit()
        self.tf_max_global_song_duration.setValidator(
            QIntValidator(0, 2147483647))
        self.mpdj_options_dock_layout.addRow('Global max song duration:',
                                             self.tf_max_global_song_duration)
        self.tf_max_global_song_duration.editingFinished.connect(
            self.write_max_global_song_duration_to_mpdj)

        self.tf_min_per_selection = QLineEdit()
        self.tf_min_per_selection.setValidator(QIntValidator(0, 2147483647))
        self.mpdj_options_dock_layout.addRow('Min per Node touch:',
                                             self.tf_min_per_selection)
        self.tf_min_per_selection.editingFinished.connect(
            self.write_min_per_note_to_mpdj)

        self.tf_max_per_selection = QLineEdit()
        self.tf_max_per_selection.setValidator(QIntValidator(0, 2147483647))
        self.mpdj_options_dock_layout.addRow('Max per Node touch:',
                                             self.tf_max_per_selection)
        self.tf_max_per_selection.editingFinished.connect(
            self.write_max_per_note_to_mpdj)

        self.combo_box_minutes_or_titles = QComboBox()
        self.combo_box_minutes_or_titles.addItems(
            [unit.gui_representation() for unit in UnitPerNodeTouch])
        self.mpdj_options_dock_layout.addRow('Unit:',
                                             self.combo_box_minutes_or_titles)
        self.combo_box_minutes_or_titles.currentTextChanged.connect(
            self.write_unit_per_node_touch_to_mpdj)

        self.tf_global_node_max_overflow_minutes = QLineEdit()
        self.tf_global_node_max_overflow_minutes.setValidator(
            QIntValidator(0, 2147483647))
        self.tf_global_node_max_overflow_minutes.editingFinished.connect(
            self.write_global_node_max_overflow_to_mpdj)
        self.cb_global_limit_overflow = QCheckBox()
        self.cb_global_limit_overflow.stateChanged.connect(lambda: list(
            map(lambda m: m(), [
                lambda: self.tf_global_node_max_overflow_minutes.setDisabled(
                    not self.cb_global_limit_overflow.isChecked()), self.
                write_limit_overspill_to_mpdj
            ])))
        self.overflow_layoout = QHBoxLayout()

        self.overflow_layoout.addWidget(self.cb_global_limit_overflow)
        self.overflow_layoout.addWidget(
            self.tf_global_node_max_overflow_minutes)
        self.mpdj_options_dock_layout.addRow("Limit overflow:",
                                             self.overflow_layoout)

        self.mpdj_docked_widget.setLayout(self.mpdj_options_dock_layout)
        self.mpdj_options_dock.setWidget(self.mpdj_docked_widget)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.mpdj_options_dock)

        self.chk_box_graph_is_directed = QCheckBox()
        self.chk_box_graph_is_directed.stateChanged.connect(
            self.write_graph_is_directed_to_mpdj)
        self.mpdj_options_dock_layout.addRow(QLabel('Graph is directed'),
                                             self.chk_box_graph_is_directed)
        self.opened_selection_window = None
        global_properties.add_listener(self)
        self.update()
Exemplo n.º 13
0
class ValueTypeEditor(QWidget):
    ValueTypes = (bool, int, float, complex, str)

    def __init__(self, *args):
        QWidget.__init__(self, *args)
        lo = QHBoxLayout(self)
        lo.setContentsMargins(0, 0, 0, 0)
        lo.setSpacing(5)
        # type selector
        self.wtypesel = QComboBox(self)
        for i, tp in enumerate(self.ValueTypes):
            self.wtypesel.addItem(tp.__name__)
        self.wtypesel.activated[int].connect(self._selectTypeNum)
        typesel_lab = QLabel("&Type:", self)
        typesel_lab.setBuddy(self.wtypesel)
        lo.addWidget(typesel_lab, 0)
        lo.addWidget(self.wtypesel, 0)
        self.wvalue = QLineEdit(self)
        self.wvalue_lab = QLabel("&Value:", self)
        self.wvalue_lab.setBuddy(self.wvalue)
        self.wbool = QComboBox(self)
        self.wbool.addItems(["false", "true"])
        self.wbool.setCurrentIndex(1)
        lo.addWidget(self.wvalue_lab, 0)
        lo.addWidget(self.wvalue, 1)
        lo.addWidget(self.wbool, 1)
        self.wvalue.hide()
        # make input validators
        self._validators = {int: QIntValidator(self), float: QDoubleValidator(self)}
        # select bool type initially
        self._selectTypeNum(0)

    def _selectTypeNum(self, index):
        tp = self.ValueTypes[index]
        self.wbool.setVisible(tp is bool)
        self.wvalue.setVisible(tp is not bool)
        self.wvalue_lab.setBuddy(self.wbool if tp is bool else self.wvalue)
        self.wvalue.setValidator(self._validators.get(tp, None))

    def setValue(self, value):
        """Sets current value"""
        for i, tp in enumerate(self.ValueTypes):
            if isinstance(value, tp):
                self.wtypesel.setCurrentIndex(i)
                self._selectTypeNum(i)
                if tp is bool:
                    self.wbool.setCurrentIndex(1 if value else 0)
                else:
                    self.wvalue.setText(str(value))
                return
        # unknown value: set bool
        self.setValue(True)

    def getValue(self):
        """Returns current value, or None if no legal value is set"""
        tp = self.ValueTypes[self.wtypesel.currentIndex()]
        if tp is bool:
            return bool(self.wbool.currentIndex())
        else:
            try:
                return tp(self.wvalue.text())
            except:
                print("Error converting input to type ", tp.__name__)
                traceback.print_exc()
                return None
Exemplo n.º 14
0
class MakeBrickDialog(QDialog):
    def __init__(self, parent, modal=True, flags=Qt.WindowFlags()):
        QDialog.__init__(self, parent, flags)
        self.model = None
        self._model_dir = None
        self.setModal(modal)
        self.setWindowTitle("Convert sources to FITS brick")
        lo = QVBoxLayout(self)
        lo.setContentsMargins(10, 10, 10, 10)
        lo.setSpacing(5)
        # file selector
        self.wfile = FileSelector(self,
                                  label="FITS filename:",
                                  dialog_label="Output FITS file",
                                  default_suffix="fits",
                                  file_types="FITS files (*.fits *.FITS)",
                                  file_mode=QFileDialog.ExistingFile)
        lo.addWidget(self.wfile)
        # reference frequency
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        label = QLabel("Frequency, MHz:", self)
        lo1.addWidget(label)
        tip = """<P>If your sky model contains spectral information (such as spectral indices), then a brick may be generated
    for a specific frequency. If a frequency is not specified here, the reference frequency of the model sources will be assumed.</P>"""
        self.wfreq = QLineEdit(self)
        self.wfreq.setValidator(QDoubleValidator(self))
        label.setToolTip(tip)
        self.wfreq.setToolTip(tip)
        lo1.addWidget(self.wfreq)
        # beam gain
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        self.wpb_apply = QCheckBox("Apply primary beam expression:", self)
        self.wpb_apply.setChecked(True)
        lo1.addWidget(self.wpb_apply)
        tip = """<P>If this option is specified, a primary power beam gain will be applied to the sources before inserting
    them into the brick. This can be any valid Python expression making use of the variables 'r' (corresponding
    to distance from field centre, in radians) and 'fq' (corresponding to frequency.)</P>"""
        self.wpb_exp = QLineEdit(self)
        self.wpb_apply.setToolTip(tip)
        self.wpb_exp.setToolTip(tip)
        lo1.addWidget(self.wpb_exp)
        # overwrite or add mode
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        self.woverwrite = QRadioButton("overwrite image", self)
        self.woverwrite.setChecked(True)
        lo1.addWidget(self.woverwrite)
        self.waddinto = QRadioButton("add into image", self)
        lo1.addWidget(self.waddinto)
        # add to model
        self.wadd = QCheckBox(
            "Add resulting brick to sky model as a FITS image component", self)
        lo.addWidget(self.wadd)
        lo1 = QHBoxLayout()
        lo.addLayout(lo1)
        lo1.setContentsMargins(0, 0, 0, 0)
        self.wpad = QLineEdit(self)
        self.wpad.setValidator(QDoubleValidator(self))
        self.wpad.setText("1.1")
        lab = QLabel("...with padding factor:", self)
        lab.setToolTip(
            """<P>The padding factor determines the amount of null padding inserted around the image during
      the prediction stage. Padding alleviates the effects of tapering and detapering in the uv-brick, which can show
      up towards the edges of the image. For a factor of N, the image will be padded out to N times its original size.
      This increases memory use, so if you have no flux at the edges of the image anyway, then a pad factor of 1 is
      perfectly fine.</P>""")
        self.wpad.setToolTip(lab.toolTip())
        self.wadd.toggled[bool].connect(self.wpad.setEnabled)
        self.wadd.toggled[bool].connect(lab.setEnabled)
        self.wpad.setEnabled(False)
        lab.setEnabled(False)
        lo1.addStretch(1)
        lo1.addWidget(lab, 0)
        lo1.addWidget(self.wpad, 1)
        self.wdel = QCheckBox(
            "Remove from the sky model sources that go into the brick", self)
        lo.addWidget(self.wdel)
        # OK/cancel buttons
        lo.addSpacing(10)
        lo2 = QHBoxLayout()
        lo.addLayout(lo2)
        lo2.setContentsMargins(5, 5, 5, 5)
        self.wokbtn = QPushButton("OK", self)
        self.wokbtn.setMinimumWidth(128)
        self.wokbtn.clicked.connect(self.accept)
        self.wokbtn.setEnabled(False)
        cancelbtn = QPushButton("Cancel", self)
        cancelbtn.setMinimumWidth(128)
        cancelbtn.clicked.connect(self.reject)
        lo2.addWidget(self.wokbtn)
        lo2.addStretch(1)
        lo2.addWidget(cancelbtn)
        self.setMinimumWidth(384)
        # signals
        self.wfile.filenameSelected.connect(self._fileSelected)
        # internal state
        self.qerrmsg = QErrorMessage(self)

    def setModel(self, model):
        self.model = model
        pb = self.model.primaryBeam()
        if pb:
            self.wpb_exp.setText(pb)
        else:
            self.wpb_apply.setChecked(False)
            self.wpb_exp.setText("")
        if model.filename():
            self._model_dir = os.path.dirname(os.path.abspath(
                model.filename()))
        else:
            self._model_dir = os.path.abspath('.')
        self.wfile.setDirectory(self._model_dir)
        self._fileSelected(self.wfile.filename(), quiet=True)

    def _fileSelected(self, filename, quiet=False):
        self.wokbtn.setEnabled(False)
        if not filename:
            return None
        # check that filename matches model
        if not os.path.samefile(self._model_dir, os.path.dirname(filename)):
            self.wfile.setFilename('')
            if not quiet:
                QMessageBox.warning(
                    self, "Directory mismatch",
                    """<P>The FITS file must reside in the same directory
          as the current sky model.</P>""")
            self.wfile.setDirectory(self._model_dir)
            return None
        # read fits file
        busy = BusyIndicator()
        try:
            input_hdu = pyfits.open(filename)[0]
            hdr = input_hdu.header
            # get frequency, if specified
            for axis in range(1, hdr['NAXIS'] + 1):
                if hdr['CTYPE%d' % axis].upper() == 'FREQ':
                    self.wfreq.setText(str(hdr['CRVAL%d' % axis] / 1e+6))
                    break
        except Exception as err:
            busy.reset_cursor()
            self.wfile.setFilename('')
            if not quiet:
                QMessageBox.warning(
                    self, "Error reading FITS",
                    "Error reading FITS file %s: %s" % (filename, str(err)))
            return None
        self.wokbtn.setEnabled(True)
        # if filename is not in model already, enable the "add to model" control
        for src in self.model.sources:
            if isinstance(getattr(src, 'shape', None), ModelClasses.FITSImage) \
                    and os.path.exists(src.shape.filename) and os.path.exists(filename) \
                    and os.path.samefile(src.shape.filename, filename):
                self.wadd.setChecked(True)
                self.wadd.setEnabled(False)
                self.wadd.setText("image already in sky model")
                break
        else:
            self.wadd.setText("add image to sky model")
        busy.reset_cursor()
        return filename

    def accept(self):
        """Tries to make a brick, and closes the dialog if successful."""
        sources = [
            src for src in self.model.sources
            if src.selected and src.typecode == 'pnt'
        ]
        filename = self.wfile.filename()
        if not self._fileSelected(filename):
            return
        # get PB expression
        pbfunc = None
        if self.wpb_apply.isChecked():
            pbexp = str(self.wpb_exp.text())
            try:
                pbfunc = eval("lambda r,fq:" + pbexp)
            except Exception as err:
                QMessageBox.warning(
                    self, "Error parsing PB experssion",
                    "Error parsing primary beam expression %s: %s" %
                    (pbexp, str(err)))
                return
        # get frequency
        freq = str(self.wfreq.text())
        freq = float(freq) * 1e+6 if freq else None
        # get pad factor
        pad = str(self.wpad.text())
        pad = max(float(pad), 1) if pad else 1
        # read fits file
        busy = BusyIndicator()
        try:
            input_hdu = pyfits.open(filename)[0]
        except Exception as err:
            busy.reset_cursor()
            QMessageBox.warning(
                self, "Error reading FITS",
                "Error reading FITS file %s: %s" % (filename, str(err)))
            return
        # reset data if asked to
        if self.woverwrite.isChecked():
            input_hdu.data[...] = 0
        # insert sources
        Imaging.restoreSources(input_hdu,
                               sources,
                               0,
                               primary_beam=pbfunc,
                               freq=freq)
        # save fits file
        try:
            # pyfits seems to produce an exception:
            #         TypeError: formatwarning() takes exactly 4 arguments (5 given)
            # when attempting to overwrite a file. As a workaround, remove the file first.
            if os.path.exists(filename):
                os.remove(filename)
            input_hdu.writeto(filename)
        except Exception as err:
            traceback.print_exc()
            busy.reset_cursor()
            QMessageBox.warning(
                self, "Error writing FITS",
                "Error writing FITS file %s: %s" % (filename, str(err)))
            return
        changed = False
        sources = self.model.sources
        # remove sources from model if asked to
        if self.wdel.isChecked():
            sources = [
                src for src in sources
                if not (src.selected and src.typecode == 'pnt')
            ]
            changed = True
        # add image to model if asked to
        if self.wadd.isChecked():
            hdr = input_hdu.header
            # get image parameters
            max_flux = float(input_hdu.data.max())
            wcs = WCS(hdr, mode='pyfits')
            # Get reference pixel coordinates
            # wcs.getCentreWCSCoords() doesn't work, as that gives us the middle of the image
            # So scan the header to get the CRPIX values
            ra0 = dec0 = 1
            for iaxis in range(hdr['NAXIS']):
                axs = str(iaxis + 1)
                name = hdr.get('CTYPE' + axs, axs).upper()
                if name.startswith("RA"):
                    ra0 = hdr.get('CRPIX' + axs, 1) - 1
                elif name.startswith("DEC"):
                    dec0 = hdr.get('CRPIX' + axs, 1) - 1
            # convert pixel to degrees
            ra0, dec0 = wcs.pix2wcs(ra0, dec0)
            ra0 *= DEG
            dec0 *= DEG
            sx, sy = wcs.getHalfSizeDeg()
            sx *= DEG
            sy *= DEG
            nx, ny = input_hdu.data.shape[-1:-3:-1]
            # check if this image is already contained in the model
            for src in sources:
                if isinstance(getattr(src, 'shape', None),
                              ModelClasses.FITSImage) and os.path.samefile(
                                  src.shape.filename, filename):
                    # update source parameters
                    src.pos.ra, src.pos.dec = ra0, dec0
                    src.flux.I = max_flux
                    src.shape.ex, src.shape.ey = sx, sy
                    src.shape.nx, src.shape.ny = nx, ny
                    src.shape.pad = pad
                    break
            # not contained, make new source object
            else:
                pos = ModelClasses.Position(ra0, dec0)
                flux = ModelClasses.Flux(max_flux)
                shape = ModelClasses.FITSImage(sx,
                                               sy,
                                               0,
                                               os.path.basename(filename),
                                               nx,
                                               ny,
                                               pad=pad)
                img_src = SkyModel.Source(os.path.splitext(
                    os.path.basename(filename))[0],
                                          pos,
                                          flux,
                                          shape=shape)
                sources.append(img_src)
            changed = True
        if changed:
            self.model.setSources(sources)
            self.model.emitUpdate(SkyModel.SkyModel.UpdateAll, origin=self)
        self.parent().showMessage("Wrote %d sources to FITS file %s" %
                                  (len(sources), filename))
        busy.reset_cursor()
        return QDialog.accept(self)
class ConfigWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.main_layout = QVBoxLayout()
        self.l = QFormLayout()
        self.l2 = QHBoxLayout()
        self.l3 = QHBoxLayout()

        self.group_box = QGroupBox('Ustawienia ogólne')
        self.group_box2 = QGroupBox('Pobieraj metadane')
        self.group_box3 = QGroupBox(
            'Pobieraj dodatkowe metadane i dołącz je do komentarza')

        # general settings
        self.max_results_label = QLabel('Maksymalna liczba wyników')
        self.max_results_label.setToolTip(
            'Maksymalna liczba pobieranych metadanych. Dla książek o nieunikalnych tytułach \
pierwszy wynik może być niepoprawny')
        self.max_results = QLineEdit(self)
        self.max_results.setValidator(QIntValidator())
        self.max_results.setText(str(PREFS['max_results']))
        self.max_results_label.setBuddy(self.max_results)
        self.l.addRow(self.max_results_label, self.max_results)

        self.authors_search_label = QLabel('Używaj autorów do wyszukiwań')
        self.authors_search_label.setToolTip(
            'Wyszukuj uwzględniając autorów. Może poprawić trafność wyników, ale błędni autorzy spowodują brak wyników'
        )
        self.authors_search = QCheckBox()
        self.authors_search.setChecked(PREFS['authors_search'])
        self.authors_search_label.setBuddy(self.authors_search)
        self.l.addRow(self.authors_search_label, self.authors_search)

        self.only_first_author_label = QLabel(
            'Używaj tylko pierwszego autora do wyszukiwania')
        self.only_first_author_label.setToolTip(
            'Używaj tylko pierwszego autora do wyszukiwań, obowiązuje tylko gdy wyszukiwanie z autorami jest aktywowane'
        )
        self.only_first_author = QCheckBox()
        self.only_first_author.setChecked(PREFS['only_first_author'])
        self.only_first_author_label.setBuddy(self.only_first_author)
        self.l.addRow(self.only_first_author_label, self.only_first_author)

        self.covers_label = QLabel('Pobieraj okładki')
        self.covers = QCheckBox()
        self.covers.setChecked(PREFS['covers'])
        self.covers_label.setBuddy(self.covers)
        self.l.addRow(self.covers_label, self.covers)

        self.max_covers_label = QLabel('Maksymalna liczba okładek')
        self.max_covers_label.setToolTip(
            'Maksymalna liczba pobieranych okładek')
        self.max_covers = QLineEdit(self)
        self.max_covers.setValidator(QIntValidator())
        self.max_covers.setText(str(PREFS['max_covers']))
        self.max_covers_label.setBuddy(self.max_covers)
        self.l.addRow(self.max_covers_label, self.max_covers)

        self.threads_label = QLabel('Wielowątkowe przetwarzanie')
        self.threads_label.setToolTip(
            'Przyśpiesza pracę używając wielu wątków')
        self.threads = QCheckBox()
        self.threads.setChecked(PREFS['threads'])
        self.threads_label.setBuddy(self.threads)
        self.l.addRow(self.threads_label, self.threads)

        self.max_threads_label = QLabel('Maksymalna liczba wątków')
        self.max_threads = QLineEdit(self)
        self.max_threads.setValidator(QIntValidator())
        self.max_threads.setText(str(PREFS['max_threads']))
        self.max_threads_label.setBuddy(self.max_threads)
        self.l.addRow(self.max_threads_label, self.max_threads)

        self.thread_delay_label = QLabel('Opóźnienie wątku')
        self.thread_delay_label.setToolTip(
            'Czas oczekiwania na uruchomienie kolejnego wątku')
        self.thread_delay = QLineEdit(self)
        self.thread_delay.setValidator(QDoubleValidator())
        self.thread_delay.setText(str(PREFS['thread_delay']))
        self.thread_delay_label.setBuddy(self.thread_delay)
        self.l.addRow(self.thread_delay_label, self.thread_delay)

        # metadata settings
        if 'title' in PREFS.defaults:
            self.title = QCheckBox('Tytuł')
            self.title.setChecked(PREFS['title'])
            self.l2.addWidget(self.title)

        if 'authors' in PREFS.defaults:
            self.authors = QCheckBox('Autorzy')
            self.authors.setChecked(PREFS['authors'])
            self.l2.addWidget(self.authors)

        if 'pubdate' in PREFS.defaults:
            self.pubdate = QCheckBox('Data wydania')
            self.pubdate.setChecked(PREFS['pubdate'])
            self.l2.addWidget(self.pubdate)

        if 'publisher' in PREFS.defaults:
            self.publisher = QCheckBox('Wydawca')
            self.publisher.setChecked(PREFS['publisher'])
            self.l2.addWidget(self.publisher)

        if 'isbn' in PREFS.defaults:
            self.isbn = QCheckBox('ISBN')
            self.isbn.setChecked(PREFS['isbn'])
            self.l2.addWidget(self.isbn)

        if 'comments' in PREFS.defaults:
            self.comments = QCheckBox('Opis')
            self.comments.setChecked(PREFS['comments'])
            self.l2.addWidget(self.comments)

        if 'languages' in PREFS.defaults:
            self.languages = QCheckBox('Języki')
            self.languages.setChecked(PREFS['languages'])
            self.l2.addWidget(self.languages)

        if 'rating' in PREFS.defaults:
            self.rating = QCheckBox('Ocena')
            self.rating.setChecked(PREFS['rating'])
            self.l2.addWidget(self.rating)

        if 'tags' in PREFS.defaults:
            self.tags = QCheckBox('Etykiety (tagi)')
            self.tags.setChecked(PREFS['tags'])
            self.l2.addWidget(self.tags)

        if 'series' in PREFS.defaults:
            self.series = QCheckBox('Cykle')
            self.series.setChecked(PREFS['series'])
            self.l2.addWidget(self.series)

        if 'identifier' in PREFS.defaults:
            self.identifier = QCheckBox('Identyfikator')
            self.identifier.setChecked(PREFS['identifier'])
            self.l2.addWidget(self.identifier)

        # custom metadata
        if 'translators' in PREFS.defaults:
            self.translators = QCheckBox('Tłumaczenie')
            self.translators.setChecked(PREFS['translators'])
            self.l3.addWidget(self.translators)

        if 'original_title' in PREFS.defaults:
            self.original_title = QCheckBox('Tytuł oryginału')
            self.original_title.setChecked(PREFS['original_title'])
            self.l3.addWidget(self.original_title)

        if 'categories' in PREFS.defaults:
            self.categories = QCheckBox('Kategorie')
            self.categories.setChecked(PREFS['categories'])
            self.l3.addWidget(self.categories)

        if 'genres' in PREFS.defaults:
            self.genres = QCheckBox('Gatunki')
            self.genres.setChecked(PREFS['genres'])
            self.l3.addWidget(self.genres)

        self.group_box.setLayout(self.l)
        self.group_box2.setLayout(self.l2)
        self.group_box3.setLayout(self.l3)
        self.main_layout.addWidget(self.group_box)
        self.main_layout.addWidget(self.group_box2)
        self.main_layout.addWidget(self.group_box3)
        self.main_layout.setAlignment(Qt.AlignTop)
        self.setLayout(self.main_layout)

    def save_settings(self):
        PREFS['max_results'] = int(self.max_results.text())
        PREFS['authors_search'] = self.authors_search.isChecked()
        PREFS['only_first_author'] = self.only_first_author.isChecked()
        PREFS['covers'] = self.covers.isChecked()
        PREFS['max_covers'] = int(self.max_covers.text())
        PREFS['threads'] = self.threads.isChecked()
        PREFS['max_threads'] = int(self.max_threads.text())
        PREFS['thread_delay'] = float(self.thread_delay.text().replace(
            ',', '.'))

        # metadata settings
        if 'title' in PREFS.defaults:
            PREFS['title'] = self.title.isChecked()
        if 'authors' in PREFS.defaults:
            PREFS['authors'] = self.authors.isChecked()
        if 'pubdate' in PREFS.defaults:
            PREFS['pubdate'] = self.pubdate.isChecked()
        if 'publisher' in PREFS.defaults:
            PREFS['publisher'] = self.publisher.isChecked()
        if 'isbn' in PREFS.defaults:
            PREFS['isbn'] = self.isbn.isChecked()
        if 'comments' in PREFS.defaults:
            PREFS['comments'] = self.comments.isChecked()
        if 'languages' in PREFS.defaults:
            PREFS['languages'] = self.languages.isChecked()
        if 'rating' in PREFS.defaults:
            PREFS['rating'] = self.rating.isChecked()
        if 'tags' in PREFS.defaults:
            PREFS['tags'] = self.tags.isChecked()
        if 'series' in PREFS.defaults:
            PREFS['series'] = self.series.isChecked()
        if 'identifier' in PREFS.defaults:
            PREFS['identifier'] = self.identifier.isChecked()

        # custom metadata settings
        if 'translators' in PREFS.defaults:
            PREFS['translators'] = self.translators.isChecked()
        if 'original_title' in PREFS.defaults:
            PREFS['original_title'] = self.original_title.isChecked()
        if 'categories' in PREFS.defaults:
            PREFS['categories'] = self.categories.isChecked()
        if 'genres' in PREFS.defaults:
            PREFS['genres'] = self.genres.isChecked()

        return PREFS