Пример #1
0
 def minimumSize(self):
     size = QSize()
     for item in self.item_list:
         size = size.expandedTo(item.minimumSize())
     #size += QSize(2*self.margin(), 2*self.margin())
     size += QSize(2*8, 2*8)
     return size
Пример #2
0
 def sizeHint(self):
     """Returns the widget size hint (based on the editor font size) """
     fm = QFontMetricsF(self.editor.font())
     size_hint = QSize(fm.height(), fm.height())
     if size_hint.width() > 16:
         size_hint.setWidth(16)
     return size_hint
Пример #3
0
    def readSettings(self, settings):
        qapp = QApplication.instance()
        qapp.setAttribute(Qt.AA_UseHighDpiPixmaps)
        if hasattr(Qt, 'AA_EnableHighDpiScaling'):
            qapp.setAttribute(Qt.AA_EnableHighDpiScaling, settings.get('high_dpi_scaling'))

        # get the saved window geometry
        window_size = settings.get('MainWindow/size')
        if not isinstance(window_size, QSize):
            window_size = QSize(*window_size)
        window_pos = settings.get('MainWindow/position')
        if not isinstance(window_pos, QPoint):
            window_pos = QPoint(*window_pos)

        # make sure main window is smaller than the desktop
        desktop = QDesktopWidget()

        # this gives the maximum screen number if the position is off screen
        screen = desktop.screenNumber(window_pos)

        # recalculate the window size
        desktop_geom = desktop.screenGeometry(screen)
        w = min(desktop_geom.size().width(), window_size.width())
        h = min(desktop_geom.size().height(), window_size.height())
        window_size = QSize(w, h)

        # and position it on the supplied desktop screen
        x = max(window_pos.x(), desktop_geom.left())
        y = max(window_pos.y(), desktop_geom.top())
        window_pos = QPoint(x, y)

        # set the geometry
        self.resize(window_size)
        self.move(window_pos)

        # restore window state
        if settings.has('MainWindow/state'):
            self.restoreState(settings.get('MainWindow/state'))
        else:
            self.setWindowState(Qt.WindowMaximized)

        # read in settings for children
        AlgorithmInputHistory().readSettings(settings)
        for widget in self.widgets:
            if hasattr(widget, 'readSettings'):
                widget.readSettings(settings)
Пример #4
0
    def imageFiles(self, new_files):
        """
        JSON-formatted dictionary keyed on states (integers), with filenames
        of the image file to display for the state.

        Parameters
        ----------
        new_files : str
        """
        self._state_images_string = str(new_files)
        try:
            new_file_dict = json.loads(self._state_images_string)
        except Exception:
            self._state_images = {}
            return
        self._sizeHint = QSize(0, 0)
        for (state, filename) in new_file_dict.items():
            if is_pydm_app():
                try:
                    file_path = self.app.get_path(filename)
                except Exception as e:
                    logger.exception("Couldn't get file with path %s", filename)
                    file_path = filename
            else:
                file_path = filename
            # First, lets try SVG.  We have to try SVG first, otherwise
            # QPixmap will happily load the SVG and turn it into a raster image.
            # Really annoying: We have to try to load the file as SVG,
            # and we expect it will fail often (because many images aren't SVG).
            # Qt prints a warning message to stdout any time SVG loading fails.
            # So we have to temporarily silence Qt warning messages here.
            qInstallMessageHandler(self.qt_message_handler)
            svg = QSvgRenderer()
            svg.repaintNeeded.connect(self.update)
            if svg.load(file_path):
                self._state_images[int(state)] = (filename, svg)
                self._sizeHint = self._sizeHint.expandedTo(svg.defaultSize())
                qInstallMessageHandler(None)
                continue
            qInstallMessageHandler(None)
            # SVG didn't work, lets try QPixmap
            image = QPixmap(file_path)
            if not image.isNull():
                self._state_images[int(state)] = (filename, image)
                self._sizeHint = self._sizeHint.expandedTo(image.size())
                continue
            # If we get this far, the file specified could not be loaded at all.
            logger.error("Could not load image: {}".format(filename))
            self._state_images[int(state)] = (filename, None)
Пример #5
0
 def __init__(self, parent=None) -> None:
     super().__init__(parent)
     self._size = QSize(50, 50)
     self._max_id = 0
Пример #6
0
	def sizeHint( self ):
		return QSize( 50, _TRACK_SIZE )
Пример #7
0
 def sizeHint(self):
     """Override Qt method"""
     return QSize(self.WIDTH, 0)
Пример #8
0
class LSPServerEditor(QDialog):
    DEFAULT_HOST = '127.0.0.1'
    DEFAULT_PORT = 2084
    DEFAULT_CMD = ''
    DEFAULT_ARGS = ''
    DEFAULT_CONFIGURATION = '{}'
    DEFAULT_EXTERNAL = False
    DEFAULT_STDIO = False
    HOST_REGEX = re.compile(r'^\w+([.]\w+)*$')
    NON_EMPTY_REGEX = re.compile(r'^\S+$')
    JSON_VALID = _('Valid JSON')
    JSON_INVALID = _('Invalid JSON')
    MIN_SIZE = QSize(850, 600)
    INVALID_CSS = "QLineEdit {border: 1px solid red;}"
    VALID_CSS = "QLineEdit {border: 1px solid green;}"

    def __init__(self,
                 parent,
                 language=None,
                 cmd='',
                 host='127.0.0.1',
                 port=2084,
                 args='',
                 external=False,
                 stdio=False,
                 configurations={},
                 **kwargs):
        super(LSPServerEditor, self).__init__(parent)

        description = _(
            "To create a new server configuration, you need to select a "
            "programming language, set the command to start its associated "
            "server and enter any arguments that should be passed to it on "
            "startup. Additionally, you can set the server's hostname and "
            "port if connecting to an external server, "
            "or to a local one using TCP instead of stdio pipes."
            "<br><br>"
            "<i>Note</i>: You can use the placeholders <tt>{host}</tt> and "
            "<tt>{port}</tt> in the server arguments field to automatically "
            "fill in the respective values.<br>")
        self.parent = parent
        self.external = external

        # Widgets
        self.server_settings_description = QLabel(description)
        self.lang_cb = QComboBox(self)
        self.external_cb = QCheckBox(_('External server'), self)
        self.host_label = QLabel(_('Host:'))
        self.host_input = QLineEdit(self)
        self.port_label = QLabel(_('Port:'))
        self.port_spinner = QSpinBox(self)
        self.cmd_label = QLabel(_('Command:'))
        self.cmd_input = QLineEdit(self)
        self.args_label = QLabel(_('Arguments:'))
        self.args_input = QLineEdit(self)
        self.json_label = QLabel(self.JSON_VALID, self)
        self.conf_label = QLabel(_('<b>Server Configuration:</b>'))
        self.conf_input = CodeEditor(None)

        self.bbox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        self.button_ok = self.bbox.button(QDialogButtonBox.Ok)
        self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel)

        # Widget setup
        self.setMinimumSize(self.MIN_SIZE)
        self.setWindowTitle(_('LSP server editor'))

        self.server_settings_description.setWordWrap(True)

        self.lang_cb.setToolTip(
            _('Programming language provided by the LSP server'))
        self.lang_cb.addItem(_('Select a language'))
        self.lang_cb.addItems(LSP_LANGUAGES)

        self.button_ok.setEnabled(False)
        if language is not None:
            idx = LSP_LANGUAGES.index(language)
            self.lang_cb.setCurrentIndex(idx + 1)
            self.button_ok.setEnabled(True)

        self.host_input.setPlaceholderText('127.0.0.1')
        self.host_input.setText(host)
        self.host_input.textChanged.connect(lambda x: self.validate())

        self.port_spinner.setToolTip(_('TCP port number of the server'))
        self.port_spinner.setMinimum(1)
        self.port_spinner.setMaximum(60000)
        self.port_spinner.setValue(port)

        self.cmd_input.setText(cmd)
        self.cmd_input.setPlaceholderText('/absolute/path/to/command')

        self.args_input.setToolTip(
            _('Additional arguments required to start the server'))
        self.args_input.setText(args)
        self.args_input.setPlaceholderText(r'--host {host} --port {port}')

        self.conf_input.setup_editor(language='json',
                                     color_scheme=CONF.get(
                                         'appearance', 'selected'),
                                     wrap=False,
                                     edge_line=True,
                                     highlight_current_line=True,
                                     highlight_current_cell=True,
                                     occurrence_highlighting=True,
                                     auto_unindent=True,
                                     font=get_font(),
                                     filename='config.json',
                                     folding=False)
        self.conf_input.set_language('json', 'config.json')
        self.conf_input.setToolTip(
            _('Additional LSP server configuration '
              'set at runtime. JSON required'))
        try:
            conf_text = json.dumps(configurations, indent=4, sort_keys=True)
        except Exception:
            conf_text = '{}'
        self.conf_input.set_text(conf_text)

        self.external_cb.setToolTip(
            _('Check if the server runs on a remote location'))
        self.external_cb.setChecked(external)

        self.stdio_cb = QCheckBox(_('Use stdio pipes for communication'), self)
        self.stdio_cb.setToolTip(
            _('Check if the server communicates '
              'using stdin/out pipes'))
        self.stdio_cb.setChecked(stdio)

        # Layout setup
        hlayout = QHBoxLayout()
        general_vlayout = QVBoxLayout()
        general_vlayout.addWidget(self.server_settings_description)

        vlayout = QVBoxLayout()

        lang_group = QGroupBox(_('Language'))
        lang_layout = QVBoxLayout()
        lang_layout.addWidget(self.lang_cb)
        lang_group.setLayout(lang_layout)
        vlayout.addWidget(lang_group)

        server_group = QGroupBox(_('Language server'))
        server_layout = QGridLayout()
        server_layout.addWidget(self.cmd_label, 0, 0)
        server_layout.addWidget(self.cmd_input, 0, 1)
        server_layout.addWidget(self.args_label, 1, 0)
        server_layout.addWidget(self.args_input, 1, 1)
        server_group.setLayout(server_layout)
        vlayout.addWidget(server_group)

        address_group = QGroupBox(_('Server address'))
        host_layout = QVBoxLayout()
        host_layout.addWidget(self.host_label)
        host_layout.addWidget(self.host_input)

        port_layout = QVBoxLayout()
        port_layout.addWidget(self.port_label)
        port_layout.addWidget(self.port_spinner)

        conn_info_layout = QHBoxLayout()
        conn_info_layout.addLayout(host_layout)
        conn_info_layout.addLayout(port_layout)
        address_group.setLayout(conn_info_layout)
        vlayout.addWidget(address_group)

        advanced_group = QGroupBox(_('Advanced'))
        advanced_layout = QVBoxLayout()
        advanced_layout.addWidget(self.external_cb)
        advanced_layout.addWidget(self.stdio_cb)
        advanced_group.setLayout(advanced_layout)
        vlayout.addWidget(advanced_group)

        conf_layout = QVBoxLayout()
        conf_layout.addWidget(self.conf_label)
        conf_layout.addWidget(self.conf_input)
        conf_layout.addWidget(self.json_label)

        vlayout.addStretch()
        hlayout.addLayout(vlayout, 2)
        hlayout.addLayout(conf_layout, 3)
        general_vlayout.addLayout(hlayout)

        general_vlayout.addWidget(self.bbox)
        self.setLayout(general_vlayout)
        self.form_status(False)

        # Signals
        if not external:
            self.cmd_input.textChanged.connect(lambda x: self.validate())
        self.external_cb.stateChanged.connect(self.set_local_options)
        self.stdio_cb.stateChanged.connect(self.set_stdio_options)
        self.lang_cb.currentIndexChanged.connect(self.lang_selection_changed)
        self.conf_input.textChanged.connect(self.validate)
        self.bbox.accepted.connect(self.accept)
        self.bbox.rejected.connect(self.reject)

        # Final setup
        if language is not None:
            self.form_status(True)
            self.validate()
            if stdio:
                self.set_stdio_options(True)
            if external:
                self.set_local_options(True)

    @Slot()
    def validate(self):
        host_text = self.host_input.text()
        cmd_text = self.cmd_input.text()

        if not self.HOST_REGEX.match(host_text):
            self.button_ok.setEnabled(False)
            self.host_input.setStyleSheet(self.INVALID_CSS)
            if bool(host_text):
                self.host_input.setToolTip(_('Hostname must be valid'))
            else:
                self.host_input.setToolTip(
                    _('Hostname or IP address of the host on which the server '
                      'is running. Must be non empty.'))
        else:
            self.host_input.setStyleSheet(self.VALID_CSS)
            self.host_input.setToolTip(_('Hostname is valid'))
            self.button_ok.setEnabled(True)

        if not self.external:
            if not self.NON_EMPTY_REGEX.match(cmd_text):
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(self.INVALID_CSS)
                self.cmd_input.setToolTip(
                    _('Command used to start the LSP server locally. Must be '
                      'non empty'))
                return

            if find_program(cmd_text) is None:
                self.button_ok.setEnabled(False)
                self.cmd_input.setStyleSheet(self.INVALID_CSS)
                self.cmd_input.setToolTip(
                    _('Program was not found '
                      'on your system'))
            else:
                self.cmd_input.setStyleSheet(self.VALID_CSS)
                self.cmd_input.setToolTip(
                    _('Program was found on your '
                      'system'))
                self.button_ok.setEnabled(True)

        try:
            json.loads(self.conf_input.toPlainText())
            try:
                self.json_label.setText(self.JSON_VALID)
            except Exception:
                pass
        except ValueError:
            try:
                self.json_label.setText(self.JSON_INVALID)
                self.button_ok.setEnabled(False)
            except Exception:
                pass

    def form_status(self, status):
        self.host_input.setEnabled(status)
        self.port_spinner.setEnabled(status)
        self.external_cb.setEnabled(status)
        self.stdio_cb.setEnabled(status)
        self.cmd_input.setEnabled(status)
        self.args_input.setEnabled(status)
        self.conf_input.setEnabled(status)
        self.json_label.setVisible(status)

    @Slot()
    def lang_selection_changed(self):
        idx = self.lang_cb.currentIndex()
        if idx == 0:
            self.set_defaults()
            self.form_status(False)
            self.button_ok.setEnabled(False)
        else:
            server = self.parent.get_server_by_lang(LSP_LANGUAGES[idx - 1])
            self.form_status(True)
            if server is not None:
                self.host_input.setText(server.host)
                self.port_spinner.setValue(server.port)
                self.external_cb.setChecked(server.external)
                self.stdio_cb.setChecked(server.stdio)
                self.cmd_input.setText(server.cmd)
                self.args_input.setText(server.args)
                self.conf_input.set_text(json.dumps(server.configurations))
                self.json_label.setText(self.JSON_VALID)
                self.button_ok.setEnabled(True)
            else:
                self.set_defaults()

    def set_defaults(self):
        self.cmd_input.setStyleSheet('')
        self.host_input.setStyleSheet('')
        self.host_input.setText(self.DEFAULT_HOST)
        self.port_spinner.setValue(self.DEFAULT_PORT)
        self.external_cb.setChecked(self.DEFAULT_EXTERNAL)
        self.stdio_cb.setChecked(self.DEFAULT_STDIO)
        self.cmd_input.setText(self.DEFAULT_CMD)
        self.args_input.setText(self.DEFAULT_ARGS)
        self.conf_input.set_text(self.DEFAULT_CONFIGURATION)
        self.json_label.setText(self.JSON_VALID)

    @Slot(bool)
    @Slot(int)
    def set_local_options(self, enabled):
        self.external = enabled
        self.cmd_input.setEnabled(True)
        self.args_input.setEnabled(True)
        if enabled:
            self.cmd_input.setEnabled(False)
            self.cmd_input.setStyleSheet('')
            self.args_input.setEnabled(False)
            self.stdio_cb.stateChanged.disconnect()
            self.stdio_cb.setChecked(False)
            self.stdio_cb.setEnabled(False)
        else:
            self.cmd_input.setEnabled(True)
            self.args_input.setEnabled(True)
            self.stdio_cb.setEnabled(True)
            self.stdio_cb.setChecked(False)
            self.stdio_cb.stateChanged.connect(self.set_stdio_options)
        try:
            self.validate()
        except Exception:
            pass

    @Slot(bool)
    @Slot(int)
    def set_stdio_options(self, enabled):
        self.stdio = enabled
        if enabled:
            self.cmd_input.setEnabled(True)
            self.args_input.setEnabled(True)
            self.external_cb.stateChanged.disconnect()
            self.external_cb.setChecked(False)
            self.external_cb.setEnabled(False)
            self.host_input.setStyleSheet('')
            self.host_input.setEnabled(False)
            self.port_spinner.setEnabled(False)
        else:
            self.cmd_input.setEnabled(True)
            self.args_input.setEnabled(True)
            self.external_cb.setChecked(False)
            self.external_cb.setEnabled(True)
            self.external_cb.stateChanged.connect(self.set_local_options)
            self.host_input.setEnabled(True)
            self.port_spinner.setEnabled(True)
        try:
            self.validate()
        except Exception:
            pass

    def get_options(self):
        language_idx = self.lang_cb.currentIndex()
        language = LSP_LANGUAGES[language_idx - 1]
        host = self.host_input.text()
        port = int(self.port_spinner.value())
        external = self.external_cb.isChecked()
        stdio = self.stdio_cb.isChecked()
        args = self.args_input.text()
        cmd = self.cmd_input.text()
        configurations = json.loads(self.conf_input.toPlainText())
        server = LSPServer(language=language.lower(),
                           cmd=cmd,
                           args=args,
                           host=host,
                           port=port,
                           external=external,
                           stdio=stdio,
                           configurations=configurations)
        return server
Пример #9
0
	def sizeHint( self ):
		return QSize( 100, 100 )
Пример #10
0
    def __init__(self, latest_version=None, prefix=None):
        """Main dialog for the anaconda navgator updater."""
        super(MainDialog, self).__init__()

        # Variables
        self.api = CondaAPI()
        self.prefix = prefix or os.environ.get('CONDA_PREFIX',
                                               self.api.ROOT_PREFIX)
        self.info = {}
        self.first_run = True
        self.setup_ready = False
        self.busy = False
        self.up_to_date = False
        self.error = False
        self.success = False
        self.status = ''
        self.current_version = None
        self.latest_version = latest_version
        self.style_sheet = load_style_sheet()
        self.timer = QTimer()
        self.timer_2 = QTimer()

        # Widgets
        self.message_box = None  # For testing
        self.label_icon = QSvgWidget()
        self.label_message = LabelBase(
            "There's a new version of Anaconda Navigator available. "
            "We strongly recommend you to update.")

        self.label_status = LabelBase('')
        self.progress_bar = QProgressBar()
        self.button_cancel = ButtonNormal('Dismiss')
        self.button_update = ButtonPrimary('Update now')
        self.button_launch = ButtonPrimary('Launch Navigator')

        # Widgets setup
        self.label_message.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.label_message.setWordWrap(True)
        self.label_status.setWordWrap(True)
        self.button_update.setAutoDefault(True)
        self.button_launch.setAutoDefault(True)
        self.button_cancel.setFocusPolicy(Qt.NoFocus)
        self.timer.setInterval(1000)
        self.timer_2.setInterval(5000)
        self.progress_bar.setTextVisible(False)
        self.progress_bar.setStyleSheet(self.style_sheet)
        self.label_icon.load(images.ANACONDA_LOGO)
        self.label_icon.setMaximumSize(QSize(64, 64))
        self.label_icon.setMinimumSize(QSize(64, 64))
        self.setWindowTitle('Anaconda Navigator Updater')
        self.progress_bar.setMaximumWidth(self.WIDTH / 3)
        self.setMinimumWidth(self.WIDTH)
        self.setMaximumWidth(self.WIDTH)
        self.setMinimumHeight(self.HEIGHT)

        # Layouts
        layout_status = QHBoxLayout()
        layout_status.addWidget(self.label_status)
        layout_status.addWidget(SpacerHorizontal())
        layout_status.addWidget(self.progress_bar)

        layout_text = QVBoxLayout()
        layout_text.addWidget(self.label_message)
        layout_text.addStretch()
        layout_text.addWidget(SpacerVertical())
        layout_text.addLayout(layout_status)

        layout_icon = QVBoxLayout()
        layout_icon.addWidget(self.label_icon)
        layout_icon.addStretch()

        layout_top = QHBoxLayout()
        layout_top.addLayout(layout_icon)
        layout_top.addWidget(SpacerHorizontal())
        layout_top.addLayout(layout_text)

        layout_buttons = QHBoxLayout()
        layout_buttons.addStretch()
        layout_buttons.addWidget(self.button_cancel)
        layout_buttons.addWidget(SpacerHorizontal())
        layout_buttons.addWidget(self.button_update)
        layout_buttons.addWidget(self.button_launch)

        layout = QVBoxLayout()
        layout.addLayout(layout_top)
        layout.addWidget(SpacerVertical())
        layout.addWidget(SpacerVertical())
        layout.addStretch()
        layout.addLayout(layout_buttons)

        self.setLayout(layout)

        # Signals
        self.button_update.clicked.connect(self.install_update)
        self.button_cancel.clicked.connect(self.reject)
        self.button_launch.clicked.connect(self.launch)
        self.timer.timeout.connect(self.refresh)
        self.timer_2.timeout.connect(self.check_conditions)

        # Setup
        self.timer.start()
        self.timer_2.start()
        self.check_conditions()
        self.refresh()
Пример #11
0
 def sizeHint(self):
     """Override Qt method."""
     return QSize(self.compute_width(), 0)
Пример #12
0
    def __init__(self, parent, names, order, active):
        super(LayoutSettingsDialog, self).__init__(parent)

        # variables
        self._parent = parent
        self._selection_model = None
        self.names = names
        self.order = order
        self.active = active

        # widgets
        self.button_move_up = QPushButton(_('Move Up'))
        self.button_move_down = QPushButton(_('Move Down'))
        self.button_delete = QPushButton(_('Delete Layout'))
        self.button_box = QDialogButtonBox(QDialogButtonBox.Ok |
                                           QDialogButtonBox.Cancel,
                                           Qt.Horizontal, self)
        self.group_box = QGroupBox(_("Layout Display and Order"))
        self.table = QTableView(self)
        self.ok_button = self.button_box.button(QDialogButtonBox.Ok)
        self.cancel_button = self.button_box.button(QDialogButtonBox.Cancel)
        self.cancel_button.setDefault(True)
        self.cancel_button.setAutoDefault(True)

        # widget setup
        self.dialog_size = QSize(300, 200)
        self.setMinimumSize(self.dialog_size)
        self.setFixedSize(self.dialog_size)
        self.setWindowTitle('Layout Settings')

        self.table.setModel(LayoutModel(self.table, order, active))
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table.verticalHeader().hide()
        self.table.horizontalHeader().hide()
        self.table.setAlternatingRowColors(True)
        self.table.setShowGrid(False)
        self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.setColumnHidden(1, True)
        
        # need to keep a reference for pyside not to segfault!
        self._selection_model = self.table.selectionModel()

        # layout
        buttons_layout = QVBoxLayout()
        buttons_layout.addWidget(self.button_move_up)
        buttons_layout.addWidget(self.button_move_down)
        buttons_layout.addStretch()
        buttons_layout.addWidget(self.button_delete)

        group_layout = QHBoxLayout()
        group_layout.addWidget(self.table)
        group_layout.addLayout(buttons_layout)
        self.group_box.setLayout(group_layout)

        layout = QVBoxLayout()
        layout.addWidget(self.group_box)
        layout.addWidget(self.button_box)

        self.setLayout(layout)

        # signals and slots
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.close)
        self.button_delete.clicked.connect(self.delete_layout)
        self.button_move_up.clicked.connect(lambda: self.move_layout(True))
        self.button_move_down.clicked.connect(lambda: self.move_layout(False))
        self.table.model().dataChanged.connect(
           lambda: self.selection_changed(None, None))
        self._selection_model.selectionChanged.connect(
           lambda: self.selection_changed(None, None))

        # focus table
        index = self.table.model().index(0, 0)
        self.table.setCurrentIndex(index)
        self.table.setFocus()
Пример #13
0
 def widget_size():
     """Return the size defined in the SASS file."""
     return QSize(SASS_VARIABLES.WIDGET_ENVIRONMENT_TOTAL_WIDTH,
                  SASS_VARIABLES.WIDGET_ENVIRONMENT_TOTAL_HEIGHT)
Пример #14
0
    def __init__(self,
                 parent=None,
                 hide_nav_bar=False,
                 hide_menu_bar=False,
                 hide_status_bar=False):
        super(PyDMMainWindow, self).__init__(parent)
        self.app = QApplication.instance()
        self.font_factor = 1
        self.iconFont = IconFont()
        self._display_widget = None
        self._showing_file_path_in_title_bar = False

        self._saved_menu_geometry = None
        self._saved_menu_height = None
        self._new_widget_size = None

        self.default_font_size = QApplication.instance().font().pointSizeF()

        self.home_file = None
        self.home_widget = None

        self.designer_path = None

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.navbar.setIconSize(QSize(24, 24))
        self.ui.navbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.ui.actionHome.triggered.connect(self.home_triggered)
        self.ui.actionHome.setIcon(self.iconFont.icon("home"))
        self.ui.actionBack.triggered.connect(self.back_triggered)
        self.ui.actionBack.setIcon(self.iconFont.icon("angle-left"))
        self.ui.actionForward.triggered.connect(self.forward_triggered)
        self.ui.actionForward.setIcon(self.iconFont.icon("angle-right"))
        self.ui.actionEdit_in_Designer.triggered.connect(self.edit_in_designer)
        self.ui.actionOpen_File.triggered.connect(self.open_file_action)
        self.ui.actionReload_Display.triggered.connect(self.reload_display)
        self.ui.actionIncrease_Font_Size.triggered.connect(
            self.increase_font_size)
        self.ui.actionDecrease_Font_Size.triggered.connect(
            self.decrease_font_size)
        self.ui.actionDefault_Font_Size.triggered.connect(self.reset_font_size)
        self.ui.actionEnter_Fullscreen.triggered.connect(self.enter_fullscreen)
        self.ui.actionShow_File_Path_in_Title_Bar.triggered.connect(
            self.toggle_file_path_in_title_bar)
        self.ui.actionShow_Navigation_Bar.triggered.connect(
            self.toggle_nav_bar)
        self.ui.actionShow_Menu_Bar.triggered.connect(self.toggle_menu_bar)
        self.ui.actionShow_Status_Bar.triggered.connect(self.toggle_status_bar)
        self.ui.actionShow_Connections.triggered.connect(self.show_connections)
        self.ui.actionAbout_PyDM.triggered.connect(self.show_about_window)
        self.ui.actionLoadTool.triggered.connect(self.load_tool)
        self.ui.actionLoadTool.setIcon(self.iconFont.icon("rocket"))
        self.ui.actionQuit.triggered.connect(self.quit_main_window)

        if hide_nav_bar:
            self.toggle_nav_bar(False)
        if hide_menu_bar:
            # Toggle the menu bar via the QAction so that the menu item
            # stays in sync with menu visibility.
            self.ui.actionShow_Menu_Bar.activate(QAction.Trigger)
        if hide_status_bar:
            self.toggle_status_bar(False)
        #Try to find the designer binary.
        self.ui.actionEdit_in_Designer.setEnabled(False)

        possible_designer_bin_paths = (
            QLibraryInfo.location(QLibraryInfo.BinariesPath),
            QLibraryInfo.location(QLibraryInfo.LibraryExecutablesPath))
        for bin_path in possible_designer_bin_paths:
            if platform.system() == 'Darwin':
                designer_path = os.path.join(
                    bin_path, 'Designer.app/Contents/MacOS/Designer')
            elif platform.system() == 'Linux':
                designer_path = os.path.join(bin_path, 'designer')
            else:
                designer_path = os.path.join(bin_path, 'designer.exe')
            if os.path.isfile(designer_path):
                self.designer_path = designer_path
                break

        self.update_tools_menu()
        self.enable_disable_navigation()
Пример #15
0
 def minimumSizeHint(self):
     return QSize(30, 30)
Пример #16
0
 def sizeHint(self):
     """Return the size required to show the entire message."""
     return QSize(
         super().sizeHint().width(),
         self.row2_widget.height() + self.message.sizeHint().height(),
     )
Пример #17
0
 def move_to_bottom_right(self, offset=(8, 8)):
     """Position widget at the bottom right edge of the parent."""
     if not self.parent():
         return
     sz = self.parent().size() - self.size() - QSize(*offset)
     self.move(QPoint(sz.width(), sz.height()))
def test_mainwindow_init(mainwindow):
    """Test that the mainwindow is initialized correctly."""
    assert mainwindow
    assert mainwindow.size() == QSize(*INIT_MAINWINDOW_SIZE)
    assert mainwindow._workdir == get_home_dir()
Пример #19
0
 def sizeHint(self):
     w, h = self.get_width_height()
     return QSize(w, h)
Пример #20
0
class PyDMSymbol(QWidget, PyDMWidget):
    """
    PyDMSymbol will render an image (symbol) for each value of a channel.

    Parameters
    ----------
    parent : QWidget
        The parent widget for the Label
    init_channel : str, optional
        The channel to be used by the widget.
    """
    def __init__(self, parent=None, init_channel=None):
        QWidget.__init__(self, parent)
        PyDMWidget.__init__(self, init_channel=init_channel)
        if 'Index' not in PyDMSymbol.RULE_PROPERTIES:
            PyDMSymbol.RULE_PROPERTIES = PyDMWidget.RULE_PROPERTIES.copy()
            PyDMSymbol.RULE_PROPERTIES.update(
                {'Index': ['set_current_key', object]})
        self.app = QApplication.instance()
        self._current_key = 0
        self._state_images_string = ""
        self._state_images = {}  # Keyed on state values (ints), values are (filename, qpixmap or qsvgrenderer) tuples.
        self._aspect_ratio_mode = Qt.KeepAspectRatio
        self._sizeHint = self.minimumSizeHint()
        self._painter = QPainter()

    def init_for_designer(self):
        """
        Method called after the constructor to tweak configurations for
        when using the widget with the Qt Designer
        """
        self.value = 0
        self._current_key = 0

    def set_current_key(self, current_key):
        """
        Change the image being displayed for the one given by `current_key`.

        Parameters
        ----------
        current_key : object
            The current_key parameter can be of any type as long as it matches
            the type used as key for the imageFiles dictionary.

        """
        if self._current_key != current_key:
            self._current_key = current_key
            self.update()

    @Property(str)
    def imageFiles(self):
        """
        JSON-formatted dictionary keyed on states (integers), with filenames
        of the image file to display for the state.

        Returns
        -------
        str
        """
        if not self._state_images:
            return self._state_images_string
        return json.dumps({str(state): val[0] for (state, val) in self._state_images.items()})

    @imageFiles.setter
    def imageFiles(self, new_files):
        """
        JSON-formatted dictionary keyed on states (integers), with filenames
        of the image file to display for the state.

        Parameters
        ----------
        new_files : str
        """
        self._state_images_string = str(new_files)
        try:
            new_file_dict = json.loads(self._state_images_string)
        except Exception:
            self._state_images = {}
            return
        self._sizeHint = QSize(0, 0)
        for (state, filename) in new_file_dict.items():
            if is_pydm_app():
                try:
                    file_path = self.app.get_path(filename)
                except Exception as e:
                    logger.exception("Couldn't get file with path %s", filename)
                    file_path = filename
            else:
                file_path = filename
            # First, lets try SVG.  We have to try SVG first, otherwise
            # QPixmap will happily load the SVG and turn it into a raster image.
            # Really annoying: We have to try to load the file as SVG,
            # and we expect it will fail often (because many images aren't SVG).
            # Qt prints a warning message to stdout any time SVG loading fails.
            # So we have to temporarily silence Qt warning messages here.
            qInstallMessageHandler(self.qt_message_handler)
            svg = QSvgRenderer()
            svg.repaintNeeded.connect(self.update)
            if svg.load(file_path):
                self._state_images[int(state)] = (filename, svg)
                self._sizeHint = self._sizeHint.expandedTo(svg.defaultSize())
                qInstallMessageHandler(None)
                continue
            qInstallMessageHandler(None)
            # SVG didn't work, lets try QPixmap
            image = QPixmap(file_path)
            if not image.isNull():
                self._state_images[int(state)] = (filename, image)
                self._sizeHint = self._sizeHint.expandedTo(image.size())
                continue
            # If we get this far, the file specified could not be loaded at all.
            logger.error("Could not load image: {}".format(filename))
            self._state_images[int(state)] = (filename, None)

    @Property(Qt.AspectRatioMode)
    def aspectRatioMode(self):
        """
        Which aspect ratio mode to use.

        Returns
        -------
        Qt.AspectRatioMode
        """
        return self._aspect_ratio_mode

    @aspectRatioMode.setter
    def aspectRatioMode(self, new_mode):
        """
        Which aspect ratio mode to use.

        Parameters
        -----------
        new_mode : Qt.AspectRatioMode
        """
        if new_mode != self._aspect_ratio_mode:
            self._aspect_ratio_mode = new_mode
            self.update()

    def connection_changed(self, connected):
        """
        Callback invoked when the connection state of the Channel is changed.
        This callback acts on the connection state to enable/disable the widget
        and also trigger the change on alarm severity to ALARM_DISCONNECTED.

        Parameters
        ----------
        connected : int
            When this value is 0 the channel is disconnected, 1 otherwise.
        """
        super(PyDMSymbol, self).connection_changed(connected)
        self.update()

    def value_changed(self, new_val):
        """
        Callback invoked when the Channel value is changed.

        Parameters
        ----------
        new_val : int
            The new value from the channel.
        """
        super(PyDMSymbol, self).value_changed(new_val)
        self._current_key = new_val
        self.update()

    def sizeHint(self):
        """
        This property holds the recommended size for the widget.

        Returns
        -------
        QSize
        """
        return self._sizeHint

    def minimumSizeHint(self):
        """
        This property holds the recommended minimum size for the widget.

        Returns
        -------
        QSize
        """
        return QSize(10, 10)  # This is totally arbitrary, I just want *some* visible nonzero size

    def paintEvent(self, event):
        """
        Paint events are sent to widgets that need to update themselves,
        for instance when part of a widget is exposed because a covering
        widget was moved.

        At PyDMSymbol this method handles the alarm painting with parameters
        from the stylesheet and draws the proper image.

        Parameters
        ----------
        event : QPaintEvent
        """
        self._painter.begin(self)
        opt = QStyleOption()
        opt.initFrom(self)
        self.style().drawPrimitive(QStyle.PE_Widget, opt, self._painter, self)
        # self._painter.setRenderHint(QPainter.Antialiasing)
        if self._current_key is None:
            self._painter.end()
            return
        image_to_draw = self._state_images.get(self._current_key, (None, None))[1]
        if image_to_draw is None:
            self._painter.end()
            return
        if isinstance(image_to_draw, QPixmap):
            w = float(image_to_draw.width())
            h = float(image_to_draw.height())
            if self._aspect_ratio_mode == Qt.IgnoreAspectRatio:
                scale = (event.rect().width() / w, event.rect().height() / h)
            elif self._aspect_ratio_mode == Qt.KeepAspectRatio:
                sf = min(event.rect().width() / w, event.rect().height() / h)
                scale = (sf, sf)
            elif self._aspect_ratio_mode == Qt.KeepAspectRatioByExpanding:
                sf = max(event.rect().width() / w, event.rect().height() / h)
                scale = (sf, sf)
            self._painter.scale(scale[0], scale[1])
            self._painter.drawPixmap(event.rect().x(), event.rect().y(), image_to_draw)
        elif isinstance(image_to_draw, QSvgRenderer):
            draw_size = QSizeF(image_to_draw.defaultSize())
            draw_size.scale(QSizeF(event.rect().size()), self._aspect_ratio_mode)
            image_to_draw.render(self._painter, QRectF(0.0, 0.0, draw_size.width(), draw_size.height()))
        self._painter.end()

    def qt_message_handler(self, msg_type, *args):
        # Intentionally suppress all qt messages.  Make sure not to leave this handler installed.
        pass
Пример #21
0
    def __init__(self, parent, prefix, name, action, version, versions, packages_sizes, active_channels):
        super(CondaPackageActionDialog, self).__init__(parent)
        self._parent = parent
        self._prefix = prefix
        self._version_text = None
        self._name = name
        self._dependencies_dic = {}
        self._active_channels = active_channels
        self._packages_sizes = packages_sizes
        self.api = ManagerAPI()

        # Widgets
        self.label = QLabel(self)
        self.combobox_version = QComboBox()
        self.label_version = QLabel(self)
        self.widget_version = None
        self.table_dependencies = None

        self.checkbox = QCheckBox(_("Install dependencies (recommended)"))
        self.bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)

        self.button_ok = self.bbox.button(QDialogButtonBox.Ok)
        self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel)

        self.button_cancel.setDefault(True)
        self.button_cancel.setAutoDefault(True)

        dialog_size = QSize(300, 90)

        # Helper variable values
        action_title = {
            C.ACTION_UPGRADE: _("Upgrade package"),
            C.ACTION_DOWNGRADE: _("Downgrade package"),
            C.ACTION_REMOVE: _("Remove package"),
            C.ACTION_INSTALL: _("Install package"),
        }

        # FIXME: There is a bug, a package installed by anaconda has version
        # astropy 0.4 and the linked list 0.4 but the available versions
        # in the json file do not include 0.4 but 0.4rc1... so...
        # temporal fix is to check if inside list otherwise show full list
        if action == C.ACTION_UPGRADE:
            if version in versions:
                index = versions.index(version)
                combo_versions = versions[index + 1 :]
            else:
                versions = versions
        elif action == C.ACTION_DOWNGRADE:
            if version in versions:
                index = versions.index(version)
                combo_versions = versions[:index]
            else:
                versions = versions
        elif action == C.ACTION_REMOVE:
            combo_versions = [version]
            self.combobox_version.setEnabled(False)
        elif action == C.ACTION_INSTALL:
            combo_versions = versions

        # Reverse order for combobox
        combo_versions = list(reversed(combo_versions))

        if len(versions) == 1:
            if action == C.ACTION_REMOVE:
                labeltext = _("Package version to remove:")
            else:
                labeltext = _("Package version available:")
            self.label_version.setText(combo_versions[0])
            self.widget_version = self.label_version
        else:
            labeltext = _("Select package version:")
            self.combobox_version.addItems(combo_versions)
            self.widget_version = self.combobox_version

        self.label.setText(labeltext)
        self.label_version.setAlignment(Qt.AlignLeft)
        self.table_dependencies = QWidget(self)

        layout = QVBoxLayout()
        version_layout = QHBoxLayout()
        version_layout.addWidget(self.label)
        version_layout.addStretch()
        version_layout.addWidget(self.widget_version)
        layout.addLayout(version_layout)

        self.widgets = [self.checkbox, self.button_ok, self.widget_version, self.table_dependencies]

        # Create a Table
        if action in [C.ACTION_INSTALL, C.ACTION_UPGRADE, C.ACTION_DOWNGRADE]:
            table = QTableView(self)
            dialog_size = QSize(dialog_size.width() + 40, 300)
            self.table_dependencies = table
            layout.addWidget(self.checkbox)
            self.checkbox.setChecked(True)
            self._changed_version(versions[0])

            table.setSelectionBehavior(QAbstractItemView.SelectRows)
            table.verticalHeader().hide()
            table.horizontalHeader().hide()
            table.setAlternatingRowColors(True)
            table.setShowGrid(False)
            table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            table.horizontalHeader().setStretchLastSection(True)

        layout.addWidget(self.table_dependencies)
        layout.addWidget(self.bbox)

        title = "{0}: {1}".format(action_title[action], name)
        self.setLayout(layout)
        self.setMinimumSize(dialog_size)
        self.setFixedSize(dialog_size)
        self.setWindowTitle(title)
        self.setModal(True)

        # Signals and slots
        self.bbox.accepted.connect(self.accept)
        self.bbox.rejected.connect(self.close)
        self.combobox_version.currentIndexChanged.connect(self._changed_version)
        self.checkbox.stateChanged.connect(self._changed_checkbox)
Пример #22
0
    def paintEvent(self, event):
        """Override Qt method.

        Painting line number area
        """
        painter = QPainter(self)
        painter.fillRect(event.rect(), self.editor.sideareas_color)
        # This is needed to make that the font size of line numbers
        # be the same as the text one when zooming
        # See spyder-ide/spyder#2296 and spyder-ide/spyder#4811.
        font = self.editor.font()
        font_height = self.editor.fontMetrics().height()

        active_block = self.editor.textCursor().block()
        active_line_number = active_block.blockNumber() + 1

        def draw_pixmap(xleft, ytop, pixmap):
            if not QT55_VERSION:
                pixmap_height = pixmap.height()
            else:
                # scale pixmap height to device independent pixels
                pixmap_height = pixmap.height() / pixmap.devicePixelRatio()
            painter.drawPixmap(xleft, ytop + (font_height - pixmap_height) / 2,
                               pixmap)

        for top, line_number, block in self.editor.visible_blocks:
            if self._margin:
                if line_number == active_line_number:
                    font.setWeight(font.Bold)
                    painter.setFont(font)
                    painter.setPen(self.editor.normal_color)
                else:
                    font.setWeight(font.Normal)
                    painter.setFont(font)
                    painter.setPen(self.linenumbers_color)

                painter.drawText(0, top, self.width(), font_height,
                                 Qt.AlignRight | Qt.AlignBottom,
                                 to_text_string(line_number))

            size = self.get_markers_margin() - 2
            icon_size = QSize(size, size)

            data = block.userData()
            if self._markers_margin and data:
                if data.code_analysis:
                    errors = 0
                    warnings = 0
                    infos = 0
                    hints = 0
                    for _, _, sev, _ in data.code_analysis:
                        errors += sev == DiagnosticSeverity.ERROR
                        warnings += sev == DiagnosticSeverity.WARNING
                        infos += sev == DiagnosticSeverity.INFORMATION
                        hints += sev == DiagnosticSeverity.HINT

                    if errors:
                        draw_pixmap(1, top, self.error_icon.pixmap(icon_size))
                    elif warnings:
                        draw_pixmap(1, top,
                                    self.warning_icon.pixmap(icon_size))
                    elif infos:
                        draw_pixmap(1, top, self.info_icon.pixmap(icon_size))
                    elif hints:
                        draw_pixmap(1, top, self.hint_icon.pixmap(icon_size))

                if data.todo:
                    draw_pixmap(1, top, self.todo_icon.pixmap(icon_size))
Пример #23
0
    def setup(self):
        """Setup window parameters"""
        self.setWindowIcon(get_icon("python.png"))
        self.setWindowTitle(APP_NAME)
        self.resize(QSize(600, 800))

        # Welcome message in statusbar:
        status = self.statusBar()
        status.showMessage(_("Welcome to guiqwt application example!"), 5000)

        # File menu
        file_menu = self.menuBar().addMenu(_("File"))
        new_action = create_action(
            self,
            _("New..."),
            shortcut="Ctrl+N",
            icon=get_icon("filenew.png"),
            tip=_("Create a new image"),
            triggered=self.new_image,
        )
        open_action = create_action(
            self,
            _("Open..."),
            shortcut="Ctrl+O",
            icon=get_icon("fileopen.png"),
            tip=_("Open an image"),
            triggered=self.open_image,
        )
        quit_action = create_action(
            self,
            _("Quit"),
            shortcut="Ctrl+Q",
            icon=get_std_icon("DialogCloseButton"),
            tip=_("Quit application"),
            triggered=self.close,
        )
        add_actions(file_menu, (new_action, open_action, None, quit_action))

        # Help menu
        help_menu = self.menuBar().addMenu("?")
        about_action = create_action(
            self,
            _("About..."),
            icon=get_std_icon("MessageBoxInformation"),
            triggered=self.about,
        )
        add_actions(help_menu, (about_action, ))

        main_toolbar = self.addToolBar("Main")
        add_actions(
            main_toolbar,
            (
                new_action,
                open_action,
            ),
        )

        # Set central widget:
        toolbar = self.addToolBar("Image")
        self.mainwidget = CentralWidget(self, toolbar)
        self.setCentralWidget(self.mainwidget)
Пример #24
0
class SnippetEditor(QDialog):
    SNIPPET_VALID = _('Valid snippet')
    SNIPPET_INVALID = _('Invalid snippet')
    INVALID_CB_CSS = "QComboBox {border: 1px solid red;}"
    VALID_CB_CSS = "QComboBox {border: 1px solid green;}"
    INVALID_LINE_CSS = "QLineEdit {border: 1px solid red;}"
    VALID_LINE_CSS = "QLineEdit {border: 1px solid green;}"
    MIN_SIZE = QSize(850, 600)

    def __init__(self,
                 parent,
                 language=None,
                 trigger_text='',
                 description='',
                 snippet_text='',
                 remove_trigger=False,
                 trigger_texts=[],
                 descriptions=[]):
        super(SnippetEditor, self).__init__(parent)

        snippet_description = _(
            "To add a new text snippet, you need to define the text "
            "that triggers it, a short description (two words maximum) "
            "of the snippet and if it should delete the trigger text when "
            "inserted. Finally, you need to define the snippet body to insert."
        )

        self.parent = parent
        self.trigger_text = trigger_text
        self.description = description
        self.remove_trigger = remove_trigger
        self.snippet_text = snippet_text
        self.descriptions = descriptions
        self.base_snippet = Snippet(language=language,
                                    trigger_text=trigger_text,
                                    snippet_text=snippet_text,
                                    description=description,
                                    remove_trigger=remove_trigger)

        # Widgets
        self.snippet_settings_description = QLabel(snippet_description)
        self.snippet_settings_description.setFixedWidth(450)

        # Trigger text
        self.trigger_text_label = QLabel(_('Trigger text:'))
        self.trigger_text_cb = QComboBox(self)
        self.trigger_text_cb.setEditable(True)

        # Description
        self.description_label = QLabel(_('Description:'))
        self.description_input = QLineEdit(self)

        # Remove trigger
        self.remove_trigger_cb = QCheckBox(
            _('Remove trigger text on insertion'), self)
        self.remove_trigger_cb.setToolTip(
            _('Check if the text that triggers '
              'this snippet should be removed '
              'when inserting it'))
        self.remove_trigger_cb.setChecked(self.remove_trigger)

        # Snippet body input
        self.snippet_label = QLabel(_('<b>Snippet text:</b>'))
        self.snippet_valid_label = QLabel(self.SNIPPET_INVALID, self)
        self.snippet_input = SimpleCodeEditor(None)

        # Dialog buttons
        self.bbox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        self.button_ok = self.bbox.button(QDialogButtonBox.Ok)
        self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel)

        # Widget setup
        self.setWindowTitle(_('Snippet editor'))

        self.snippet_settings_description.setWordWrap(True)
        self.trigger_text_cb.setToolTip(
            _('Trigger text for the current snippet'))
        self.trigger_text_cb.addItems(trigger_texts)

        if self.trigger_text != '':
            idx = trigger_texts.index(self.trigger_text)
            self.trigger_text_cb.setCurrentIndex(idx)

        self.description_input.setText(self.description)
        self.description_input.textChanged.connect(lambda _x: self.validate())

        text_inputs = (self.trigger_text, self.description, self.snippet_text)
        non_empty_text = all([x != '' for x in text_inputs])
        if non_empty_text:
            self.button_ok.setEnabled(True)

        self.snippet_input.setup_editor(language=language,
                                        color_scheme=CONF.get(
                                            'appearance', 'selected'),
                                        wrap=False,
                                        highlight_current_line=True,
                                        font=get_font())
        self.snippet_input.set_language(language)
        self.snippet_input.setToolTip(_('Snippet text completion to insert'))
        self.snippet_input.set_text(snippet_text)

        # Layout setup
        general_layout = QVBoxLayout()
        general_layout.addWidget(self.snippet_settings_description)

        snippet_settings_group = QGroupBox(_('Trigger information'))
        settings_layout = QGridLayout()
        settings_layout.addWidget(self.trigger_text_label, 0, 0)
        settings_layout.addWidget(self.trigger_text_cb, 0, 1)
        settings_layout.addWidget(self.description_label, 1, 0)
        settings_layout.addWidget(self.description_input, 1, 1)

        all_settings_layout = QVBoxLayout()
        all_settings_layout.addLayout(settings_layout)
        all_settings_layout.addWidget(self.remove_trigger_cb)
        snippet_settings_group.setLayout(all_settings_layout)
        general_layout.addWidget(snippet_settings_group)

        text_layout = QVBoxLayout()
        text_layout.addWidget(self.snippet_label)
        text_layout.addWidget(self.snippet_input)
        text_layout.addWidget(self.snippet_valid_label)
        general_layout.addLayout(text_layout)

        general_layout.addWidget(self.bbox)
        self.setLayout(general_layout)

        # Signals
        self.trigger_text_cb.editTextChanged.connect(self.validate)
        self.description_input.textChanged.connect(self.validate)
        self.snippet_input.textChanged.connect(self.validate)
        self.bbox.accepted.connect(self.accept)
        self.bbox.rejected.connect(self.reject)

        # Final setup
        if trigger_text != '' or snippet_text != '':
            self.validate()

    @Slot()
    def validate(self):
        trigger_text = self.trigger_text_cb.currentText()
        description_text = self.description_input.text()
        snippet_text = self.snippet_input.toPlainText()

        invalid = False
        try:
            build_snippet_ast(snippet_text)
            self.snippet_valid_label.setText(self.SNIPPET_VALID)
        except SyntaxError:
            invalid = True
            self.snippet_valid_label.setText(self.SNIPPET_INVALID)

        if trigger_text == '':
            invalid = True
            self.trigger_text_cb.setStyleSheet(self.INVALID_CB_CSS)
        else:
            self.trigger_text_cb.setStyleSheet(self.VALID_CB_CSS)

        if trigger_text in self.descriptions:
            if self.trigger_text != trigger_text:
                if description_text in self.descriptions[trigger_text]:
                    invalid = True
                    self.description_input.setStyleSheet(self.INVALID_LINE_CSS)
                else:
                    self.description_input.setStyleSheet(self.VALID_LINE_CSS)
            else:
                if description_text != self.description:
                    if description_text in self.descriptions[trigger_text]:
                        invalid = True
                        self.description_input.setStyleSheet(
                            self.INVALID_LINE_CSS)
                    else:
                        self.description_input.setStyleSheet(
                            self.VALID_LINE_CSS)
                else:
                    self.description_input.setStyleSheet(self.VALID_LINE_CSS)

        self.button_ok.setEnabled(not invalid)

    def get_options(self):
        trigger_text = self.trigger_text_cb.currentText()
        description_text = self.description_input.text()
        snippet_text = self.snippet_input.toPlainText()
        remove_trigger = self.remove_trigger_cb.isChecked()
        self.base_snippet.update(trigger_text, description_text, snippet_text,
                                 remove_trigger)
        return self.base_snippet
Пример #25
0
    def __init__(self, parent, env, name, action, version, versions):
        super(CondaPackageActionDialog, self).__init__(parent)
        self._parent = parent
        self._env = env
        self._version_text = None
        self._name = name
        self._dependencies_dic = {}
        self._conda_process = \
            conda_api_q.CondaProcess(self, self._on_process_finished)

        # widgets
        self.label = QLabel(self)
        self.combobox_version = QComboBox()
        self.label_version = QLabel(self)
        self.widget_version = None
        self.table_dependencies = None

        self.checkbox = QCheckBox(_('Install dependencies (recommended)'))
        self.bbox = QDialogButtonBox(QDialogButtonBox.Ok |
                                     QDialogButtonBox.Cancel, Qt.Horizontal,
                                     self)

        self.button_ok = self.bbox.button(QDialogButtonBox.Ok)
        self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel)

        self.button_cancel.setDefault(True)
        self.button_cancel.setAutoDefault(True)

        dialog_size = QSize(300, 90)

        # helper variable values
        action_title = {const.UPGRADE: _("Upgrade package"),
                        const.DOWNGRADE: _("Downgrade package"),
                        const.REMOVE: _("Remove package"),
                        const.INSTALL: _("Install package")}

        # Versions might have duplicates from different builds
        versions = sort_versions(list(set(versions)), reverse=True)

        # FIXME: There is a bug, a package installed by anaconda has version
        # astropy 0.4 and the linked list 0.4 but the available versions
        # in the json file do not include 0.4 but 0.4rc1... so...
        # temporal fix is to check if inside list otherwise show full list
        if action == const.UPGRADE:
            if version in versions:
                index = versions.index(version)
                versions = versions[:index]
            else:
                versions = versions
        elif action == const.DOWNGRADE:
            if version in versions:
                index = versions.index(version)
                versions = versions[index+1:]
            else:
                versions = versions
        elif action == const.REMOVE:
            versions = [version]
            self.combobox_version.setEnabled(False)

        if len(versions) == 1:
            if action == const.REMOVE:
                labeltext = _('Package version to remove:')
            else:
                labeltext = _('Package version available:')
            self.label_version.setText(versions[0])
            self.widget_version = self.label_version
        else:
            labeltext = _("Select package version:")
            self.combobox_version.addItems(versions)
            self.widget_version = self.combobox_version

        self.label.setText(labeltext)
        self.label_version.setAlignment(Qt.AlignLeft)
        self.table_dependencies = QWidget(self)

        self._layout = QGridLayout()
        self._layout.addWidget(self.label, 0, 0, Qt.AlignVCenter |
                               Qt.AlignLeft)
        self._layout.addWidget(self.widget_version, 0, 1, Qt.AlignVCenter |
                               Qt.AlignRight)

        self.widgets = [self.checkbox, self.button_ok, self.widget_version,
                        self.table_dependencies]
        row_index = 1

        # Create a Table
        if action in [const.INSTALL, const.UPGRADE, const.DOWNGRADE]:
            table = QTableView(self)
            dialog_size = QSize(dialog_size.width() + 40, 300)
            self.table_dependencies = table
            row_index = 1
            self._layout.addItem(QSpacerItem(10, 5), row_index, 0)
            self._layout.addWidget(self.checkbox, row_index + 1, 0, 1, 2)
            self.checkbox.setChecked(True)
            self._changed_version(versions[0])

            table.setSelectionBehavior(QAbstractItemView.SelectRows)
            table.verticalHeader().hide()
            table.horizontalHeader().hide()
            table.setAlternatingRowColors(True)
            table.setShowGrid(False)
            table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            table.horizontalHeader().setStretchLastSection(True)

        self._layout.addWidget(self.table_dependencies, row_index + 2, 0, 1, 2,
                               Qt.AlignHCenter)
        self._layout.addItem(QSpacerItem(10, 5), row_index + 3, 0)
        self._layout.addWidget(self.bbox, row_index + 6, 0, 1, 2,
                               Qt.AlignHCenter)

        title = "{0}: {1}".format(action_title[action], name)
        self.setLayout(self._layout)
        self.setMinimumSize(dialog_size)
        self.setFixedSize(dialog_size)
        self.setWindowTitle(title)
        self.setModal(True)

        # signals and slots
        self.bbox.accepted.connect(self.accept)
        self.bbox.rejected.connect(self.close)
        self.combobox_version.currentIndexChanged.connect(
            self._changed_version)
        self.checkbox.stateChanged.connect(self._changed_checkbox)
Пример #26
0
    def createSpace(self, size=5):
        """Creates a widget that can be used as spacing on  a panel."""
        qw = QWidget()
        qw.setMinimumSize(QSize(size, size))

        return qw
Пример #27
0
    def __init__(self,
                 parent,
                 data=None,
                 readonly=False,
                 bg_value=None,
                 bg_gradient='blue-red',
                 minvalue=None,
                 maxvalue=None,
                 digits=None):
        QWidget.__init__(self, parent)
        assert bg_gradient in gradient_map
        if data is not None and np.isscalar(data):
            readonly = True
        self.readonly = readonly

        # prepare internal views and models
        self.model_axes = AxesArrayModel(parent=self, readonly=readonly)
        self.view_axes = AxesView(parent=self, model=self.model_axes)

        self.model_hlabels = LabelsArrayModel(parent=self, readonly=readonly)
        self.view_hlabels = LabelsView(parent=self,
                                       model=self.model_hlabels,
                                       hpos=RIGHT,
                                       vpos=TOP)

        self.model_vlabels = LabelsArrayModel(parent=self, readonly=readonly)
        self.view_vlabels = LabelsView(parent=self,
                                       model=self.model_vlabels,
                                       hpos=LEFT,
                                       vpos=BOTTOM)

        self.model_data = DataArrayModel(parent=self,
                                         readonly=readonly,
                                         minvalue=minvalue,
                                         maxvalue=maxvalue)
        self.view_data = DataView(parent=self, model=self.model_data)

        # in case data is None
        self.data_adapter = None

        # Create vertical and horizontal scrollbars
        self.vscrollbar = ScrollBar(self, self.view_data.verticalScrollBar())
        self.hscrollbar = ScrollBar(self, self.view_data.horizontalScrollBar())

        # Synchronize resizing
        self.view_axes.horizontalHeader().sectionResized.connect(
            self.view_vlabels.updateSectionWidth)
        self.view_axes.verticalHeader().sectionResized.connect(
            self.view_hlabels.updateSectionHeight)
        self.view_hlabels.horizontalHeader().sectionResized.connect(
            self.view_data.updateSectionWidth)
        self.view_vlabels.verticalHeader().sectionResized.connect(
            self.view_data.updateSectionHeight)
        # Synchronize auto-resizing
        self.view_axes.horizontalHeader().sectionHandleDoubleClicked.connect(
            self.resize_axes_column_to_contents)
        self.view_hlabels.horizontalHeader(
        ).sectionHandleDoubleClicked.connect(
            self.resize_hlabels_column_to_contents)
        self.view_axes.verticalHeader().sectionHandleDoubleClicked.connect(
            self.resize_axes_row_to_contents)
        self.view_vlabels.verticalHeader().sectionHandleDoubleClicked.connect(
            self.resize_vlabels_row_to_contents)

        # synchronize specific methods
        self.view_axes.allSelected.connect(self.view_data.selectAll)
        self.view_data.signal_copy.connect(self.copy)
        self.view_data.signal_excel.connect(self.to_excel)
        self.view_data.signal_paste.connect(self.paste)
        self.view_data.signal_plot.connect(self.plot)

        # propagate changes (add new items in the QUndoStack attribute of MappingEditor)
        self.model_data.newChanges.connect(self.data_changed)

        # Synchronize scrolling
        # data <--> hlabels
        self.view_data.horizontalScrollBar().valueChanged.connect(
            self.view_hlabels.horizontalScrollBar().setValue)
        self.view_hlabels.horizontalScrollBar().valueChanged.connect(
            self.view_data.horizontalScrollBar().setValue)
        # data <--> vlabels
        self.view_data.verticalScrollBar().valueChanged.connect(
            self.view_vlabels.verticalScrollBar().setValue)
        self.view_vlabels.verticalScrollBar().valueChanged.connect(
            self.view_data.verticalScrollBar().setValue)

        # Synchronize selecting columns(rows) via hor.(vert.) header of x(y)labels view
        self.view_hlabels.horizontalHeader().sectionPressed.connect(
            self.view_data.selectColumn)
        self.view_hlabels.horizontalHeader().sectionEntered.connect(
            self.view_data.selectNewColumn)
        self.view_vlabels.verticalHeader().sectionPressed.connect(
            self.view_data.selectRow)
        self.view_vlabels.verticalHeader().sectionEntered.connect(
            self.view_data.selectNewRow)

        # following lines are required to keep usual selection color
        # when selecting rows/columns via headers of label views.
        # Otherwise, selected rows/columns appear in grey.
        self.view_data.setStyleSheet("""QTableView {
            selection-background-color: palette(highlight);
            selection-color: white;
        }""")

        # set external borders
        array_frame = QFrame(self)
        array_frame.setFrameStyle(QFrame.StyledPanel)
        # remove borders of internal tables
        self.view_axes.setFrameStyle(QFrame.NoFrame)
        self.view_hlabels.setFrameStyle(QFrame.NoFrame)
        self.view_vlabels.setFrameStyle(QFrame.NoFrame)
        self.view_data.setFrameStyle(QFrame.NoFrame)
        # Set layout of table views:
        # [ axes  ][hlabels]|V|
        # [vlabels][ data  ]|s|
        # |  H. scrollbar  |
        array_layout = QGridLayout()
        array_layout.addWidget(self.view_axes, 0, 0)
        array_layout.addWidget(self.view_hlabels, 0, 1)
        array_layout.addWidget(self.view_vlabels, 1, 0)
        self.view_data.setSizePolicy(QSizePolicy.Expanding,
                                     QSizePolicy.Expanding)
        array_layout.addWidget(self.view_data, 1, 1)
        array_layout.addWidget(self.vscrollbar, 0, 2, 2, 1)
        array_layout.addWidget(self.hscrollbar, 2, 0, 1, 2)
        array_layout.setSpacing(0)
        array_layout.setContentsMargins(0, 0, 0, 0)
        array_frame.setLayout(array_layout)

        # Set filters and buttons layout
        self.filters_layout = QHBoxLayout()
        self.btn_layout = QHBoxLayout()
        self.btn_layout.setAlignment(Qt.AlignLeft)

        label = QLabel("Digits")
        self.btn_layout.addWidget(label)
        spin = QSpinBox(self)
        spin.valueChanged.connect(self.digits_changed)
        self.digits_spinbox = spin
        self.btn_layout.addWidget(spin)
        self.digits = 0

        scientific = QCheckBox(_('Scientific'))
        scientific.stateChanged.connect(self.scientific_changed)
        self.scientific_checkbox = scientific
        self.btn_layout.addWidget(scientific)
        self.use_scientific = False

        gradient_chooser = QComboBox()
        gradient_chooser.setMaximumSize(120, 20)
        gradient_chooser.setIconSize(QSize(100, 20))

        pixmap = QPixmap(100, 15)
        pixmap.fill(Qt.white)
        gradient_chooser.addItem(QIcon(pixmap), " ")

        pixmap.fill(Qt.transparent)
        painter = QPainter(pixmap)
        for name, gradient in available_gradients[1:]:
            qgradient = gradient.as_qgradient()

            # * fill with white because gradient can be transparent and if we do not "start from whilte", it skews the
            #   colors.
            # * 1 and 13 instead of 0 and 15 to have a transparent border around/between the gradients
            painter.fillRect(0, 1, 100, 13, Qt.white)
            painter.fillRect(0, 1, 100, 13, qgradient)
            gradient_chooser.addItem(QIcon(pixmap), name, gradient)

        # without this, we can crash python :)
        del painter, pixmap
        # select default gradient
        # requires Qt5+
        # gradient_chooser.setCurrentText(bg_gradient)
        gradient_chooser.setCurrentIndex(
            gradient_chooser.findText(bg_gradient))
        gradient_chooser.currentIndexChanged.connect(self.gradient_changed)
        self.btn_layout.addWidget(gradient_chooser)
        self.gradient_chooser = gradient_chooser

        # Set widget layout
        layout = QVBoxLayout()
        layout.addLayout(self.filters_layout)
        layout.addWidget(array_frame)
        layout.addLayout(self.btn_layout)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        # set gradient
        self.model_data.set_bg_gradient(gradient_map[bg_gradient])

        # set data
        if data is not None:
            self.set_data(data, bg_value=bg_value, digits=digits)

        # See http://doc.qt.io/qt-4.8/qt-draganddrop-fridgemagnets-dragwidget-cpp.html for an example
        self.setAcceptDrops(True)
Пример #28
0
 def sizeHint(self):
     return QSize(self.prefixwidth, 0)