예제 #1
0
class FileWidget(QWidget):
    on_open = pyqtSignal(str)

    # TODO consider removing directory_aliases since it is not used any more
    def __init__(self,
                 dialog_title='',
                 dialog_format='',
                 start_dir=os.path.expanduser('~/'),
                 icon_size=(12, 20),
                 minimal_width=200,
                 browse_label='Browse',
                 on_open=None,
                 reload_button=True,
                 reload_label='Reload',
                 recent_files=None,
                 directory_aliases=None,
                 allow_empty=True,
                 empty_file_label='(none)'):
        """ Creates a widget with a button for file loading and
        an optional combo box for recent files and reload buttons.

        Args:
            dialog_title (str): The title of the dialog.
            dialog_format (str): Formats for the dialog.
            start_dir (str): A directory to start from.
            icon_size (int, int): The size of buttons' icons.
            on_open (callable): A callback function that accepts filepath as the only argument.
            reload_button (bool): Whether to show reload button.
            reload_label (str): The text displayed on the reload button.
            recent_files (List[str]): List of recent files.
            directory_aliases (dict): An {alias: dir} dictionary for fast directories' access.
            allow_empty (bool): Whether empty path is allowed.
        """
        super().__init__()
        self.dialog_title = dialog_title
        self.dialog_format = dialog_format
        self.start_dir = start_dir

        # Recent files should also contain `empty_file_label` so
        # when (none) is selected this is stored in settings.
        self.recent_files = recent_files if recent_files is not None else []
        self.directory_aliases = directory_aliases or {}
        self.allow_empty = allow_empty
        self.empty_file_label = empty_file_label
        if self.empty_file_label not in self.recent_files \
                and (self.allow_empty or not self.recent_files):
            self.recent_files.append(self.empty_file_label)

        self.check_existence()
        self.on_open.connect(on_open)

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        if recent_files is not None:
            self.file_combo = QComboBox()
            self.file_combo.setMinimumWidth(minimal_width)
            self.file_combo.activated[int].connect(self.select)
            self.update_combo()
            layout.addWidget(self.file_combo)

        self.browse_button = QPushButton(browse_label)
        self.browse_button.setFocusPolicy(Qt.NoFocus)
        self.browse_button.clicked.connect(self.browse)
        self.browse_button.setIcon(self.style().standardIcon(
            QStyle.SP_DirOpenIcon))
        self.browse_button.setIconSize(QSize(*icon_size))
        self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        layout.addWidget(self.browse_button)

        if reload_button:
            self.reload_button = QPushButton(reload_label)
            self.reload_button.setFocusPolicy(Qt.NoFocus)
            self.reload_button.clicked.connect(self.reload)
            self.reload_button.setIcon(self.style().standardIcon(
                QStyle.SP_BrowserReload))
            self.reload_button.setSizePolicy(QSizePolicy.Fixed,
                                             QSizePolicy.Fixed)
            self.reload_button.setIconSize(QSize(*icon_size))
            layout.addWidget(self.reload_button)

    def browse(self, start_dir=None):
        start_dir = start_dir or self.start_dir
        path, _ = QFileDialog().getOpenFileName(self, self.dialog_title,
                                                start_dir, self.dialog_format)

        if path and self.recent_files is not None:
            if path in self.recent_files:
                self.recent_files.remove(path)
            self.recent_files.insert(0, path)
            self.update_combo()

        if path:
            self.open_file(path)

    def select(self, n):
        name = self.file_combo.currentText()
        if name == self.empty_file_label:
            del self.recent_files[n]
            self.recent_files.insert(0, self.empty_file_label)
            self.update_combo()
            self.open_file(self.empty_file_label)
        elif name in self.directory_aliases:
            self.browse(self.directory_aliases[name])
        elif n < len(self.recent_files):
            name = self.recent_files[n]
            del self.recent_files[n]
            self.recent_files.insert(0, name)
            self.update_combo()
            self.open_file(self.recent_files[0])

    def update_combo(self):
        """ Sync combo values to the changes in self.recent_files. """
        if self.recent_files is not None:
            self.file_combo.clear()
            for i, file in enumerate(self.recent_files):
                # remove (none) when we have some files and allow_empty=False
                if file == self.empty_file_label and \
                        not self.allow_empty and len(self.recent_files) > 1:
                    del self.recent_files[i]
                else:
                    self.file_combo.addItem(os.path.split(file)[1])

            for alias in self.directory_aliases.keys():
                self.file_combo.addItem(alias)

    def reload(self):
        if self.recent_files:
            self.select(0)

    def check_existence(self):
        if self.recent_files:
            to_remove = []
            for file in self.recent_files:
                doc_path = os.path.join(get_sample_corpora_dir(), file)
                exists = any(os.path.exists(f) for f in [file, doc_path])
                if file != self.empty_file_label and not exists:
                    to_remove.append(file)
            for file in to_remove:
                self.recent_files.remove(file)

    def open_file(self, path):
        self.on_open.emit(path if path != self.empty_file_label else '')

    def get_selected_filename(self):
        if self.recent_files:
            return self.recent_files[0]
        else:
            return self.empty_file_label
예제 #2
0
class FileLoader(QWidget):
    activated = pyqtSignal()
    file_loaded = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.recent_paths = []

        self.file_combo = QComboBox()
        self.file_combo.setMinimumWidth(80)
        self.file_combo.activated.connect(self._activate)

        self.browse_btn = QPushButton("...")
        icon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
        self.browse_btn.setIcon(icon)
        self.browse_btn.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        self.browse_btn.clicked.connect(self.browse)

        self.load_btn = QPushButton("")
        icon = self.style().standardIcon(QStyle.SP_BrowserReload)
        self.load_btn.setIcon(icon)
        self.load_btn.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        self.load_btn.setAutoDefault(True)
        self.load_btn.clicked.connect(self.file_loaded)

    def browse(self):
        start_file = self.last_path() or os.path.expanduser("~/")
        formats = ["Text files (*.txt)", "All files (*)"]
        file_name, _ = QFileDialog.getOpenFileName(None, "Open...", start_file,
                                                   ";;".join(formats),
                                                   formats[0])
        if not file_name:
            return
        self.add_path(file_name)
        self._activate()

    def _activate(self):
        self.activated.emit()
        self.file_loaded.emit()

    def set_current_file(self, path: str):
        if path:
            self.add_path(path)
            self.file_combo.setCurrentText(path)
        else:
            self.file_combo.setCurrentText("(none)")

    def get_current_file(self) -> Optional[RecentPath]:
        index = self.file_combo.currentIndex()
        if index >= len(self.recent_paths) or index < 0:
            return None
        path = self.recent_paths[index]
        return path if isinstance(path, RecentPath) else None

    def add_path(self, filename: str):
        recent = RecentPath.create(filename, [])
        if recent in self.recent_paths:
            self.recent_paths.remove(recent)
        self.recent_paths.insert(0, recent)
        self.set_file_list()

    def set_file_list(self):
        self.file_combo.clear()
        for i, recent in enumerate(self.recent_paths):
            self.file_combo.addItem(recent.basename)
            self.file_combo.model().item(i).setToolTip(recent.abspath)
            if not os.path.exists(recent.abspath):
                self.file_combo.setItemData(i, QBrush(Qt.red),
                                            Qt.TextColorRole)
        self.file_combo.addItem(_DEFAULT_NONE)

    def last_path(self) -> Optional[str]:
        return self.recent_paths[0].abspath if self.recent_paths else None
예제 #3
0
class ControlButton(ControlBase):
    def __init__(self, *args, **kwargs):
        self._checkable = kwargs.get('checkable', False)
        super(ControlButton, self).__init__(*args, **kwargs)

        default = kwargs.get('default', None)
        if default: self.value = default

    def init_form(self):
        self._form = QPushButton()
        self._form.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self._form.setCheckable(self._checkable)
        self.label = self._label
        self._form.setToolTip(self.help)

    def click(self):
        self._form.click()

    def load_form(self, data, path=None):
        pass

    def save_form(self, data, path=None):
        pass

    ##########################################################################

    @property
    def label(self):
        return ControlBase.label.fget(self)

    @label.setter
    def label(self, value):
        ControlBase.label.fset(self, value)
        self._form.setText(self._label)

    @property
    def icon(self):
        return self._form.icon()

    @icon.setter
    def icon(self, value):
        if isinstance(value, (str, bytes)):
            self._form.setIcon(QIcon(value))
        else:
            self._form.setIcon(value)

    ##########################################################################

    @property
    def value(self):
        return None

    @value.setter
    def value(self, value):
        try:
            self._form.clicked.disconnect()  # ignore previous signals if any
        except TypeError as err:
            # http://stackoverflow.com/questions/21586643/pyqt-widget-connect-and-disconnect
            pass
        self._form.clicked[bool].connect(value)

    @property
    def checked(self):
        return self._form.isChecked()

    @checked.setter
    def checked(self, value):
        self._form.setChecked(value)
예제 #4
0
파일: MainUI.py 프로젝트: kylefortin/TacOS
class MainUI(QWidget):
    def __init__(self):
        super().__init__()
        self.left = Config.geometry[0]
        self.top = Config.geometry[1]
        self.width = Config.geometry[2]
        self.height = Config.geometry[3]
        self.setLayout(QHBoxLayout(self))

        # Init logger
        self.logger = Logger('mainUI', 'UI : Main')

        # Read in user prefs
        self.prefs = {}
        self.loadPrefs()

        # Load configured objects
        self.lights = Lights()
        self.lights.load()
        self.obas = OBAs()
        self.obas.load()
        self.tracs = Tracs()
        self.tracs.load()

        # Init I2C control
        if 'i2cAddress' in self.prefs.keys():
            _address = self.prefs['i2cAddress']
        else:
            _address = Config.defaultI2CAddress
        if 'i2cBus' in self.prefs.keys():
            _bus = self.prefs['i2cBus']
        else:
            _bus = Config.defaultI2CBus
        if 'i2cDebug' in self.prefs.keys():
            _debug = self.prefs['i2cDebug']
        else:
            _debug = False
        self._i2cBus = I2CBus(int(_bus), str(_address), bool(_debug))
        del _bus, _address, _debug

        # Create menu frame
        self._sidebarMenu = QFrame(self)
        self._sidebarMenu.layout = QVBoxLayout(self._sidebarMenu)
        self._sidebarMenu.setMaximumWidth(Config.menuWidth + 50)
        self._sidebarMenu.setMaximumHeight(Config.geometry[3])
        self._sidebarMenu.setStyleSheet(
            "QFrame{border-right: 1px solid black}")

        # Create menu
        _container = QWidget()
        _container.layout = QVBoxLayout()
        _container.setLayout(_container.layout)
        _scroll = QScrollArea()
        _scroll.setWidget(_container)
        _scroll.setWidgetResizable(True)
        self._sidebarMenu.layout.addWidget(_scroll)
        for _key in [
                'enableOBA', 'enableLighting', 'enableTracControl',
                'enableCamViewer', 'enableGyro'
        ]:
            if _key in self.prefs.keys():
                if self.prefs[_key]:
                    _title = {
                        'enableOBA': 'control_oba',
                        'enableLighting': 'control_light',
                        'enableTracControl': 'control_trac',
                        'enableCamViewer': 'control_cam',
                        'enableGyro': 'control_gyro'
                    }[_key]
                    _icon = {
                        'enableOBA':
                        Config.faIcon("wind"),
                        'enableLighting':
                        Config.faIcon("lightbulb"),
                        'enableTracControl':
                        Config.icon("tracControl", "rearDiff")['path'],
                        'enableCamViewer':
                        Config.faIcon("camera"),
                        'enableGyro':
                        Config.faIcon("truck-pickup")
                    }[_key]
                    _button = MenuButton(panel=_title, parent=self)
                    _button.setIcon(QIcon(_icon))
                    _container.layout.addWidget(_button)
        _settingsButton = MenuButton(panel="config_prefs", parent=self)
        _settingsButton.setIcon(QIcon(Config.faIcon("user-cog")))
        _container.layout.addWidget(_settingsButton)
        del _container, _scroll, _key, _settingsButton, _title, _icon, _button

        # Create version info label
        self._version = QLabel('v%s' % Config.version, self)
        self._version.setAlignment(Qt.AlignCenter)
        self._version.setFixedWidth(Config.menuWidth)
        self._version.setStyleSheet("QLabel{border: none}")
        self._sidebarMenu.layout.addWidget(self._version)

        # Create OSK button
        self._oskButton = QPushButton('', self)
        self._oskButton.setIcon(QIcon(Config.faIcon('keyboard')))
        self._oskButton.setFixedWidth(Config.menuWidth)
        self._oskButton.clicked.connect(self.showOSK)
        self._sidebarMenu.layout.addWidget(self._oskButton)

        # Add menu frame to main UI
        self.layout().addWidget(self._sidebarMenu)

        # Create main UI panel
        self._mainPanel = QWidget(self)
        self._mainPanel.setLayout(QVBoxLayout(self._mainPanel))
        self.layout().addWidget(self._mainPanel)

        # Init default UI
        for _key in [
                'enableOBA', 'enableLighting', 'enableTracControl',
                'enableCamViewer', 'enableGyro'
        ]:
            _cUI = None
            _uiName = None
            if _key in self.prefs.keys():
                if self.prefs[_key]:
                    if _key == 'enableOBA':
                        _cUI = OBAControlUI(self.obas.obas, self)
                        _uiName = 'control_oba'
                    elif _key == 'enableLighting':
                        _cUI = LightControlUI(self.lights.lights, self)
                        _uiName = 'control_light'
                    elif _key == 'enableTracControl':
                        _cUI = TracControlUI(self.tracs.tracs, self)
                        _uiName = 'control_trac'
                    elif _key == 'enableCamViewer':
                        _cUI = CamViewer(0)
                        _uiName = 'control_cam'
                    elif _key == 'enableGryo':
                        _cUI = Gyrometer()
                        _uiName = 'control_gyro'
            if _cUI is not None:
                break
        if _cUI is None:
            _cUI = UserPrefUI(self.prefs, parent=self)
            _uiName = 'config_prefs'
        self._currentUI = {'name': _uiName, 'obj': _cUI}
        _cUI.setParent(self)
        self._mainPanel.layout().addWidget(_cUI)
        _cUI.show()

        # Create button panel
        self._btnPanel = QWidget(self)
        self._btnPanel.setLayout(QHBoxLayout(self._btnPanel))
        self._mainPanel.layout().addWidget(self._btnPanel)

        # Create Config button
        self._configButton = QPushButton('Configure', self)
        self._configButton.setFixedHeight(50)
        self._configButton.setIcon(QIcon(Config.faIcon('cog')))
        self._configButton.clicked.connect(self.__configButtonAction)
        self._btnPanel.layout().addWidget(self._configButton)

        # Create Night Mode button
        self._nightModeButton = QPushButton('', self)
        self._nightModeButton.setFixedHeight(50)
        self._nightModeButton.setIcon(
            QIcon({
                True: Config.faIcon('sun'),
                False: Config.faIcon('moon')
            }[self.prefs['nightMode']]))
        self._nightModeButton.setText({
            True: 'Day Mode',
            False: 'Night Mode'
        }[self.prefs['nightMode']])
        self._nightModeButton.clicked.connect(self.toggleNightMode)
        self._btnPanel.layout().addWidget(self._nightModeButton)
        self.setNightMode(self.prefs['nightMode'])

    def closeEvent(self, event):
        self.savePrefs()
        self._i2cBus.deEnergizeAll()
        super(MainUI, self).closeEvent(event)

    def availablePins(self, value=None):
        if not self.prefs['allowDuplicatePins']:
            _pins = Config.outputPinList
            for _light in self.lights.lights:
                if _light.outputPin in _pins:
                    _pins.remove(_light.outputPin)
            for _oba in self.obas.obas:
                if _oba.outputPin in _pins:
                    _pins.remove(_oba.outputPin)
            for _trac in self.tracs.tracs:
                if _trac.outputPin in _pins:
                    _pins.remove(_trac.outputPin)
        else:
            _pins = Config.outputPinList
        _pins.sort()
        return _pins

    def setOutputPin(self, pin, state):
        fx = {
            True: self.i2cBus.energizeRelay,
            False: self.i2cBus.deEnergizeRelay
        }[state]
        fx(pin)

    def disableConfigButtons(self):
        for _ctrl in [self.configButton]:
            _ctrl.setEnabled(False)
        del _ctrl

    def enableConfigButtons(self):
        for _ctrl in [self.configButton]:
            _ctrl.setEnabled(True)
        del _ctrl

    def loadUI(self, ui, idx=None):
        if 'cam' in self.currentUI['name']:
            self.currentUI['obj'].stop()
        if 'gyro' in self.currentUI['name']:
            self.currentUI['obj'].stopSerial()
            self.currentUI['obj'].stopRotation()
        self.currentUI['obj'].hide()
        self.mainPanel.layout().removeWidget(self.currentUI['obj'])
        self.mainPanel.layout().removeWidget(self.btnPanel)
        _mode = ui.split('_')[0]
        _type = ui.split('_')[1]
        _ui = None
        if _mode == 'control':
            if _type == 'gyro':
                self.configButton.setText("Calibrate")
            else:
                self.configButton.setText("Configure")
            if _type == 'light':
                _ui = LightControlUI(self.lights.lights, self)
            elif _type == 'oba':
                _ui = OBAControlUI(self.obas.obas, self)
            elif _type == 'trac':
                _ui = TracControlUI(self.tracs.tracs, self)
            elif _type == 'cam':
                _ui = CamViewer(0)
                _ui.start()
            elif _type == 'gyro':
                _ui = Gyrometer(parent=self)
                _ui.startSerial()
                _ui.startRotation()
        elif _mode == 'config':
            if _type == 'light':
                _ui = LightConfigUI(self.lights.lights, self)
            elif _type == 'oba':
                _ui = OBAConfigUI(self.obas.obas, self)
            elif _type == 'trac':
                _ui = TracConfigUI(self.tracs.tracs, self)
            elif _type == 'prefs':
                _ui = UserPrefUI(self.prefs, self)
        elif _mode == 'edit':
            if _type == 'light':
                _ui = EditLightUI(self.lights.lights[idx], self)
            elif _type == 'oba':
                _ui = EditOBAUI(self.obas.obas[idx], self)
            elif _type == 'trac':
                _ui = EditTracUI(self.tracs.tracs[idx], self)
        elif _mode == 'create':
            if _type == 'light':
                _ui = AddLightUI(self)
            elif _type == 'oba':
                _ui = AddOBAUI(self)
            elif _type == 'trac':
                _ui = AddTracUI(self)
        if _ui is not None:
            _ui.setParent(self)
            self.mainPanel.layout().addWidget(_ui)
            _ui.show()
            self.currentUI = {'name': ui, 'obj': _ui}
        self.mainPanel.layout().addWidget(self.btnPanel)

    def toggleNightMode(self):
        _mode = self.prefs['nightMode']
        _value = {False: Config.dayBright, True: Config.nightBright}[not _mode]
        self.nightModeButton.setIcon({
            False: QIcon(Config.faIcon('sun')),
            True: QIcon(Config.faIcon('moon'))
        }[not _mode])
        self.nightModeButton.setText({
            False: 'Day Mode',
            True: 'Night Mode'
        }[not _mode])
        os.system("echo %s > /sys/class/backlight/rpi_backlight/brightness" %
                  _value)
        self.prefs['nightMode'] = not _mode
        self.savePrefs()
        self.logger.log('Night mode %s: backlight set to %s' %
                        (not _mode, _value))
        del _mode, _value

    def setNightMode(self, mode):
        _value = {False: Config.dayBright, True: Config.nightBright}[mode]
        self.nightModeButton.setIcon({
            False: QIcon(Config.faIcon('sun')),
            True: QIcon(Config.faIcon('moon'))
        }[mode])
        self.nightModeButton.setText({
            False: 'Day Mode',
            True: 'Night Mode'
        }[mode])
        os.system("echo %s > /sys/class/backlight/rpi_backlight/brightness" %
                  _value)
        del _value

    def loadPrefs(self):
        _pPrefs = open(Config.prefs, 'rb')
        _prefs = pickle.load(_pPrefs)
        for key in _prefs:
            self.prefs[key] = _prefs[key]
        _pPrefs.close()
        del _pPrefs, _prefs

    def savePrefs(self):
        _pPrefs = open(Config.prefs, 'wb')
        pickle.dump(self.prefs, _pPrefs)
        _pPrefs.close()

    def showOSK(self):
        if self.window().dock.isHidden():
            self.window().dock.show()
        else:
            self.window().dock.hide()

    def __configButtonAction(self):
        if self.currentUI['name'] not in ['control_camera', 'control_gyro']:
            self.disableConfigButtons()
            self.mainPanel.layout().removeWidget(self.currentUI['obj'])
            self.loadUI(self.currentUI['name'].replace('control', 'config'))
        elif self.currentUI['name'] == 'control_gyro':
            self.currentUI['obj'].calibrate()

    @property
    def mainPanel(self):
        return self._mainPanel

    @property
    def btnPanel(self):
        return self._btnPanel

    @property
    def nightModeButton(self):
        return self._nightModeButton

    @property
    def configButton(self):
        return self._configButton

    @property
    def currentUI(self):
        return self._currentUI

    @currentUI.setter
    def currentUI(self, value):
        self._currentUI = value

    @property
    def i2cBus(self):
        return self._i2cBus
예제 #5
0
class FileWidget(QWidget):
    on_open = pyqtSignal(str)

    def __init__(self,
                 dialog_title='',
                 dialog_format='',
                 start_dir=os.path.expanduser('~/'),
                 icon_size=(12, 20),
                 minimal_width=200,
                 browse_label='Browse',
                 on_open=None,
                 reload_button=True,
                 reload_label='Reload',
                 recent_files=None,
                 directory_aliases=None,
                 allow_empty=True,
                 empty_file_label='(none)'):
        """ Creates a widget with a button for file loading and
        an optional combo box for recent files and reload buttons.

        Args:
            dialog_title (str): The title of the dialog.
            dialog_format (str): Formats for the dialog.
            start_dir (str): A directory to start from.
            icon_size (int, int): The size of buttons' icons.
            on_open (callable): A callback function that accepts filepath as the only argument.
            reload_button (bool): Whether to show reload button.
            reload_label (str): The text displayed on the reload button.
            recent_files (List[str]): List of recent files.
            directory_aliases (dict): An {alias: dir} dictionary for fast directories' access.
            allow_empty (bool): Whether empty path is allowed.
        """
        super().__init__()
        self.dialog_title = dialog_title
        self.dialog_format = dialog_format
        self.start_dir = start_dir

        self.recent_files = recent_files
        self.directory_aliases = directory_aliases or {}
        self.check_existence()

        self.on_open.connect(on_open)
        self.allow_empty = allow_empty
        self.empty_file_label = empty_file_label

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        if recent_files is not None:
            self.file_combo = QComboBox()
            self.file_combo.setMinimumWidth(minimal_width)
            self.file_combo.activated[int].connect(self.select)
            self.update_combo()
            layout.addWidget(self.file_combo)

        self.browse_button = QPushButton(browse_label)
        self.browse_button.setFocusPolicy(Qt.NoFocus)
        self.browse_button.clicked.connect(self.browse)
        self.browse_button.setIcon(self.style().standardIcon(
            QStyle.SP_DirOpenIcon))
        self.browse_button.setIconSize(QSize(*icon_size))
        self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        layout.addWidget(self.browse_button)

        if reload_button:
            self.reload_button = QPushButton(reload_label)
            self.reload_button.setFocusPolicy(Qt.NoFocus)
            self.reload_button.clicked.connect(self.reload)
            self.reload_button.setIcon(self.style().standardIcon(
                QStyle.SP_BrowserReload))
            self.reload_button.setSizePolicy(QSizePolicy.Fixed,
                                             QSizePolicy.Fixed)
            self.reload_button.setIconSize(QSize(*icon_size))
            layout.addWidget(self.reload_button)

    def browse(self, start_dir=None):
        start_dir = start_dir or self.start_dir
        path, _ = QFileDialog().getOpenFileName(self, self.dialog_title,
                                                start_dir, self.dialog_format)

        if path and self.recent_files is not None:
            if path in self.recent_files:
                self.recent_files.remove(path)
            self.recent_files.insert(0, path)
            self.update_combo()

        self.open_file(path)

    def select(self, n):
        name = self.file_combo.currentText()
        if n < len(self.recent_files):
            name = self.recent_files[n]
            del self.recent_files[n]
            self.recent_files.insert(0, name)
            self.open_file(self.recent_files[0])
            self.update_combo()
        elif name == self.empty_file_label:
            self.open_file(self.empty_file_label)
        elif name in self.directory_aliases:
            self.browse(self.directory_aliases[name])

    def update_combo(self):
        if self.recent_files is not None:
            self.file_combo.clear()
            for file in self.recent_files:
                self.file_combo.addItem(os.path.split(file)[1])

            if self.allow_empty or not self.recent_files:
                self.file_combo.addItem(self.empty_file_label)

            for alias in self.directory_aliases.keys():
                self.file_combo.addItem(alias)

    def reload(self):
        if self.recent_files:
            self.select(0)

    def check_existence(self):
        if self.recent_files:
            to_remove = [
                file for file in self.recent_files if not os.path.exists(file)
            ]
            for file in to_remove:
                self.recent_files.remove(file)

    def open_file(self, path):
        try:
            self.on_open.emit(path if path != self.empty_file_label else '')
        except (OSError, IOError):
            self.loading_error_signal.emit('Could not open "{}".'.format(path))
예제 #6
0
class FileWidget(QWidget):
    on_open = pyqtSignal(str)

    def __init__(self, dialog_title='', dialog_format='',
                 start_dir=os.path.expanduser('~/'),
                 icon_size=(12, 20), minimal_width=200,
                 browse_label='Browse', on_open=None,
                 reload_button=True, reload_label='Reload',
                 recent_files=None, directory_aliases=None,
                 allow_empty=True, empty_file_label='(none)'):
        """ Creates a widget with a button for file loading and
        an optional combo box for recent files and reload buttons.

        Args:
            dialog_title (str): The title of the dialog.
            dialog_format (str): Formats for the dialog.
            start_dir (str): A directory to start from.
            icon_size (int, int): The size of buttons' icons.
            on_open (callable): A callback function that accepts filepath as the only argument.
            reload_button (bool): Whether to show reload button.
            reload_label (str): The text displayed on the reload button.
            recent_files (List[str]): List of recent files.
            directory_aliases (dict): An {alias: dir} dictionary for fast directories' access.
            allow_empty (bool): Whether empty path is allowed.
        """
        super().__init__()
        self.dialog_title = dialog_title
        self.dialog_format = dialog_format
        self.start_dir = start_dir

        self.recent_files = recent_files
        self.directory_aliases = directory_aliases or {}
        self.check_existence()

        self.on_open.connect(on_open)
        self.allow_empty = allow_empty
        self.empty_file_label = empty_file_label

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        if recent_files is not None:
            self.file_combo = QComboBox()
            self.file_combo.setMinimumWidth(minimal_width)
            self.file_combo.activated[int].connect(self.select)
            self.update_combo()
            layout.addWidget(self.file_combo)

        self.browse_button = QPushButton(browse_label)
        self.browse_button.setFocusPolicy(Qt.NoFocus)
        self.browse_button.clicked.connect(self.browse)
        self.browse_button.setIcon(self.style()
                                   .standardIcon(QStyle.SP_DirOpenIcon))
        self.browse_button.setIconSize(QSize(*icon_size))
        self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        layout.addWidget(self.browse_button)

        if reload_button:
            self.reload_button = QPushButton(reload_label)
            self.reload_button.setFocusPolicy(Qt.NoFocus)
            self.reload_button.clicked.connect(self.reload)
            self.reload_button.setIcon(self.style()
                                       .standardIcon(QStyle.SP_BrowserReload))
            self.reload_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            self.reload_button.setIconSize(QSize(*icon_size))
            layout.addWidget(self.reload_button)

    def browse(self, start_dir=None):
        start_dir = start_dir or self.start_dir
        path, _ = QFileDialog().getOpenFileName(self, self.dialog_title,
                                                start_dir, self.dialog_format)

        if path and self.recent_files is not None:
            if path in self.recent_files:
                self.recent_files.remove(path)
            self.recent_files.insert(0, path)
            self.update_combo()

        self.open_file(path)

    def select(self, n):
        name = self.file_combo.currentText()
        if n < len(self.recent_files):
            name = self.recent_files[n]
            del self.recent_files[n]
            self.recent_files.insert(0, name)
            self.open_file(self.recent_files[0])
            self.update_combo()
        elif name == self.empty_file_label:
            self.open_file(self.empty_file_label)
        elif name in self.directory_aliases:
            self.browse(self.directory_aliases[name])

    def update_combo(self):
        if self.recent_files is not None:
            self.file_combo.clear()
            for file in self.recent_files:
                self.file_combo.addItem(os.path.split(file)[1])

            if self.allow_empty or not self.recent_files:
                self.file_combo.addItem(self.empty_file_label)

            for alias in self.directory_aliases.keys():
                self.file_combo.addItem(alias)

    def reload(self):
        if self.recent_files:
            self.select(0)

    def check_existence(self):
        if self.recent_files:
            to_remove = [
                file for file in self.recent_files if not os.path.exists(file)
            ]
            for file in to_remove:
                self.recent_files.remove(file)

    def open_file(self, path):
        try:
            self.on_open.emit(path if path != self.empty_file_label else '')
        except (OSError, IOError):
            self.loading_error_signal.emit('Could not open "{}".'
                                           .format(path))
예제 #7
0
    def init_form(self):
        # Get the current path of the file
        rootPath = os.path.dirname(__file__)

        vlayout = QVBoxLayout()
        hlayout = QHBoxLayout()

        if _api.USED_API == _api.QT_API_PYQT5:
            hlayout.setContentsMargins(0, 0, 0, 0)
            vlayout.setContentsMargins(0, 0, 0, 0)
        elif _api.USED_API == _api.QT_API_PYQT4:
            hlayout.setMargin(0)
            vlayout.setMargin(0)

        self.setLayout(vlayout)

        # Add scroll area
        scrollarea = QScrollArea()
        self._scrollArea = scrollarea
        scrollarea.setMinimumHeight(140)
        scrollarea.setWidgetResizable(True)
        scrollarea.keyPressEvent = self.__scrollAreaKeyPressEvent
        scrollarea.keyReleaseEvent = self.__scrollAreaKeyReleaseEvent

        vlayout.addWidget(scrollarea)

        # The timeline widget
        self._time = widget = TimelineWidget(self)
        widget._scroll = scrollarea
        scrollarea.setWidget(widget)

        # Timeline zoom slider
        slider = QSlider(QtCore.Qt.Horizontal)
        slider.setFocusPolicy(QtCore.Qt.NoFocus)
        slider.setMinimum(1)
        slider.setMaximum(100)
        slider.setValue(10)
        slider.setPageStep(1)
        slider.setTickPosition(QSlider.NoTicks)  # TicksBothSides
        slider.valueChanged.connect(self.__scaleSliderChange)

        slider_label_zoom_in = QLabel()
        slider_label_zoom_out = QLabel()
        slider_label_zoom_in.setPixmap(
            conf.PYFORMS_PIXMAP_EVENTTIMELINE_ZOOM_IN)
        slider_label_zoom_out.setPixmap(
            conf.PYFORMS_PIXMAP_EVENTTIMELINE_ZOOM_OUT)

        self._zoomLabel = QLabel("100%")
        hlayout.addWidget(self._zoomLabel)
        hlayout.addWidget(slider_label_zoom_out)
        hlayout.addWidget(slider)
        hlayout.addWidget(slider_label_zoom_in)

        # Import/Export Buttons
        btn_import = QPushButton("Import")

        btn_import.setIcon(conf.PYFORMS_ICON_EVENTTIMELINE_IMPORT)
        btn_import.clicked.connect(self.__open_import_win_evt)
        btn_export = QPushButton("Export")

        btn_export.setIcon(conf.PYFORMS_ICON_EVENTTIMELINE_EXPORT)
        btn_export.clicked.connect(self.__export)
        hlayout.addWidget(btn_import)
        hlayout.addWidget(btn_export)

        vlayout.addLayout(hlayout)
예제 #8
0
class FileWidget(QWidget):
    on_open = pyqtSignal(str)

    # TODO consider removing directory_aliases since it is not used any more
    def __init__(self, dialog_title='', dialog_format='',
                 start_dir=os.path.expanduser('~/'),
                 icon_size=(12, 20), minimal_width=200,
                 browse_label='Browse', on_open=None,
                 reload_button=True, reload_label='Reload',
                 recent_files=None, directory_aliases=None,
                 allow_empty=True, empty_file_label='(none)'):
        """ Creates a widget with a button for file loading and
        an optional combo box for recent files and reload buttons.

        Args:
            dialog_title (str): The title of the dialog.
            dialog_format (str): Formats for the dialog.
            start_dir (str): A directory to start from.
            icon_size (int, int): The size of buttons' icons.
            on_open (callable): A callback function that accepts filepath as the only argument.
            reload_button (bool): Whether to show reload button.
            reload_label (str): The text displayed on the reload button.
            recent_files (List[str]): List of recent files.
            directory_aliases (dict): An {alias: dir} dictionary for fast directories' access.
            allow_empty (bool): Whether empty path is allowed.
        """
        super().__init__()
        self.dialog_title = dialog_title
        self.dialog_format = dialog_format
        self.start_dir = start_dir

        # Recent files should also contain `empty_file_label` so
        # when (none) is selected this is stored in settings.
        self.recent_files = recent_files if recent_files is not None else []
        self.directory_aliases = directory_aliases or {}
        self.allow_empty = allow_empty
        self.empty_file_label = empty_file_label
        if self.empty_file_label not in self.recent_files \
                and (self.allow_empty or not self.recent_files):
            self.recent_files.append(self.empty_file_label)

        self.check_existence()
        self.on_open.connect(on_open)

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        if recent_files is not None:
            self.file_combo = QComboBox()
            self.file_combo.setMinimumWidth(minimal_width)
            self.file_combo.activated[int].connect(self.select)
            self.update_combo()
            layout.addWidget(self.file_combo)

        self.browse_button = QPushButton(browse_label)
        self.browse_button.setFocusPolicy(Qt.NoFocus)
        self.browse_button.clicked.connect(self.browse)
        self.browse_button.setIcon(self.style()
                                   .standardIcon(QStyle.SP_DirOpenIcon))
        self.browse_button.setIconSize(QSize(*icon_size))
        self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        layout.addWidget(self.browse_button)

        if reload_button:
            self.reload_button = QPushButton(reload_label)
            self.reload_button.setFocusPolicy(Qt.NoFocus)
            self.reload_button.clicked.connect(self.reload)
            self.reload_button.setIcon(self.style()
                                       .standardIcon(QStyle.SP_BrowserReload))
            self.reload_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            self.reload_button.setIconSize(QSize(*icon_size))
            layout.addWidget(self.reload_button)

    def browse(self, start_dir=None):
        start_dir = start_dir or self.start_dir
        path, _ = QFileDialog().getOpenFileName(self, self.dialog_title,
                                                start_dir, self.dialog_format)

        if path and self.recent_files is not None:
            if path in self.recent_files:
                self.recent_files.remove(path)
            self.recent_files.insert(0, path)
            self.update_combo()

        if path:
            self.open_file(path)

    def select(self, n):
        name = self.file_combo.currentText()
        if name == self.empty_file_label:
            del self.recent_files[n]
            self.recent_files.insert(0, self.empty_file_label)
            self.update_combo()
            self.open_file(self.empty_file_label)
        elif name in self.directory_aliases:
            self.browse(self.directory_aliases[name])
        elif n < len(self.recent_files):
            name = self.recent_files[n]
            del self.recent_files[n]
            self.recent_files.insert(0, name)
            self.update_combo()
            self.open_file(self.recent_files[0])

    def update_combo(self):
        """ Sync combo values to the changes in self.recent_files. """
        if self.recent_files is not None:
            self.file_combo.clear()
            for i, file in enumerate(self.recent_files):
                # remove (none) when we have some files and allow_empty=False
                if file == self.empty_file_label and \
                        not self.allow_empty and len(self.recent_files) > 1:
                    del self.recent_files[i]
                else:
                    self.file_combo.addItem(os.path.split(file)[1])

            for alias in self.directory_aliases.keys():
                self.file_combo.addItem(alias)

    def reload(self):
        if self.recent_files:
            self.select(0)

    def check_existence(self):
        if self.recent_files:
            to_remove = []
            for file in self.recent_files:
                doc_path = os.path.join(get_sample_corpora_dir(), file)
                exists = any(os.path.exists(f) for f in [file, doc_path])
                if file != self.empty_file_label and not exists:
                    to_remove.append(file)
            for file in to_remove:
                self.recent_files.remove(file)

    def open_file(self, path):
        self.on_open.emit(path if path != self.empty_file_label else '')

    def get_selected_filename(self):
        if self.recent_files:
            return self.recent_files[0]
        else:
            return self.empty_file_label