Пример #1
0
class PageProjectType(QWizardPage):

    def __init__(self, wizard):
        super(PageProjectType, self).__init__()
        self.setTitle(_translate("PageProjectType", "Project Type"))
        self.setSubTitle(_translate("PageProjectType", "Choose the Project Type"))
        self._wizard = wizard

        vbox = QVBoxLayout(self)
        self.listWidget = QListWidget()
        vbox.addWidget(self.listWidget)
        types = settings.get_all_project_types()
        types.sort()
        index = types.index('Python')
        types.insert(0, types.pop(index))
        self.listWidget.addItems(types)
        self.listWidget.setCurrentRow(0)

        self.listWidget.itemClicked['QListWidgetItem*'].connect(self.load_pages)

    def validatePage(self):
        self._wizard.option = self.listWidget.currentItem().text()
        return True

    def load_pages(self):
        self.wizard().add_project_pages(self.listWidget.currentItem().text())
Пример #2
0
class NapalmInterfaces(QWidget):
    
    napalm_actions = (
    'Interfaces',
    'Interface IP',
    'Interfaces counters',
    )

    @update_paths
    def __init__(self, node, controller):
        super().__init__()
        self.node = node

        action_label = QLabel('Action')
        object_label = QLabel('Object')
        
        self.object_list = QListWidget()
        self.object_list.setSortingEnabled(True)
        self.object_list.itemSelectionChanged.connect(self.text_update)        
        
        self.action_list = QListWidget()
        self.action_list.setSortingEnabled(True)
        self.action_list.itemSelectionChanged.connect(self.text_update)
        self.action_list.addItems(self.napalm_actions)
        
        self.properties_edit = QConsoleEdit()
        self.properties_edit.setMinimumSize(300, 300)

        layout = QGridLayout()
        layout.addWidget(object_label, 0, 0)
        layout.addWidget(self.object_list, 1, 0)
        layout.addWidget(action_label, 0, 1)
        layout.addWidget(self.action_list, 1, 1)
        layout.addWidget(self.properties_edit, 2, 0, 1, 2)
        self.setLayout(layout)
        
    def update(self):
        self.object_list.clear()
        if 'Interfaces' in self.node.napalm_data:
            self.object_list.addItems(self.node.napalm_data['Interfaces'])
            
    def text_update(self):
        action = self.action_list.currentItem()
        object = self.object_list.currentItem()
        
        if action and object:
            self.properties_edit.clear()
            # we display a dictionnary with the following format:
            # property1: value1
            # property2: value2
            
            action, object = action.text(), object.text()
            value = str_dict(self.node.napalm_data[action][object])                
            self.properties_edit.insertPlainText(value)
                        
Пример #3
0
class SessionManager(QMainWindow):
    def __init__(self, parent=None):
        QListWidget.__init__(self, parent)
        self.setWindowTitle(tr("Saved Sessions"))
        self.setWindowFlags(Qt.Dialog)
        hideAction = QAction(self)
        hideAction.setShortcuts(["Esc", "Ctrl+W"])
        hideAction.triggered.connect(self.hide)
        self.addAction(hideAction)
        self.sessionList = QListWidget(self)
        self.sessionList.itemActivated.connect(self.loadSession)
        self.setCentralWidget(self.sessionList)
        self.toolBar = QToolBar(self)
        self.toolBar.setMovable(False)
        self.toolBar.setContextMenuPolicy(Qt.CustomContextMenu)
        self.addToolBar(Qt.BottomToolBarArea, self.toolBar)
        self.loadButton = QPushButton(tr("&Load"), self)
        self.loadButton.clicked.connect(lambda: self.loadSession(self.sessionList.currentItem()))
        self.toolBar.addWidget(self.loadButton)
        self.saveButton = QPushButton(tr("&Save"), self)
        self.saveButton.clicked.connect(saveSessionManually)
        self.saveButton.clicked.connect(self.refresh)
        self.toolBar.addWidget(self.saveButton)
        deleteAction = QAction(self)
        deleteAction.setShortcut("Del")
        deleteAction.triggered.connect(self.delete)
        self.addAction(deleteAction)
    def refresh(self):
        self.sessionList.clear()
        if os.path.exists(settings.session_folder):
            sessions = os.listdir(settings.session_folder)
            for session in sessions:
                self.sessionList.addItem(session)
    def delete(self):
        if self.sessionList.hasFocus():
            try: os.remove(os.path.join(settings.session_folder, self.sessionList.currentItem().text()))
            except: pass
            self.refresh()
    def show(self):
        self.refresh()
        QMainWindow.show(self)
    def loadSession(self, item):
        if os.path.exists(settings.session_folder):
            loadSession(os.path.join(settings.session_folder, item.text()))
        self.hide()
Пример #4
0
class ModeSelector(QDialog):
    """
    Defines a UI for selecting the mode for Mu.
    """

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

    def setup(self, modes, current_mode):
        self.setMinimumSize(600, 400)
        self.setWindowTitle(_('Select Mode'))
        widget_layout = QVBoxLayout()
        label = QLabel(_('Please select the desired mode then click "OK". '
                         'Otherwise, click "Cancel".'))
        label.setWordWrap(True)
        widget_layout.addWidget(label)
        self.setLayout(widget_layout)
        self.mode_list = QListWidget()
        self.mode_list.itemDoubleClicked.connect(self.select_and_accept)
        widget_layout.addWidget(self.mode_list)
        self.mode_list.setIconSize(QSize(48, 48))
        for name, item in modes.items():
            if not item.is_debugger:
                litem = ModeItem(item.name, item.description, item.icon,
                                 self.mode_list)
                if item.icon == current_mode:
                    self.mode_list.setCurrentItem(litem)
        self.mode_list.sortItems()
        instructions = QLabel(_('Change mode at any time by clicking '
                                'the "Mode" button containing Mu\'s logo.'))
        instructions.setWordWrap(True)
        widget_layout.addWidget(instructions)
        button_box = QDialogButtonBox(QDialogButtonBox.Ok |
                                      QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        widget_layout.addWidget(button_box)

    def select_and_accept(self):
        """
        Handler for when an item is double-clicked.
        """
        self.accept()

    def get_mode(self):
        """
        Return details of the newly selected mode.
        """
        if self.result() == QDialog.Accepted:
            return self.mode_list.currentItem().icon
        else:
            raise RuntimeError('Mode change cancelled.')
Пример #5
0
class ModeSelector(QDialog):
    """
    Defines a UI for selecting the mode for Mu.
    """

    def setup(self, modes, current_mode, theme):
        if theme == 'day':
            self.setStyleSheet(DAY_STYLE)
        elif theme == 'night':
            self.setStyleSheet(NIGHT_STYLE)
        else:
            self.setStyleSheet(CONTRAST_STYLE)
        self.setMinimumSize(600, 400)
        self.setWindowTitle(_('Select Mode'))
        widget_layout = QVBoxLayout()
        label = QLabel(_('Please select the desired mode then click "OK". '
                         'Otherwise, click "Cancel".'))
        label.setWordWrap(True)
        widget_layout.addWidget(label)
        self.setLayout(widget_layout)
        self.mode_list = QListWidget()
        widget_layout.addWidget(self.mode_list)
        self.mode_list.setIconSize(QSize(48, 48))
        for name, item in modes.items():
            if not item.is_debugger:
                ModeItem(item.name, item.description, item.icon,
                         self.mode_list)
        self.mode_list.sortItems()
        instructions = QLabel(_('You can change mode at any time by clicking '
                                'the name of the current mode shown in the '
                                'bottom right-hand corner of Mu.'))
        instructions.setWordWrap(True)
        widget_layout.addWidget(instructions)
        button_box = QDialogButtonBox(QDialogButtonBox.Ok |
                                      QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        widget_layout.addWidget(button_box)

    def get_mode(self):
        """
        Return details of the newly selected mode.
        """
        if self.result() == QDialog.Accepted:
            return self.mode_list.currentItem().icon
        else:
            raise RuntimeError('Mode change cancelled.')
Пример #6
0
class JavaScriptExceptionsPanel(SettingsPanel):
    def __init__(self, parent=None):
        super(JavaScriptExceptionsPanel, self).__init__(parent)

        domainEntryRow = custom_widgets.LineEditRow(tr("Add domain:"), self)
        self.domainEntry = domainEntryRow.lineEdit
        self.domainEntry.returnPressed.connect(self.addDomain)
        self.layout().addWidget(domainEntryRow)

        self.addDomainButton = QPushButton(tr("Add"))
        self.addDomainButton.clicked.connect(self.addDomain)
        domainEntryRow.layout().addWidget(self.addDomainButton)

        self.domainList = QListWidget(self)
        self.layout().addWidget(self.domainList)

        self.removeDomainButton = QPushButton(tr("Remove"))
        self.removeDomainButton.clicked.connect(lambda: self.removeDomain(True))
        self.layout().addWidget(self.removeDomainButton)

        self.removeAction = QAction(self)
        self.removeAction.setShortcut("Del")
        self.removeAction.triggered.connect(self.removeDomain)
        self.addAction(self.removeAction)

    def removeDomain(self, forceFocus=False):
        if self.domainList.hasFocus() or forceFocus:
            self.domainList.takeItem(self.domainList.row(self.domainList.currentItem()))

    def addDomain(self):
        self.domainList.addItem(self.domainEntry.text())
        self.domainEntry.clear()

    def loadSettings(self):
        settings.js_exceptions = settings.setting_to_list("content/JavaScriptExceptions")
        self.domainList.clear()
        for f in settings.js_exceptions:
            self.domainList.addItem(f)

    def saveSettings(self):
        settings.js_exceptions = [self.domainList.item(f).text() for f in range(0, self.domainList.count())]
        settings.settings.setValue("content/JavaScriptExceptions", settings.js_exceptions)
        settings.settings.sync()
Пример #7
0
class AdremoverSettingsPanel(SettingsPanel):
    def __init__(self, parent=None):
        super(AdremoverSettingsPanel, self).__init__(parent)

        filterEntryRow = custom_widgets.LineEditRow(tr("Add filter:"), self)
        self.filterEntry = filterEntryRow.lineEdit
        self.filterEntry.returnPressed.connect(self.addFilter)
        self.layout().addWidget(filterEntryRow)

        self.addFilterButton = QPushButton(tr("Add"))
        self.addFilterButton.clicked.connect(self.addFilter)
        filterEntryRow.layout().addWidget(self.addFilterButton)

        # Ad Remover filter list.
        self.filterList = QListWidget(self)
        self.layout().addWidget(self.filterList)

        self.removeFilterButton = QPushButton(tr("Remove"))
        self.removeFilterButton.clicked.connect(lambda: self.removeFilter(True))
        self.layout().addWidget(self.removeFilterButton)

        self.removeAction = QAction(self)
        self.removeAction.setShortcut("Del")
        self.removeAction.triggered.connect(self.removeFilter)
        self.addAction(self.removeAction)

    def removeFilter(self, forceFocus=False):
        if self.filterList.hasFocus() or forceFocus:
            self.filterList.takeItem(self.filterList.row(self.filterList.currentItem()))

    def addFilter(self):
        self.filterList.addItem(self.filterEntry.text())
        self.filterEntry.clear()

    def loadSettings(self):
        settings.load_adremover_filters()
        self.filterList.clear()
        for f in settings.adremover_filters:
            self.filterList.addItem(f)

    def saveSettings(self):
        settings.adremover_filters = [self.filterList.item(f).text() for f in range(0, self.filterList.count())]
        settings.save_adremover_filters()
class PythonDetectDialog(QDialog):

    def __init__(self, suggested, parent=None):
        super(PythonDetectDialog, self).__init__(parent, Qt.Dialog)
        self.setMaximumSize(QSize(0, 0))
        self.setWindowTitle("Configure Python Path")

        vbox = QVBoxLayout(self)
        msg_str = ("We have detected that you are using "
                   "Windows,\nplease choose the proper "
                   "Python application for you:")
        lblMessage = QLabel(self.tr(msg_str))
        vbox.addWidget(lblMessage)

        self.listPaths = QListWidget()
        self.listPaths.setSelectionMode(QListWidget.SingleSelection)
        vbox.addWidget(self.listPaths)

        hbox = QHBoxLayout()
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        btnCancel = QPushButton(self.tr("Cancel"))
        btnAccept = QPushButton(self.tr("Accept"))
        hbox.addWidget(btnCancel)
        hbox.addWidget(btnAccept)
        vbox.addLayout(hbox)

        btnAccept.clicked['bool'].connect(self._set_python_path)
        btnCancel.clicked['bool'].connect(self.close)

        for path in suggested:
            self.listPaths.addItem(path)
        self.listPaths.setCurrentRow(0)

    def _set_python_path(self):
        python_path = self.listPaths.currentItem().text()

        qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat)
        settings.PYTHON_PATH = python_path
        settings.PYTHON_EXEC = python_path
        settings.PYTHON_EXEC_CONFIGURED_BY_USER = True
        qsettings.setValue('preferences/execution/pythonExec', python_path)
        qsettings.setValue('preferences/execution/pythonExecConfigured', True)
        self.close()
Пример #9
0
class LanguageChooser(QDialog):

    newQM = QtCore.pyqtSignal(str)
    supportedLanguages = {'Español': 'es_ES',
                          'English': 'en_GB', 'Català': 'ca_ES'}

    def __init__(self, parent=None):
        super(LanguageChooser, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.setWindowTitle(i18n(
            "LanguageChooser", "Language"))
        self.widgetLayout = QVBoxLayout(self)
        self.infoLabel = QLabel(self)
        self.infoLabel.setText(i18n(
            "LanguageChooser", "Select the desired language:"))
        self.widgetLayout.addWidget(self.infoLabel)
        self.languageListWidget = QListWidget(self)
        self.widgetLayout.addWidget(self.languageListWidget)
        for language in self.supportedLanguages.keys():
            self.languageListWidget.addItem(language)

        self.buttonBox = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            QtCore.Qt.Horizontal, self)
        self.buttonBox.accepted.connect(self.changeLanguage)
        self.buttonBox.rejected.connect(self.close)
        self.widgetLayout.addWidget(self.buttonBox)

    def changeLanguage(self):

        ci = self.languageListWidget.currentItem()
        if ci:
            selected = ci.text()
            fname = self.supportedLanguages[selected]
            self.newQM.emit(fname)
        self.close()
Пример #10
0
class DataSettingsPanel(SettingsPanel):
    def __init__(self, parent=None):
        super(DataSettingsPanel, self).__init__(parent)

        # Clear history dialog.
        self.clearHistoryDialog = clear_history_dialog.ClearHistoryDialog(self)
        self.clearHistoryDialog.hide()

        self.showClearHistoryDialogButton = QPushButton(tr("Clear Data"), self)
        self.showClearHistoryDialogButton.clicked.connect(self.clearHistoryDialog.exec_)
        self.layout().addWidget(self.showClearHistoryDialogButton)

        # Remember history checkbox.
        self.rememberHistoryToggle = QCheckBox(tr("Remember &history"), self)
        self.layout().addWidget(self.rememberHistoryToggle)

        # Maximum URL length spinbox.
        self.maximumURLLengthRow = custom_widgets.SpinBoxRow(tr("Maximum URL length:"), self)
        self.maximumURLLengthRow.expander.setText(tr("characters"))
        self.maximumURLLength = self.maximumURLLengthRow.spinBox
        self.maximumURLLength.setMaximum(9999)
        self.layout().addWidget(self.maximumURLLengthRow)

        # Maximum cache size spinbox.
        # The cache is gone because it f***s Nimbus with a chainsaw.
        #self.maximumCacheSizeRow = custom_widgets.SpinBoxRow(tr("Maximum cache size:"), self)
        #self.maximumCacheSizeRow.expander.setText(tr("MB"))
        #self.maximumCacheSize = self.maximumCacheSizeRow.spinBox
        #self.maximumCacheSize.setMaximum(20000)
        #self.layout().addWidget(self.maximumCacheSizeRow)

        # Checkbox to toggle geolocation.
        self.geolocationToggle = QCheckBox(tr("Enable geo&location"), self)
        self.layout().addWidget(self.geolocationToggle)

        self.geolocationPermissionsRow = custom_widgets.Row(self)
        self.layout().addWidget(self.geolocationPermissionsRow)

        self.geolocationWhitelistColumn = custom_widgets.Column(self)
        self.geolocationPermissionsRow.addWidget(self.geolocationWhitelistColumn)

        self.geolocationWhitelistLabel = QLabel(tr("Allow these sites to track my location:"), self)
        self.geolocationWhitelistColumn.addWidget(self.geolocationWhitelistLabel)

        self.geolocationWhitelist = QListWidget(self)
        self.geolocationWhitelistColumn.addWidget(self.geolocationWhitelist)

        self.removeFromWhitelistButton = QPushButton(tr("Remove"))
        self.removeFromWhitelistButton.clicked.connect(lambda: self.geolocationWhitelist.takeItem(self.geolocationWhitelist.row(self.geolocationWhitelist.currentItem())))
        self.geolocationWhitelistColumn.addWidget(self.removeFromWhitelistButton)

        self.geolocationBlacklistColumn = custom_widgets.Column(self)
        self.geolocationPermissionsRow.addWidget(self.geolocationBlacklistColumn)

        self.geolocationBlacklistLabel = QLabel(tr("Prevent these sites from tracking my location:"), self)
        self.geolocationBlacklistColumn.addWidget(self.geolocationBlacklistLabel)

        self.geolocationBlacklist = QListWidget(self)
        self.geolocationBlacklistColumn.addWidget(self.geolocationBlacklist)

        self.removeFromBlacklistButton = QPushButton(tr("Remove"))
        self.removeFromBlacklistButton.clicked.connect(lambda: self.geolocationBlacklist.takeItem(self.geolocationBlacklist.row(self.geolocationBlacklist.currentItem())))
        self.geolocationBlacklistColumn.addWidget(self.removeFromBlacklistButton)

        self.removeAction = QAction(self)
        self.removeAction.setShortcut("Del")
        self.removeAction.triggered.connect(lambda: self.geolocationWhitelist.takeItem(self.geolocationWhitelist.row(self.geolocationWhitelist.currentItem())) if self.geolocationWhitelist.hasFocus() else self.geolocationBlacklist.takeItem(self.geolocationBlacklist.row(self.geolocationBlacklist.currentItem())))
        self.addAction(self.removeAction)

        self.layout().addWidget(custom_widgets.Expander(self))
    def loadSettings(self):
        self.maximumURLLength.setValue(settings.setting_to_int("data/MaximumURLLength"))
        #self.maximumCacheSize.setValue(settings.setting_to_int("data/MaximumCacheSize"))
        self.rememberHistoryToggle.setChecked(settings.setting_to_bool("data/RememberHistory"))
        self.geolocationToggle.setChecked(settings.setting_to_bool("network/GeolocationEnabled"))
        self.geolocationWhitelist.clear()
        for url in data.geolocation_whitelist:
            self.geolocationWhitelist.addItem(url)
        self.geolocationBlacklist.clear()
        for url in data.geolocation_blacklist:
            self.geolocationBlacklist.addItem(url)
    def saveSettings(self):
        settings.settings.setValue("data/MaximumURLLength", self.maximumURLLength.value())
        #settings.settings.setValue("data/MaximumCacheSize", self.maximumCacheSize.value())
        settings.settings.setValue("data/RememberHistory", self.rememberHistoryToggle.isChecked())
        settings.settings.setValue("network/GeolocationEnabled", self.geolocationToggle.isChecked())
        data.geolocation_whitelist = [self.geolocationWhitelist.item(authority).text() for authority in range(0, self.geolocationWhitelist.count())]
        data.geolocation_blacklist = [self.geolocationBlacklist.item(authority).text() for authority in range(0, self.geolocationBlacklist.count())]
        data.saveData()
Пример #11
0
class ConnectionSplash(QDialog):
    def __init__(self, parent):
        super().__init__(parent)
        self.setWindowTitle('New Connection')
        # Keep focus on window
        self.setModal(True)
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)

        self.remove_item = QPushButton('Remove Item')

        main_layout = QHBoxLayout()

        # Saved IP's
        saved_box = QGroupBox('Saved')
        saved_layout = QVBoxLayout()
        saved_box.setLayout(saved_layout)
        self.save_list = QListWidget()
        self.save_list.addItem('New Connection...')
        self.save_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.loaded_connections = self.load_profiles()
        self.save_list.setCurrentRow(0)
        self.save_list.clicked.connect(self.update_list_functions)
        saved_layout.addWidget(self.save_list)
        self.remove_item.setEnabled(False)
        self.remove_item.clicked.connect(self.remove_selected_item)
        saved_layout.addWidget(self.remove_item)

        # Connection
        connect_box = QGroupBox('Connection Details')
        connect_layout = QVBoxLayout()
        connect_box.setLayout(connect_layout)

        connection_options = QHBoxLayout()

        # Connection details
        host_label = QLabel('Server IP:')
        connect_layout.addWidget(host_label)
        self.address = QLineEdit()
        self.address.textChanged.connect(self.check_arguments)
        connect_layout.addWidget(self.address)
        port_label = QLabel('Port:')
        connect_layout.addWidget(port_label)
        self.port = QSpinBox()
        self.port.setMinimum(0)
        self.port.setMaximum(65536)
        self.port.setValue(30000)
        connect_layout.addWidget(self.port)
        pass_label = QLabel('Password:'******'Connect')
        self.connect.clicked.connect(self.connect_to_target)
        self.connect.setEnabled(False)
        self.save = QPushButton('Save')
        self.save.clicked.connect(self.save_connection)
        self.save.setEnabled(False)
        connection_options.addWidget(self.save)
        connection_options.addStretch()
        connection_options.addWidget(self.connect)
        connect_layout.addStretch()
        connect_layout.addLayout(connection_options)

        main_layout.addWidget(saved_box)
        main_layout.addWidget(connect_box)
        self.setLayout(main_layout)
        self.exec_()

    def load_profiles(self):
        user_dir = appdirs.user_data_dir('PySmartSwitchClient', 'JackHogan')
        if not isdir(user_dir):
            makedirs(user_dir, exist_ok=True)
        if not isfile(join(user_dir, 'profiles.json')):
            with open(join(user_dir, 'profiles.json'), 'w') as f:
                f.write('{}')
        with open(join(user_dir, 'profiles.json'), 'r+') as json_file:
            profiles = json.load(json_file)
            self.remove_item.setEnabled(len(profiles) > 0)
            for profile in profiles:
                self.save_list.addItem(profile)
            return profiles

    def closeEvent(self, event: QCloseEvent):
        self.save_all_connections()
        sys.exit(0)

    def connect_to_target(self):
        self.save_all_connections()
        self.hide()

    # Checks to make sure that all parameters are filled before allowing save/connection
    def check_arguments(self):
        ok = len(self.address.text()) > 0
        self.save.setEnabled(ok)
        self.connect.setEnabled(ok)

    def save_connection(self):
        title = QInputDialog.getText(self, 'Save Connection',
                                     'Input Connection Name:',
                                     QLineEdit.Normal, '',
                                     Qt.WindowCloseButtonHint)
        if not title[1]:
            return
        name = title[0]
        if name in self.loaded_connections:
            append_digit = 1
            while (name + ' (' + str(append_digit) +
                   ')') in self.loaded_connections:
                append_digit += 1
            self.loaded_connections[name + ' (' + str(append_digit) +
                                    ')'] = (self.address.text(),
                                            self.port.value())
            self.save_list.addItem(name + ' (' + str(append_digit) + ')')
        else:
            self.loaded_connections[name] = (self.address.text(),
                                             self.port.value())
            self.save_list.addItem(name)
        self.save_list.setCurrentRow(len(self.save_list) - 1)
        self.remove_item.setEnabled(True)

    def update_list_functions(self):
        self.remove_item.setEnabled(
            not self.save_list.currentItem().text() == 'New Connection...')
        if self.save_list.currentItem().text() == 'New Connection...':
            self.address.setText('')
            self.port.setValue(30000)
        else:
            self.address.setText(self.loaded_connections[
                self.save_list.currentItem().text()][0])
            self.port.setValue(self.loaded_connections[
                self.save_list.currentItem().text()][1])

    def remove_selected_item(self):
        self.loaded_connections.pop(self.save_list.currentItem().text())
        self.save_list.takeItem(
            self.save_list.row(self.save_list.currentItem()))
        self.update_list_functions()

    def save_all_connections(self):
        user_dir = appdirs.user_data_dir('PySmartSwitchClient', 'JackHogan')
        if isfile(join(user_dir, 'profiles.json')):
            remove(join(user_dir, 'profiles.json'))
        with open(join(user_dir, 'profiles.json'), 'w') as f:
            json.dump(self.loaded_connections, f)

    def get_port(self):
        return self.port.value()

    def get_address(self):
        return self.address.text()

    def get_pass(self):
        return self.password.text()
Пример #12
0
class CodeCompletionWidget(QFrame):

    def __init__(self, editor):
        super(CodeCompletionWidget, self).__init__(
            None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self._revision = 0
        self._block = 0
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {'a': resources.IMAGES['attribute'],
                       'f': resources.IMAGES['function'],
                       'c': resources.IMAGES['class'],
                       'm': resources.IMAGES['module']}

        self.cc = code_completion.CodeCompletion()
        self._completion_results = {}
        self._prefix = ''
        self.setVisible(False)
        self.source = ''
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        self.desktop = QApplication.instance().desktop()

        self.completion_list.itemClicked['QListWidgetItem*'].connect(self.pre_key_insert_completion)
        self._editor.document().cursorPositionChanged['const QTextCursor &'].connect(self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(
                self.completion_list.count() - move)
        return True

    def update_metadata(self, cursor):
        if settings.CODE_COMPLETION:
            if self._editor.document().revision() != self._revision and \
               cursor.block().blockNumber() != self._block:
                source = self._editor.get_text()
                source = source.encode(self._editor.encoding)
                self.cc.analyze_file(self._editor.ID, source,
                                     self._editor.indent, self._editor.useTabs)
                self._revision = self._editor.document().revision()
                self._block = cursor.block().blockNumber()

    def insert_completion(self, insert, type_=ord('a')):
        if insert != self._prefix:
            closing = ''
            if type_ in (ord('f'), ord('c')):
                closing = '()'
            extra = len(self._prefix) - len(insert)
            insertion = '%s%s' % (insert[extra:], closing)
            self._editor.textCursor().insertText(insertion)
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        desktop_geometry = self.desktop.availableGeometry(self._editor)
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        #Check new position according desktop geometry
        width = (self.completion_list.sizeHintForColumn(0) +
                 self.completion_list.verticalScrollBar().sizeHint().width() +
                 10)
        height = 200
        orientation = (point.y() + height) < desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(
                    QIcon(
                        self._icons.get(p[0], resources.IMAGES['attribute'])),
                    p[1], type=ord(p[0])))

    def set_completion_prefix(self, prefix, valid=True):
        self._prefix = prefix
        proposals = []
        proposals += [('m', item)
                      for item in self._completion_results.get('modules', [])
                      if item.startswith(prefix)]
        proposals += [('c', item)
                      for item in self._completion_results.get('classes', [])
                      if item.startswith(prefix)]
        proposals += [('a', item)
                      for item in self._completion_results.get(
                          'attributes', [])
                      if item.startswith(prefix)]
        proposals += [('f', item)
                      for item in self._completion_results.get('functions', [])
                      if item.startswith(prefix)]
        if proposals and valid:
            self.complete(proposals)
        else:
            self.hide_completer()

    def _invalid_completion_position(self):
        result = False
        cursor = self._editor.textCursor()
        cursor.movePosition(QTextCursor.StartOfLine,
                            QTextCursor.KeepAnchor)
        selection = cursor.selectedText()[:-1].split(' ')
        if len(selection) == 0 or selection[-1] == '' or \
           selection[-1].isdigit():
            result = True
        return result

    def fill_completer(self, force_completion=False):
        if not force_completion and (self._editor.cursor_inside_string() or
           self._editor.cursor_inside_comment() or
           self._invalid_completion_position()):
            return
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self._completion_results = results
        if force_completion:
            cursor = self._editor.textCursor()
            cursor.movePosition(QTextCursor.StartOfWord,
                                QTextCursor.KeepAnchor)
            prefix = cursor.selectedText()
        else:
            prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ''
        self.hide()

    def pre_key_insert_completion(self):
        type_ = ord('a')
        current = self.completion_list.currentItem()
        insert = current.text()
        if not insert.endswith(')'):
            type_ = current.type()
        self.insert_completion(insert, type_)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible() or self._editor.lang != "python":
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix, valid = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix, valid)
            self.completion_list.setCurrentRow(0)
        force_completion = (event.key() == Qt.Key_Space and
                            event.modifiers() == Qt.ControlModifier)
        if event.key() == Qt.Key_Period or force_completion:
            self.fill_completer(force_completion)
Пример #13
0
class Scheduler:
    def showDialog(self, currentCard=None):
        if currentCard:
            self.did = currentCard.did
        elif mw._selectedDeck():
            self.did = mw._selectedDeck()['id']
        else:
            return

        if not self._getCardInfo(self.did):
            showInfo('Please select an Incremental Reading deck.')
            return

        dialog = QDialog(mw)
        layout = QVBoxLayout()
        self.cardListWidget = QListWidget()
        self.cardListWidget.setAlternatingRowColors(True)
        self.cardListWidget.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.cardListWidget.setWordWrap(True)
        self.cardListWidget.itemDoubleClicked.connect(lambda: self.showBrowser(
            self.cardListWidget.currentItem().data(Qt.UserRole)['nid']))

        self._updateListItems()

        upButton = QPushButton('Up')
        upButton.clicked.connect(self._moveUp)
        downButton = QPushButton('Down')
        downButton.clicked.connect(self._moveDown)
        topButton = QPushButton('Top')
        topButton.clicked.connect(self._moveToTop)
        bottomButton = QPushButton('Bottom')
        bottomButton.clicked.connect(self._moveToBottom)
        randomizeButton = QPushButton('Randomize')
        randomizeButton.clicked.connect(self._randomize)

        controlsLayout = QHBoxLayout()
        controlsLayout.addWidget(topButton)
        controlsLayout.addWidget(upButton)
        controlsLayout.addWidget(downButton)
        controlsLayout.addWidget(bottomButton)
        controlsLayout.addStretch()
        controlsLayout.addWidget(randomizeButton)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Close
                                     | QDialogButtonBox.Save)
        buttonBox.accepted.connect(dialog.accept)
        buttonBox.rejected.connect(dialog.reject)
        buttonBox.setOrientation(Qt.Horizontal)

        layout.addLayout(controlsLayout)
        layout.addWidget(self.cardListWidget)
        layout.addWidget(buttonBox)

        dialog.setLayout(layout)
        dialog.setWindowModality(Qt.WindowModal)
        dialog.resize(500, 500)
        choice = dialog.exec_()

        if choice == 1:
            cids = []
            for i in range(self.cardListWidget.count()):
                card = self.cardListWidget.item(i).data(Qt.UserRole)
                cids.append(card['id'])

            self.reorder(cids)

    def _updateListItems(self):
        cardInfo = self._getCardInfo(self.did)
        self.cardListWidget.clear()
        posWidth = len(str(len(cardInfo) + 1))
        for i, card in enumerate(cardInfo, start=1):
            if self.settings['prioEnabled']:
                info = card['priority']
            else:
                info = str(i).zfill(posWidth)
            title = sub('\s+', ' ', stripHTML(card['title']))
            text = self.settings['organizerFormat'].format(info=info,
                                                           title=title)
            item = QListWidgetItem(text)
            item.setData(Qt.UserRole, card)
            self.cardListWidget.addItem(item)

    def _moveToTop(self):
        selected = self._getSelected()
        if not selected:
            showInfo('Please select one or several items.')
            return

        selected.reverse()
        for item in selected:
            self.cardListWidget.takeItem(self.cardListWidget.row(item))
            self.cardListWidget.insertItem(0, item)
            item.setSelected(True)

        self.cardListWidget.scrollToTop()

    def _moveUp(self):
        selected = self._getSelected()
        if not selected:
            showInfo('Please select one or several items.')
            return

        if self.cardListWidget.row(selected[0]) == 0:
            return

        for item in selected:
            row = self.cardListWidget.row(item)
            self.cardListWidget.takeItem(row)
            self.cardListWidget.insertItem(row - 1, item)
            item.setSelected(True)
            self.cardListWidget.scrollToItem(item)

    def _moveDown(self):
        selected = self._getSelected()
        if not selected:
            showInfo('Please select one or several items.')
            return

        selected.reverse()

        if (self.cardListWidget.row(
                selected[0]) == self.cardListWidget.count() - 1):
            return

        for item in selected:
            row = self.cardListWidget.row(item)
            self.cardListWidget.takeItem(row)
            self.cardListWidget.insertItem(row + 1, item)
            item.setSelected(True)
            self.cardListWidget.scrollToItem(item)

    def _moveToBottom(self):
        selected = self._getSelected()
        if not selected:
            showInfo('Please select one or several items.')
            return

        for item in selected:
            self.cardListWidget.takeItem(self.cardListWidget.row(item))
            self.cardListWidget.insertItem(self.cardListWidget.count(), item)
            item.setSelected(True)

        self.cardListWidget.scrollToBottom()

    def _getSelected(self):
        return [
            self.cardListWidget.item(i)
            for i in range(self.cardListWidget.count())
            if self.cardListWidget.item(i).isSelected()
        ]

    def _randomize(self):
        allItems = [
            self.cardListWidget.takeItem(0)
            for _ in range(self.cardListWidget.count())
        ]
        if self.settings['prioEnabled']:
            maxPrio = len(self.settings['priorities']) - 1
            for item in allItems:
                priority = item.data(Qt.UserRole)['priority']
                if priority != '':
                    item.contNewPos = gauss(maxPrio - int(priority),
                                            maxPrio / 20)
                else:
                    item.contNewPos = float('inf')
            allItems.sort(key=lambda item: item.contNewPos)

        else:
            shuffle(allItems)

        for item in allItems:
            self.cardListWidget.addItem(item)

    def answer(self, card, ease):
        if self.settings['prioEnabled']:
            # reposition the card at the end of the organizer
            cardCount = len(self._getCardInfo(card.did))
            self.reposition(card, cardCount)
            return

        if ease == SCHEDULE_EXTRACT:
            value = self.settings['extractValue']
            randomize = self.settings['extractRandom']
            method = self.settings['extractMethod']
        elif ease == SCHEDULE_SOON:
            value = self.settings['soonValue']
            randomize = self.settings['soonRandom']
            method = self.settings['soonMethod']
        elif ease == SCHEDULE_LATER:
            value = self.settings['laterValue']
            randomize = self.settings['laterRandom']
            method = self.settings['laterMethod']
        elif ease == SCHEDULE_CUSTOM:
            self.reposition(card, 1)
            self.showDialog(card)
            return

        if method == 'percent':
            totalCards = len([c['id'] for c in self._getCardInfo(card.did)])
            newPos = totalCards * (value / 100)
        elif method == 'count':
            newPos = value

        if randomize:
            newPos = gauss(newPos, newPos / 10)

        newPos = max(1, round(newPos))
        self.reposition(card, newPos)

        if ease != SCHEDULE_EXTRACT:
            tooltip('Card moved to position {}'.format(newPos))

    def reposition(self, card, newPos):
        cids = [c['id'] for c in self._getCardInfo(card.did)]
        mw.col.sched.forgetCards(cids)
        cids.remove(card.id)
        newOrder = cids[:newPos - 1] + [card.id] + cids[newPos - 1:]
        mw.col.sched.sortCards(newOrder)

    def reorder(self, cids):
        mw.col.sched.forgetCards(cids)
        mw.col.sched.sortCards(cids)

    def _getCardInfo(self, did):
        cardInfo = []

        for cid, nid in mw.col.db.execute(
                'select id, nid from cards where did = ?', did):
            note = mw.col.getNote(nid)
            if note.model()['name'] == self.settings['modelName']:
                if self.settings['prioEnabled']:
                    prio = note[self.settings['prioField']]
                else:
                    prio = None

                cardInfo.append({
                    'id': cid,
                    'nid': nid,
                    'title': note[self.settings['titleField']],
                    'priority': prio
                })

        return cardInfo

    def showBrowser(self, nid):
        browser = dialogs.open('Browser', mw)
        browser.form.searchEdit.lineEdit().setText('nid:' + str(nid))
        browser.onSearchActivated()
Пример #14
0
class SettingsDialog(QDialog):
    def __init__(self, parent=None):
        super(SettingsDialog, self).__init__(parent)
        self.currentDirectories = []
        # self.addDirectories(directories)
        self.initButtons()
        self.initUi()

        self.restoreSettings()
        self.setLibraryDirectoriesWidget()

    def saveSettings(self):
        settings = QtCore.QSettings(
            QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope,
            QtCore.QCoreApplication.organizationName(),
            QtCore.QCoreApplication.applicationName())

        settings.beginGroup("preferences")
        settings.beginWriteArray('library_directories',
                                 len(self.currentDirectories))

        for index, value in enumerate(self.currentDirectories):
            settings.setArrayIndex(index)
            settings.setValue("url", value)
        settings.endArray()
        settings.endGroup()

    def restoreSettings(self):
        settings = QtCore.QSettings(
            QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope,
            QtCore.QCoreApplication.organizationName(),
            QtCore.QCoreApplication.applicationName())

#        settings.setValue("preferences_window/position", self.pos())

        settings.beginGroup("preferences")
        size = settings.beginReadArray('library_directories')
        if not size == 0:
            for i in range(0, size):
                settings.setArrayIndex(i)
                url = settings.value("url")
                self.currentDirectories.append(url)
        settings.endArray()
        settings.endGroup()

    def initButtons(self):
        self.libraryDirectories = QLabel()
        self.libraryDirectories.setText("Library Directories")
        self.libraryDirectories.setAlignment(QtCore.Qt.AlignLeft)

        self.addButton = QPushButton("Add Directory")
        self.addButton.clicked.connect(self._onAdd)

        self.removeButton = QPushButton("Remove Directory")
        self.removeButton.clicked.connect(self._onRemove)

        self.directoriesList = QListWidget(self)

    def addDirectories(self, directories):
        if not isinstance(directories, list):
            directories = [directories]

        for directory in directories:
            self.currentDirectories.append(directory)

    def setLibraryDirectoriesWidget(self):
        for directory in self.currentDirectories:
            newItem = QListWidgetItem(directory, self.directoriesList)

    def _onAdd(self):
        directories = self.choose_directory()
        if not directories:
            return None

        for directory in directories:
            if directory not in self.currentDirectories:
                self.currentDirectories.append(directory)
                newItem = QListWidgetItem(directory, self.directoriesList)

    def _onRemove(self):
        currentItem = self.directoriesList.currentItem()
        row = self.directoriesList.indexFromItem(currentItem).row()
        if currentItem:
            self.directoriesList.takeItem(row)
            self.currentDirectories.remove(currentItem.data(
                QtCore.Qt.DisplayRole))

    def choose_directory(self):
        fileDialog = QFileDialog(self)
        fileDialog.setAcceptMode(QFileDialog.AcceptOpen)
        fileDialog.setFileMode(QFileDialog.Directory)
        fileDialog.setViewMode(QFileDialog.Detail)
        fileDialog.setWindowTitle("Choose Media Directory")
        try:
            fileDialog.setDirectory(QtCore.QStandardPaths.standardLocations(
                                    QtCore.QStandardPaths.MusicLocation)[0])
        except IndexError:
            fileDialog.setDirectory(QtCore.QDir.homePath())

        if fileDialog.exec_() == QDialog.Accepted:
            return fileDialog.selectedFiles()

    def initUi(self):
        self.directoriesButtonsLayout = QVBoxLayout()
        self.directoriesButtonsLayout.addWidget(self.addButton)
        self.directoriesButtonsLayout.addWidget(self.removeButton)
        self.directoriesButtonsLayout.addSpacing(10)

        self.directoriesLayout = QHBoxLayout()
        self.directoriesLayout.addWidget(self.directoriesList)
        self.directoriesLayout.addLayout(self.directoriesButtonsLayout)

        self.closeButton = QPushButton("Close")
        self.saveButton = QPushButton("Save")

        self.closeButton.clicked.connect(self.reject)
        self.saveButton.clicked.connect(self.accept)

        self.bottomButtonsLayout = QHBoxLayout()
        self.bottomButtonsLayout.addStretch(1)
        self.bottomButtonsLayout.addSpacing(12)
        self.bottomButtonsLayout.addWidget(self.saveButton)
        self.bottomButtonsLayout.addWidget(self.closeButton)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.libraryDirectories)
        mainLayout.addLayout(self.directoriesLayout)
        mainLayout.addLayout(self.bottomButtonsLayout)
        self.setLayout(mainLayout)

        self.setWindowTitle("Settings")
        self.setMinimumSize(450, 340)
        self.resize(680, 420)
class Theme(QWidget):
    """Theme widget class."""

    def __init__(self, parent):
        super(Theme, self).__init__()
        self._preferences, vbox = parent, QVBoxLayout(self)
        vbox.addWidget(QLabel(self.tr("<b>Select Theme:</b>")))
        self.list_skins = QListWidget()
        self.list_skins.setSelectionMode(QListWidget.SingleSelection)
        vbox.addWidget(self.list_skins)
        self.btn_delete = QPushButton(self.tr("Delete Theme"))
        self.btn_preview = QPushButton(self.tr("Preview Theme"))
        self.btn_create = QPushButton(self.tr("Create Theme"))
        hbox = QHBoxLayout()
        hbox.addWidget(self.btn_delete)
        hbox.addSpacerItem(QSpacerItem(10, 0, QSizePolicy.Expanding,
                           QSizePolicy.Fixed))
        hbox.addWidget(self.btn_preview)
        hbox.addWidget(self.btn_create)
        vbox.addLayout(hbox)
        self._refresh_list()

        self.btn_preview.clicked['bool'].connect(self.preview_theme)
        self.btn_delete.clicked['bool'].connect(self.delete_theme)
        self.btn_create.clicked['bool'].connect(self.create_theme)

        self._preferences.savePreferences.connect(self.save)

    def delete_theme(self):
        if self.list_skins.currentRow() != 0:
            file_name = ("%s.qss" % self.list_skins.currentItem().text())
            qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD,
                                                file_name)
            file_manager.delete_file(qss_file)
            self._refresh_list()

    def create_theme(self):
        designer = preferences_theme_editor.ThemeEditor(self)
        designer.exec_()
        self._refresh_list()

    def showEvent(self, event):
        self._refresh_list()
        super(Theme, self).showEvent(event)

    def _refresh_list(self):
        self.list_skins.clear()
        self.list_skins.addItem("Default")

        files = [file_manager.get_file_name(filename) for filename in
                 file_manager.get_files_from_folder(
                     resources.NINJA_THEME_DOWNLOAD, "qss")]
        files.sort()
        self.list_skins.addItems(files)

        if settings.NINJA_SKIN in files:
            index = files.index(settings.NINJA_SKIN)
            self.list_skins.setCurrentRow(index + 1)
        else:
            self.list_skins.setCurrentRow(0)

    def save(self):
        qsettings = IDE.ninja_settings()
        settings.NINJA_SKIN = self.list_skins.currentItem().text()
        qsettings.setValue("preferences/theme/skin", settings.NINJA_SKIN)
        self.preview_theme()

    def preview_theme(self):
        if self.list_skins.currentRow() == 0:
            qss_file = resources.NINJA_THEME
        else:
            file_name = ("%s.qss" % self.list_skins.currentItem().text())
            qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD,
                                                file_name)
        with open(qss_file) as f:
            qss = f.read()
        QApplication.instance().setStyleSheet(qss)
Пример #16
0
class UI(QWidget):
    def __init__(self):
        super().__init__()
        self.width: any = None
        self.height: any = None

        self.input_open_button: QPushButton = None
        self.input_clear_button: QPushButton = None
        self.input_list: QListWidget = None
        self.input_input_label: QLabel = None

        self.method_calculate_button: QPushButton = None
        self.method_reset_button: QPushButton = None
        self.method_combobox: QComboBox = None
        self.method_method_used_label: QLabel = None
        self.method_intial_interval_textbox: QPlainTextEdit = None

        self.output_save_button: QPushButton = None
        self.output_clear_button: QPushButton = None
        self.output_textbox: QPlainTextEdit = None
        self.output_output_label: QLabel = None

        # 3d
        self.figure1 = plt.figure()
        self.canvas1 = FigureCanvas(self.figure1)

        # 2d
        self.figure2 = plt.figure()
        self.canvas2 = FigureCanvas(self.figure2)

        # graph error message box
        self.graph_error_texbox: QPlainTextEdit = None

        self.grid_layout: QGridLayout = None

        self.hbox1: QHBoxLayout = None
        self.hbox2: QHBoxLayout = None
        self.hbox: QHBoxLayout = None
        self.vbox: QVBoxLayout = None

        self.open_file_location: str = os.path.dirname(
            os.path.abspath(__file__))
        self.save_file_location: str = os.path.dirname(
            os.path.abspath(__file__))

        self.methods = list(Methods.keys())

        self.initUI()

    def initUI(self):
        self.grid_layout = QGridLayout()
        self.setLayout(self.grid_layout)
        self.grid_layout.setHorizontalSpacing(50)

        # create 5 blocks
        self.create_input_block()
        self.create_method_used_block()
        self.create_output_block()
        self.create_graph_block()

        self.setGeometry(170, 100, 1600, 75E0)
        #self.setMinimumSize(1600, 500)
        self.setWindowTitle('Project2-Optimization')

        self.width = self.frameGeometry().width()
        self.height = self.frameGeometry().height()
        self.show()

    def create_input_block(self):

        self.input_open_button = QPushButton("open")
        self.input_open_button.setSizePolicy(QSizePolicy.Fixed,
                                             QSizePolicy.Fixed)
        self.input_open_button.clicked.connect(self.open_file_dialog)

        self.input_clear_button = QPushButton("clear")
        self.input_clear_button.setSizePolicy(QSizePolicy.Fixed,
                                              QSizePolicy.Fixed)
        self.input_clear_button.clicked.connect(self.input_clear)

        self.input_input_label = QLabel('Input:')

        input_h_box = QHBoxLayout()
        input_h_box.addWidget(self.input_open_button)
        input_h_box.addSpacing(50)
        input_h_box.addWidget(self.input_clear_button)

        self.input_list = QListWidget()

        input_v_box = QVBoxLayout()
        input_v_box.addWidget(self.input_input_label)
        input_v_box.addWidget(self.input_list)

        input_v_box.addLayout(input_h_box)
        self.grid_layout.addLayout(input_v_box, 0, 0)

    def create_method_used_block(self):
        # Combo Box to be used
        self.method_combobox = QComboBox(self)
        self.method_combobox.addItems(self.methods)

        # Buttons to be used
        self.method_reset_button = QPushButton("reset")
        self.method_reset_button.setSizePolicy(QSizePolicy.Fixed,
                                               QSizePolicy.Fixed)
        self.method_reset_button.clicked.connect(self.method_reset)

        self.method_calculate_button = QPushButton("calculate")
        self.method_calculate_button.setSizePolicy(QSizePolicy.Fixed,
                                                   QSizePolicy.Fixed)
        self.method_calculate_button.clicked.connect(self.method_calculate)

        # Qlabel to be used
        self.method_method_used_label = QLabel('Method Used:')
        self.method_intial_interval_textbox = QPlainTextEdit()

        method_h2_box = QHBoxLayout()
        method_h2_box.addWidget(self.method_reset_button)
        method_h2_box.addWidget(self.method_calculate_button)

        method_v_box = QVBoxLayout()
        method_v_box.addWidget(self.method_method_used_label)
        method_v_box.addWidget(self.method_combobox)
        method_v_box.addWidget(self.method_intial_interval_textbox)

        method_v_box.addLayout(method_h2_box)
        self.grid_layout.addLayout(method_v_box, 0, 1)

    def create_output_block(self):
        self.output_textbox = QPlainTextEdit(QWidget().resize(640, 480))
        self.output_textbox.setReadOnly(True)

        self.output_save_button = QPushButton("save")
        self.output_save_button.setSizePolicy(QSizePolicy.Fixed,
                                              QSizePolicy.Fixed)
        self.output_save_button.clicked.connect(self.save_file_dialog)

        self.output_clear_button = QPushButton("clear")
        self.output_clear_button.setSizePolicy(QSizePolicy.Fixed,
                                               QSizePolicy.Fixed)
        self.output_clear_button.clicked.connect(self.output_clear)

        self.output_output_label = QLabel('Output:')

        output_h_box = QHBoxLayout()
        output_h_box.addWidget(self.output_save_button)
        output_h_box.addWidget(self.output_clear_button)

        output_v_box = QVBoxLayout()
        output_v_box.addWidget(self.output_output_label)
        output_v_box.addWidget(self.output_textbox)

        output_v_box.addLayout(output_h_box)
        self.grid_layout.addLayout(output_v_box, 1, 0, 1, 2)

    def create_graph_block(self):
        ''' plot some random stuff '''
        self.figure1.suptitle('3d')
        self.figure2.suptitle('2d')

        self.canvas1.draw()
        self.canvas2.draw()
        # self.figure2.legend()

        self.graph_error_texbox = QPlainTextEdit('Default graph(NULL)')
        self.graph_error_texbox.setReadOnly(True)
        self.graph_error_texbox.setMinimumSize(640, 110)

        self.hbox1 = QHBoxLayout()
        self.hbox2 = QHBoxLayout()
        self.hbox = QHBoxLayout()
        self.vbox = QVBoxLayout()

        self.hbox1.addWidget(self.canvas1)
        self.hbox2.addWidget(self.canvas2)
        self.hbox.addLayout(self.hbox1)
        self.hbox.addLayout(self.hbox2)
        self.vbox.addLayout(self.hbox)
        self.vbox.addWidget(self.graph_error_texbox)

        self.grid_layout.addLayout(self.vbox, 0, 2, 2, 2)

    def open_file_dialog(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Open file",
                                                  self.open_file_location,
                                                  "Text Files (*.txt)")
        temp_pos = filename.rfind('/')
        if temp_pos:
            self.open_file_location = filename[:temp_pos + 1]

        if filename:
            with open(filename, 'rb') as file:
                read_data = file.read()
                udatabtype = read_data.decode("utf-8")
                asciidatabtype = udatabtype.encode("ascii", "ignore")
                asciidata = asciidatabtype.decode("ascii")
                read_data_list = asciidata.splitlines()
                self.input_list.addItems(read_data_list)

    def save_file_dialog(self):
        filename, _ = QFileDialog.getSaveFileName(self, "Save File",
                                                  self.save_file_location,
                                                  "Text Files (*.txt)")
        temp_pos = filename.rfind('/')
        self.save_file_location = filename[:temp_pos + 1]

        if filename:
            with open(filename, 'w') as file:
                file.write(self.output_textbox.toPlainText())
            self.output_clear()

    def input_clear(self):
        self.input_list.clear()

    def output_clear(self):
        # clear textbox
        self.output_textbox.clear()
        # clear graph
        ''' clear windows '''
        plt.figure(1)
        plt.clf()
        plt.figure(2)
        plt.clf()
        plt.close('all')
        ''' plot some random stuff '''
        self.figure1 = plt.figure()
        self.figure2 = plt.figure()
        self.canvas1 = FigureCanvas(self.figure1)
        self.canvas2 = FigureCanvas(self.figure2)

        self.figure1.suptitle('3d')
        self.figure2.suptitle('2d')

        self.canvas1.draw()
        self.canvas2.draw()

        self.grid_layout.removeItem(self.hbox1)
        self.grid_layout.removeItem(self.hbox2)
        self.grid_layout.removeItem(self.hbox)
        self.grid_layout.removeItem(self.vbox)

        self.graph_error_texbox.setPlainText('Default graph(NULL)')

        self.hbox1 = QHBoxLayout()
        self.hbox2 = QHBoxLayout()
        self.hbox = QHBoxLayout()
        self.vbox = QVBoxLayout()

        self.hbox1.addWidget(self.canvas1)
        self.hbox2.addWidget(self.canvas2)
        self.hbox.addLayout(self.hbox1)
        self.hbox.addLayout(self.hbox2)
        self.vbox.addLayout(self.hbox)
        self.vbox.addWidget(self.graph_error_texbox)

        self.grid_layout.addLayout(self.vbox, 0, 2, 2, 2)

    def method_reset(self):
        self.method_intial_interval_textbox.setPlainText('')
        self.method_combobox.setCurrentIndex(0)

    def method_calculate(self):
        initial_interval = self.method_intial_interval_textbox.toPlainText()
        method = self.method_combobox.currentText()
        equation_item = self.input_list.currentItem()

        if equation_item is None:
            self.output_textbox.setPlainText('No equation string detected!\n')
            return

        elif method == 'None----':
            self.output_textbox.setPlainText('Method couldnt be None\n')
            return

        elif initial_interval == '':
            self.output_textbox.setPlainText('No initial point\n')
            return

        # global variables
        equation_str: str = None
        initial_point: List[float] = None
        intervals: List[List[float]] = None
        answer: str = None
        Xs: List[Arrai] = None
        vars_form: List[str] = None

        # exception added
        try:
            equation_str = equation_item.text()
            # get initial point and intervals
            initial_point, vars_form, intervals = get_ip_intervals(
                initial_interval)

            # manager = Manager(equation_str, vars_form, method, initial_point, intervals)
            manager = Manager(equation_str=equation_str,
                              vars_form=vars_form,
                              method_name=method,
                              initial_point=initial_point,
                              intervals=intervals)
            answer, Xs = manager.run()

            # write answer to output
            self.output_textbox.setPlainText(answer)

        except Exception as explosion:
            answer = explosion.args[0]
            self.output_textbox.setPlainText(answer)

        try:
            # draw out graph
            draw_graph(self, equation_str, vars_form, Xs, intervals)

        # catch graph drawing exception
        except:
            self.graph_error_texbox.setPlainText(
                'Error while building graph!\n Current Equation: %s' %
                equation_str)

    def resizeEvent(self, a0: QResizeEvent) -> None:
        HeightIncreasement = self.frameGeometry().height() - self.height
        temp_size = 30

        if abs(HeightIncreasement) - temp_size >= 0:
            # no pointer could be used in python
            self.change_font(self.input_input_label,
                             HeightIncreasement / temp_size)
            self.change_font(self.method_method_used_label,
                             HeightIncreasement / temp_size)
            self.change_font(self.output_output_label,
                             HeightIncreasement / temp_size)
            self.change_font(self.input_open_button,
                             HeightIncreasement / temp_size)
            self.change_font(self.input_clear_button,
                             HeightIncreasement / temp_size)
            self.change_font(self.method_calculate_button,
                             HeightIncreasement / temp_size)
            self.change_font(self.method_reset_button,
                             HeightIncreasement / temp_size)
            self.change_font(self.output_save_button,
                             HeightIncreasement / temp_size)
            self.change_font(self.output_clear_button,
                             HeightIncreasement / temp_size)
            self.change_font(self.method_combobox,
                             HeightIncreasement / temp_size)

            self.width = self.frameGeometry().width()
            self.height = self.frameGeometry().height()

    @staticmethod
    def change_font(label: QLabel, increasement: int):
        font = label.font()
        font.setPointSize(font.pointSize() + increasement)
        if font.pointSize() > 8:
            label.setFont(font)
Пример #17
0
class Example(QWidget):
    def __init__(self, parent=None):
        super(Example, self).__init__(parent)
        QApplication.setStyle(QStyleFactory.create('Fusion'))

        # -------------- QCOMBOBOX ----------------------
        cbx = QComboBox()
        # agregar lista de nombres de estilos disponibles
        cbx.addItems(QStyleFactory.keys())
        # responder al evento cambio de texto
        cbx.currentTextChanged.connect(self.textChanged)
        # seleccionar el ultimo elemento
        cbx.setItemText(4, 'Fusion')

        # -------------- QLISTWIDGET ---------------------
        items = ['Ubuntu', 'Linux', 'Mac OS', 'Windows', 'Fedora', 'Chrome OS', 'Android', 'Windows Phone']

        self.lv = QListWidget()
        self.lv.addItems(items)
        self.lv.itemSelectionChanged.connect(self.itemChanged)

        # -------------- QTABLEWIDGET --------------------
        self.table = QTableWidget(10, 3)
        # establecer nombre de cabecera de las columnas
        self.table.setHorizontalHeaderLabels(['Nombre', 'Edad', 'Nacionalidad'])
        # evento producido cuando cambia el elemento seleccionado
        self.table.itemSelectionChanged.connect(self.tableItemChanged)
        # alternar color de fila
        self.table.setAlternatingRowColors(True)
        # seleccionar solo filas
        self.table.setSelectionBehavior(QTableWidget.SelectRows)
        # usar seleccion simple, una fila a la vez
        self.table.setSelectionMode(QTableWidget.SingleSelection)

        table_data = [
            ("Alice", 15, "Panama"),
            ("Dana", 25, "Chile"),
            ("Fernada", 18, "Ecuador")
        ]

        # agregar cada uno de los elementos al QTableWidget
        for i, (name, age, city) in enumerate(table_data):
            self.table.setItem(i, 0, QTableWidgetItem(name))
            self.table.setItem(i, 1, QTableWidgetItem(str(age)))
            self.table.setItem(i, 2, QTableWidgetItem(city))

        vbx = QVBoxLayout()
        vbx.addWidget(QPushButton('Tutoriales PyQT-5'))
        vbx.setAlignment(Qt.AlignTop)
        vbx.addWidget(cbx)
        vbx.addWidget(self.lv)
        vbx.addWidget(self.table)

        self.setWindowTitle("Items View")
        self.resize(362, 320)
        self.setLayout(vbx)

    def textChanged(self, txt):
        QApplication.setStyle(QStyleFactory.create(txt))

    def itemChanged(self):
        item = QListWidgetItem(self.lv.currentItem())
        print("Sistema seleccionado: ", item.text())

    def tableItemChanged(self):
        name, age, city = self.table.selectedItems()
        print("Data:", name.text(), age.text(), city.text())
Пример #18
0
class MainWindow(QMainWindow):
    htmlReady = pyqtSignal(str)

    def __init__(self, app):
        QMainWindow.__init__(self)
        self.install_directory = os.getcwd()

        self.app = app
        self.book = None
        self.last_book = ""
        self.filename = ""
        self._part_is_new = False
        self.tread_running = False
        self.initTheme()
        self.createUi()
        self.createMenus()
        self.createStatusBar()
        self.readSettings()
        self.text_edit.textChanged.connect(self.textChanged)

    def initTheme(self):
        settings = QSettings(QSettings.IniFormat, QSettings.UserScope, QCoreApplication.organizationName(), QCoreApplication.applicationName())
        self.theme = settings.value("theme", "DarkFusion")
        hilite_color = settings.value("hiliteColor", self.palette().highlight().color().name())
        self.changeStyle(self.theme, hilite_color)

    def showEvent(self, event):
        if self.last_book:
            self.loadBook(self.last_book)

    def changeStyle(self, theme, hilite_color):
        self.theme = theme
        if theme == "DarkFusion":
            QApplication.setStyle(DarkFusion(hilite_color))
        else:
            QApplication.setStyle(QStyleFactory.create(theme))
            pal = self.app.palette()
            pal.setColor(QPalette.Highlight, QColor(hilite_color))
            self.app.setPalette(pal)

    def createUi(self):
        self.content = Expander("Content", ":/images/parts.svg")
        self.images = Expander("Images", ":/images/images.svg")
        self.settings = Expander("Settings", ":/images/settings.svg")

        self.setWindowTitle(QCoreApplication.applicationName() + " " + QCoreApplication.applicationVersion())
        vbox = QVBoxLayout()
        vbox.addWidget(self.content)
        vbox.addWidget(self.images)
        vbox.addWidget(self.settings)
        vbox.addStretch()

        self.content_list = QListWidget()
        self.content_list.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        content_box = QVBoxLayout()
        content_box.addWidget(self.content_list)
        self.item_edit = QLineEdit()
        self.item_edit.setMaximumHeight(0)
        self.item_edit.editingFinished.connect(self.editItemFinished)
        self.item_anim = QPropertyAnimation(self.item_edit, "maximumHeight".encode("utf-8"))
        content_box.addWidget(self.item_edit)
        button_layout = QHBoxLayout()
        plus_button = FlatButton(":/images/plus.svg")
        self.edit_button = FlatButton(":/images/edit.svg")
        self.trash_button = FlatButton(":/images/trash.svg")
        self.up_button = FlatButton(":/images/up.svg")
        self.down_button = FlatButton(":/images/down.svg")
        self.trash_button.enabled = False
        self.up_button.enabled = False
        self.down_button.enabled = False
        button_layout.addWidget(plus_button)
        button_layout.addWidget(self.up_button)
        button_layout.addWidget(self.down_button)
        button_layout.addWidget(self.edit_button)
        button_layout.addWidget(self.trash_button)
        content_box.addLayout(button_layout)
        self.content.addLayout(content_box)
        plus_button.clicked.connect(self.addPart)
        self.trash_button.clicked.connect(self.dropPart)
        self.up_button.clicked.connect(self.partUp)
        self.down_button.clicked.connect(self.partDown)
        self.edit_button.clicked.connect(self.editPart)

        self.image_list = QListWidget()
        self.image_list.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
        image_box = QVBoxLayout()
        image_box.addWidget(self.image_list)
        image_button_layout = QHBoxLayout()
        image_plus_button = FlatButton(":/images/plus.svg")
        self.image_trash_button = FlatButton(":/images/trash.svg")
        self.image_trash_button.enabled = False
        image_button_layout.addWidget(image_plus_button)
        image_button_layout.addWidget(self.image_trash_button)
        image_box.addLayout(image_button_layout)
        self.images.addLayout(image_box)
        image_plus_button.clicked.connect(self.addImage)
        self.image_trash_button.clicked.connect(self.dropImage)

        scroll_content = QWidget()
        scroll_content.setLayout(vbox)
        scroll = QScrollArea()
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll.setWidget(scroll_content)
        scroll.setWidgetResizable(True)
        scroll.setMaximumWidth(200)
        scroll.setMinimumWidth(200)

        self.navigationdock = QDockWidget("Navigation", self)
        self.navigationdock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.navigationdock.setWidget(scroll)
        self.navigationdock.setObjectName("Navigation")
        self.addDockWidget(Qt.LeftDockWidgetArea, self.navigationdock)

        self.splitter = QSplitter()
        self.text_edit = MarkdownEdit()
        self.text_edit.setFont(QFont("Courier", 11))
        self.preview = QWebEngineView()
        self.preview.setMinimumWidth(300)
        self.setWindowTitle(QCoreApplication.applicationName())

        self.splitter.addWidget(self.text_edit)
        self.splitter.addWidget(self.preview)
        self.setCentralWidget(self.splitter)

        self.content.expanded.connect(self.contentExpanded)
        self.images.expanded.connect(self.imagesExpanded)
        self.settings.expanded.connect(self.settingsExpanded)
        self.settings.clicked.connect(self.openSettings)
        self.content_list.currentItemChanged.connect(self.partSelectionChanged)
        self.image_list.currentItemChanged.connect(self.imageSelectionChanged)
        self.image_list.itemDoubleClicked.connect(self.insertImage)

        self.text_edit.undoAvailable.connect(self.undoAvailable)
        self.text_edit.redoAvailable.connect(self.redoAvailable)
        self.text_edit.copyAvailable.connect(self.copyAvailable)

        QApplication.clipboard().dataChanged.connect(self.clipboardDataChanged)

    def undoAvailable(self, value):
        self.undo_act.setEnabled(value)

    def redoAvailable(self, value):
        self.redo_act.setEnabled(value)

    def copyAvailable(self, value):
        self.copy_act.setEnabled(value)
        self.cut_act.setEnabled(value)

    def clipboardDataChanged(self):
        md = QApplication.clipboard().mimeData()
        self.paste_act.setEnabled(md.hasText())

    def openSettings(self):
        dlg = Settings(self.book, self.install_directory)
        dlg.exec()
        if dlg.saved:
            self.setWindowTitle(QCoreApplication.applicationName() + " - " + self.book.name)

    def addPart(self):
        self.item_edit.setText("")
        self.item_edit.setFocus()
        self.item_anim.setStartValue(0)
        self.item_anim.setEndValue(23)
        self.item_anim.start()
        self._part_is_new = True

    def addItem(self):
        text = self.item_edit.text()
        if text:
            if not self.book.getPart(text):
                self.book.addPart(text)
                self.loadBook(self.last_book)

    def updateItem(self):
        text = self.item_edit.text()
        if text:
            if not self.book.getPart(text):
                self.book.updatePart(self.content_list.currentItem().data(1).name, text)
                self.loadBook(self.last_book)

    def editItemFinished(self):
        if self._part_is_new:
            self.addItem()
        else:
            self.updateItem()
        self.item_anim.setStartValue(23)
        self.item_anim.setEndValue(0)
        self.item_anim.start()

    def editPart(self):
        item = self.content_list.currentItem().data(1).name
        self.item_edit.setText(item)
        self.item_edit.setFocus()
        self.item_anim.setStartValue(0)
        self.item_anim.setEndValue(23)
        self.item_anim.start()
        self._part_is_new = False

    def dropPart(self):
        item = self.content_list.currentItem().data(1).name
        msgBox = QMessageBox()
        msgBox.setText("You are about to delete the part <i>" + item + "</i>")
        msgBox.setInformativeText("Do you really want to delete the item?")
        msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel)
        msgBox.setDefaultButton(QMessageBox.Cancel)
        ret = msgBox.exec()
        if ret == QMessageBox.Yes:
            self.book.dropPart(item)
            self.loadBook(self.last_book)

    def addImage(self):
        fileName = ""
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setNameFilter("Image Files(*.png *.jpg *.bmp *.gif);;All (*)")
        dialog.setWindowTitle("Load Image")
        dialog.setOption(QFileDialog.DontUseNativeDialog, True)
        dialog.setAcceptMode(QFileDialog.AcceptOpen)
        if dialog.exec_():
            fileName = dialog.selectedFiles()[0]
        del dialog
        if not fileName:
            return

        base = os.path.basename(fileName)
        if not os.path.exists(os.path.join(self.book.source_path, "images", base)):
            copy(fileName, os.path.join(self.book.source_path, "images"))
        item = QListWidgetItem()
        item.setText(Path(fileName).name)
        item.setData(1, os.path.join(self.book.source_path, "images", Path(fileName).name))
        self.image_list.addItem(item)

    def dropImage(self):
        item = self.image_list.currentItem()
        image = item.data(1)
        filename = os.path.join(self.book.source_path, "parts", image)
        os.remove(filename)
        self.loadImages()

    def loadImages(self):
        self.image_list.clear()
        for root, dir, files in os.walk(os.path.join(self.book.source_path, "images")):
            for file in files:
                filename = os.path.join(self.book.source_path, "images", Path(file).name)
                item = QListWidgetItem()
                item.setToolTip("Doubleclick image to insert into text")
                item.setText(Path(file).name)
                item.setData(1, filename)
                self.image_list.addItem(item)

    def partUp(self):
        pos = self.content_list.currentRow()
        item = self.content_list.takeItem(pos)
        self.content_list.insertItem(pos - 1, item)
        self.content_list.setCurrentRow(pos - 1)
        self.book.partUp(item.data(1).name)

    def partDown(self):
        pos = self.content_list.currentRow()
        item = self.content_list.takeItem(pos)
        self.content_list.insertItem(pos + 1, item)
        self.content_list.setCurrentRow(pos + 1)
        self.book.partDown(item.data(1).name)

    def partSelectionChanged(self, item):
        if item:
            part = item.data(1)
            self.filename = os.path.join(self.book.source_path, "parts", part.src)
            with open(self.filename, "r") as f:
                self.text_edit.setText(f.read())
            self.trash_button.enabled = True
            self.up_button.enabled = self.content_list.currentRow() > 0
            self.down_button.enabled = self.content_list.currentRow() < self.content_list.count() - 1
            self.edit_button.enabled = True
        else:
            self.text_edit.setText("")
            self.trash_button.enabled = False
            self.up_button.enabled = False
            self.down_button.enabled = False
            self.edit_button.enabled = False

    def imageSelectionChanged(self, item):
        if item:
            self.image_trash_button.enabled = True
        else:
            self.image_trash_button.enabled = False

    def contentExpanded(self, value):
        if value:
            self.images.setExpanded(False)
            self.settings.setExpanded(False)

    def imagesExpanded(self, value):
        if value:
            self.content.setExpanded(False)
            self.settings.setExpanded(False)

    def appearanceExpanded(self, value):
        if value:
            self.content.setExpanded(False)
            self.images.setExpanded(False)
            self.settings.setExpanded(False)

    def settingsExpanded(self, value):
        if value:
            self.content.setExpanded(False)
            self.images.setExpanded(False)

    def closeEvent(self, event):
        self.writeSettings()
        event.accept()

    def createMenus(self):
        new_icon = QIcon(QPixmap(":/images/new.svg"))
        open_icon = QIcon(QPixmap(":/images/open.svg"))
        book_icon = QIcon(QPixmap(":/images/book.svg"))
        bold_icon = QIcon(QPixmap(":/images/bold.svg"))
        italic_icon = QIcon(QPixmap(":/images/italic.svg"))
        image_icon = QIcon(QPixmap(":/images/image.svg"))
        table_icon = QIcon(QPixmap(":/images/table.svg"))
        á_icon = QIcon(QPixmap(":/images/á.svg"))
        ã_icon = QIcon(QPixmap(":/images/ã.svg"))
        é_icon = QIcon(QPixmap(":/images/é.svg"))
        ê_icon = QIcon(QPixmap(":/images/ê.svg"))
        ó_icon = QIcon(QPixmap(":/images/ó.svg"))

        new_act = QAction(new_icon, "&New", self)
        new_act.setShortcuts(QKeySequence.New)
        new_act.setStatusTip("Create a new ebook project")
        new_act.triggered.connect(self.newFile)
        new_act.setToolTip("Create new ebook project")

        open_act = QAction(open_icon, "&Open", self)
        open_act.setShortcuts(QKeySequence.Open)
        open_act.setStatusTip("Open an existing ebook project")
        open_act.triggered.connect(self.open)
        open_act.setToolTip("Open an existing ebook project")

        book_act = QAction(book_icon, "&Create Book", self)
        book_act.setShortcuts(QKeySequence.SaveAs)
        book_act.setStatusTip("Create an ebook")
        book_act.triggered.connect(self.create)
        book_act.setToolTip("Create an ebook")

        pdf_act = QAction("Create &PDF", self)
        pdf_act.setStatusTip("Create PDF")
        pdf_act.setToolTip("Create PDF")
        pdf_act.triggered.connect(self.pdfExport)

        settings_act = QAction("&Settings", self)
        settings_act.setStatusTip("Open settings dialog")
        settings_act.triggered.connect(self.settingsDialog)
        settings_act.setToolTip("Open settings dialog")

        exit_act = QAction("E&xit", self)
        exit_act.setShortcuts(QKeySequence.Quit)
        exit_act.setStatusTip("Exit the application")
        exit_act.triggered.connect(self.close)

        self.undo_act = QAction("Undo", self)
        self.undo_act.setShortcut(QKeySequence.Undo)
        self.undo_act.setEnabled(False)
        self.undo_act.triggered.connect(self.doUndo)

        self.redo_act = QAction("Redo", self)
        self.redo_act.setShortcut(QKeySequence.Redo)
        self.redo_act.setEnabled(False)
        self.undo_act.triggered.connect(self.doRedo)

        self.cut_act = QAction("Cu&t", self)
        self.cut_act.setShortcut(QKeySequence.Cut)
        self.cut_act.triggered.connect(self.doCut)
        self.cut_act.setEnabled(False)

        self.copy_act = QAction("&Copy", self)
        self.copy_act.setShortcut(QKeySequence.Copy)
        self.copy_act.triggered.connect(self.doCopy)
        self.copy_act.setEnabled(False)

        self.paste_act = QAction("&Paste", self)
        self.paste_act.setShortcut(QKeySequence.Paste)
        self.paste_act.triggered.connect(self.doPaste)
        self.paste_act.setEnabled(False)

        bold_act = QAction(bold_icon, "Bold", self)
        bold_act.setShortcut(Qt.CTRL + Qt.Key_B)
        bold_act.triggered.connect(self.bold)

        italic_act = QAction(italic_icon, "Italic", self)
        italic_act.setShortcut(Qt.CTRL + Qt.Key_I)
        italic_act.triggered.connect(self.italic)

        image_act = QAction(image_icon, "Image", self)
        image_act.setShortcut(Qt.CTRL + Qt.Key_G)
        image_act.triggered.connect(self.insertImage)
        image_act.setToolTip("Insert an image")

        table_act = QAction(table_icon, "Table", self)
        table_act.setShortcut(Qt.CTRL + Qt.Key_T)
        table_act.triggered.connect(self.insertTable)
        table_act.setToolTip("Insert a table")

        á_act = QAction(á_icon, "á", self)
        á_act.triggered.connect(self.insertLetterA1)
        á_act.setToolTip("Insert letter á")

        ã_act = QAction(ã_icon, "ã", self)
        ã_act.triggered.connect(self.insertLetterA2)
        ã_act.setToolTip("Insert letter ã")

        é_act = QAction(é_icon, "é", self)
        é_act.triggered.connect(self.insertLetterE1)
        é_act.setToolTip("Insert letter é")

        ê_act = QAction(ê_icon, "ê", self)
        ê_act.triggered.connect(self.insertLetterE2)
        ê_act.setToolTip("Insert letter ê")

        ó_act = QAction(ó_icon, "ó", self)
        ó_act.triggered.connect(self.insertLetterO1)
        ó_act.setToolTip("Insert letter ó")

        about_act = QAction("&About", self)
        about_act.triggered.connect(self.about)
        about_act.setStatusTip("Show the application's About box")

        spell_act = QAction("&Spellcheck", self)
        spell_act.setShortcut(Qt.CTRL + Qt.Key_P)
        spell_act.triggered.connect(self.spellCheck)
        spell_act.setStatusTip("Spellcheck")

        file_menu = self.menuBar().addMenu("&File")
        file_menu.addAction(new_act)
        file_menu.addAction(open_act)
        file_menu.addAction(book_act)
        file_menu.addAction(pdf_act)
        file_menu.addSeparator()
        file_menu.addAction(settings_act)
        file_menu.addSeparator()
        file_menu.addAction(exit_act)

        edit_menu = self.menuBar().addMenu("&Edit")
        edit_menu.addAction(self.undo_act)
        edit_menu.addAction(self.redo_act)
        edit_menu.addSeparator()
        edit_menu.addAction(self.cut_act)
        edit_menu.addAction(self.copy_act)
        edit_menu.addAction(self.paste_act)

        format_menu = self.menuBar().addMenu("&Format")
        format_menu.addAction(bold_act)
        format_menu.addAction(italic_act)

        insert_menu = self.menuBar().addMenu("&Insert")
        insert_menu.addAction(image_act)
        insert_menu.addAction(table_act)

        help_menu = self.menuBar().addMenu("&Help")
        help_menu.addAction(about_act)
        help_menu.addAction(spell_act)

        file_tool_bar = self.addToolBar("File")
        file_tool_bar.addAction(new_act)
        file_tool_bar.addAction(open_act)
        file_tool_bar.addAction(book_act)

        format_tool_bar = self.addToolBar("Format")
        format_tool_bar.addAction(bold_act)
        format_tool_bar.addAction(italic_act)

        insert_toolbar = self.addToolBar("Insert")
        insert_toolbar.addAction(image_act)
        insert_toolbar.addAction(table_act)
        insert_toolbar.addAction(á_act)
        insert_toolbar.addAction(ã_act)
        insert_toolbar.addAction(é_act)
        insert_toolbar.addAction(ê_act)
        insert_toolbar.addAction(ó_act)

    def doUndo(self):
        self.text_edit.undo()

    def doRedo(self):
        self.text_edit.redo()

    def doCut(self):
        self.text_edit.cut()

    def doCopy(self):
        self.text_edit.copy()

    def doPaste(self):
        self.text_edit.paste()

    def insertImage(self):
        if not self.book:
            QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to load or create a book first!")
            return
        if not self.filename:
            QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select part from the book content first!")
            return
        if self.image_list.count() == 0:
            QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to add an image to the image list first!")
            return
        if not self.image_list.currentItem():
            QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select an image from the image list first!")
            return

        item = self.image_list.currentItem()
        filename = item.text()
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        base = filename.split(".")[0].replace("_", "-")
        cursor.insertText("![" + base + "](../images/" + filename + " \"" + base + "\")")
        cursor.setPosition(pos)
        self.text_edit.setTextCursor(cursor)

    def insertTable(self):
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        cursor.insertText("| alignLeft | alignCenter | unAligned | alignRight |\n"
                          "|  :---     |   :---:     |   ---     |   ---:     |\n"
                          "|  cell a   |   cell b    |   cell c  |   cell d   |\n"
                          "|  cell e   |   cell f    |   cell g  |   cell h   |\n")
        cursor.setPosition(pos)
        self.text_edit.setTextCursor(cursor)

    def insertLetterA1(self):
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        cursor.insertText("á")
        cursor.setPosition(pos + 1)
        self.text_edit.setTextCursor(cursor)

    def insertLetterA2(self):
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        cursor.insertText("ã")
        cursor.setPosition(pos + 1)
        self.text_edit.setTextCursor(cursor)

    def insertLetterE1(self):
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        cursor.insertText("é")
        cursor.setPosition(pos + 1)
        self.text_edit.setTextCursor(cursor)

    def insertLetterE2(self):
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        cursor.insertText("ê")
        cursor.setPosition(pos + 1)
        self.text_edit.setTextCursor(cursor)

    def insertLetterO1(self):
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        cursor.insertText("ó")
        cursor.setPosition(pos + 1)
        self.text_edit.setTextCursor(cursor)

    def createStatusBar(self):
        self.statusBar().showMessage("Ready")

    def about(self):
        QMessageBox.about(self, "About " + QCoreApplication.applicationName(), "EbookCreator\nVersion: " + QCoreApplication.applicationVersion() + "\n(C) Copyright 2019 Olaf Japp. All rights reserved.\n\nThis program is provided AS IS with NO\nWARRANTY OF ANY KIND, INCLUDING THE\nWARRANTY OF DESIGN, MERCHANTABILITY AND\nFITNESS FOR A PATICULAR PURPOSE.")

    def newFile(self):
        dlg = ProjectWizard(self.install_directory, parent = self)
        dlg.loadBook.connect(self.loadBook)
        dlg.show()

    def open(self):
        fileName = ""
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setNameFilter("EbookCreator (book.qml);;All (*)")
        dialog.setWindowTitle("Load Ebook")
        dialog.setOption(QFileDialog.DontUseNativeDialog, True)
        dialog.setAcceptMode(QFileDialog.AcceptOpen)
        dialog.setDirectory(os.path.join(self.install_directory, "sources"))
        if dialog.exec_():
            fileName = dialog.selectedFiles()[0]
        del dialog
        if not fileName:
            return
        self.loadBook(fileName)

    def writeSettings(self):
        settings = QSettings(QSettings.IniFormat, QSettings.UserScope, QCoreApplication.organizationName(), QCoreApplication.applicationName())
        settings.setValue("geometry", self.saveGeometry())
        settings.setValue("lastBook", self.last_book)

    def readSettings(self):
        settings = QSettings(QSettings.IniFormat, QSettings.UserScope, QCoreApplication.organizationName(), QCoreApplication.applicationName())
        geometry = settings.value("geometry", QByteArray())
        self.last_book = settings.value("lastBook")
        if not geometry:
            availableGeometry = QApplication.desktop().availableGeometry(self)
            self.resize(availableGeometry.width() / 3, availableGeometry.height() / 2)
            self.move((availableGeometry.width() - self.width()) / 2, (availableGeometry.height() - self.height()) / 2)
        else:
            self.restoreGeometry(geometry)

    def bold(self):
        if not self.filename:
            QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select part from the book content first!")
            return
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        if not cursor.hasSelection():
            cursor.select(QTextCursor.WordUnderCursor)
        cursor.insertText("**" + cursor.selectedText() + "**")
        cursor.setPosition(pos + 2)
        self.text_edit.setTextCursor(cursor)

    def italic(self):
        if not self.filename:
            QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select part from the book content first!")
            return
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        if not cursor.hasSelection():
            cursor.select(QTextCursor.WordUnderCursor)
        cursor.insertText("*" + cursor.selectedText() + "*")
        cursor.setPosition(pos + 1)
        self.text_edit.setTextCursor(cursor)

    def create(self):
        filename = ""
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setNameFilter("ePub3 (*.epub);;All (*)")
        dialog.setWindowTitle("Create Ebook")
        dialog.setOption(QFileDialog.DontUseNativeDialog, True)
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        dialog.setDirectory(self.book.source_path)
        dialog.setDefaultSuffix("epub")
        if dialog.exec_():
            filename = dialog.selectedFiles()[0]
        del dialog
        if not filename:
            return
        QApplication.setOverrideCursor(Qt.WaitCursor)
        createEpub(filename, self.book, self)
        QApplication.restoreOverrideCursor()

    def loadStatusChanged(self, status):
        if status == 1:
            self.book = self.component.create()
            if self.book is not None:
                self.book.setFilename(self.last_book)
                self.book.setWindow(self)
            else:
                for error in self.component.errors():
                    print(error.toString())
                return

            self.content_list.clear()
            for part in self.book.parts:
                item = QListWidgetItem()
                item.setText(part.name)
                item.setData(1, part)
                self.content_list.addItem(item)

            self.loadImages()
            self.setWindowTitle(QCoreApplication.applicationName() + " - " + self.book.name)

            self.content.setExpanded(True)
            self.content_list.setCurrentRow(0)
        elif status == 3:
            for error in self.component.errors():
                print(error.toString())
            return

    def loadBook(self, filename):
        self.last_book = filename
        self.filename = ""
        engine = QQmlEngine()
        self.component = QQmlComponent(engine)
        self.component.statusChanged.connect(self.loadStatusChanged)
        self.component.loadUrl(QUrl.fromLocalFile(filename))

    def settingsDialog(self):
        dlg = SettingsDialog(self.theme, self.palette().highlight().color().name(), parent=self)
        dlg.exec()
        if dlg.theme != self.theme or dlg.hilite_color != self.palette().highlight().color().name():
            settings = QSettings(QSettings.IniFormat, QSettings.UserScope, QCoreApplication.organizationName(), QCoreApplication.applicationName())
            settings.setValue("theme", dlg.theme)
            settings.setValue("hiliteColor", dlg.hilite_color)

            msgBox = QMessageBox()
            msgBox.setText("Please restart the app to change the theme!")
            msgBox.exec()

    def textChanged(self):
        text = self.text_edit.toPlainText()
        if self.filename:
            with open(self.filename, "w") as f:
                f.write(text)

        self.lock = Lock()
        with self.lock:
            if not self.tread_running:
                self.tread_running = True
                self.htmlReady.connect(self.previewReady)
                thread = Thread(target=self.createHtml, args=(text,))
                thread.daemon = True
                thread.start()

    def previewReady(self, html):
        self.preview.setHtml(html, baseUrl=QUrl(Path(os.path.join(self.book.source_path, "parts", "index.html")).as_uri()))
        self.htmlReady.disconnect()
        with self.lock:
            self.tread_running = False

    def createHtml(self, text):
        html = "<html>\n<head>\n"
        html += "<link href=\"../css/pastie.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
        html += "<link href=\"../css/stylesheet.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
        html += "</head>\n<body>\n"
        html += markdown(text, html4tags=False, extras=["fenced-code-blocks", "wiki-tables", "tables", "header-ids"])
        html += "\n</body>\n</html>"
        html = addLineNumbers(html)
        self.htmlReady.emit(html)

    def pdfExport(self):
        p = PdfExport(self.book, self.statusBar())

    def spellCheck(self):
        if not self.filename:
            QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select part from the book content first!")
            return
        cursor = self.text_edit.textCursor()
        pos = cursor.position()
        if not cursor.hasSelection():
            cursor.select(QTextCursor.WordUnderCursor)
        spell = Speller(lang='en')
        changed = spell(cursor.selectedText())
        if changed != cursor.selectedText():
            cursor.insertText(changed)
            self.text_edit.setTextCursor(cursor)
Пример #19
0
class AccountsView(QSplitter):
    computing_privkeys_signal = pyqtSignal()
    show_privkeys_signal = pyqtSignal()

    def __init__(self, main_window: ElectrumWindow, wallet: Wallet) -> None:
        super().__init__(main_window)

        self._main_window = main_window
        self._wallet = wallet

        self._main_window.account_created_signal.connect(
            self._on_account_created)

        self._selection_list = QListWidget()
        self._selection_list.setMinimumWidth(150)
        self._tab_widget = QTabWidget()

        self.addWidget(self._selection_list)
        self.addWidget(self._tab_widget)

        self.setStretchFactor(1, 2)

        self._selection_list.setIconSize(QSize(32, 32))
        self._selection_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self._selection_list.customContextMenuRequested.connect(
            self._create_account_menu)

        self._update_account_list()

    def _on_account_created(self, new_account_id: int) -> None:
        self._update_account_list()

    def get_tab_widget(self) -> QTabWidget:
        return self._tab_widget

    def _update_account_list(self) -> None:
        self._selection_list.clear()
        for account in self._wallet.get_accounts():
            item = QListWidgetItem()
            keystore = account.get_keystore()
            derivation_type = keystore.derivation_type if keystore is not None \
                else DerivationType.NONE
            is_watching_only = keystore.is_watching_only(
            ) if keystore is not None else True
            icon_state = "inactive" if is_watching_only else "active"
            if derivation_type == DerivationType.ELECTRUM_MULTISIG:
                tooltip_text = _("Multi-signature account")
                icon_filename = "icons8-group-task-80-blueui-{}.png"
            elif derivation_type == DerivationType.HARDWARE:
                tooltip_text = _("Hardware wallet account")
                icon_filename = "icons8-usb-2-80-blueui-{}.png"
            elif derivation_type == DerivationType.IMPORTED:
                # This should not be watch only as imported public keys have no keystore.
                tooltip_text = _("Imported private key account")
                icon_filename = "icons8-key-80-plus-blueui-{}.png"
            elif derivation_type == DerivationType.ELECTRUM_OLD:
                tooltip_text = _("Old-style Electrum account")
                icon_filename = "icons8-password-1-80-blueui-{}.png"
            elif derivation_type == DerivationType.BIP32:
                tooltip_text = _("BIP32 account")
                icon_filename = "icons8-grand-master-key-80-blueui-{}.png"
            else:
                # This should always be watch only as imported public keys have no keystore.
                tooltip_text = _("Imported public key account")
                icon_filename = "icons8-key-80-plus-blueui-{}.png"
            if is_watching_only:
                tooltip_text += f" ({_('watch only')})"
            item.setIcon(read_QIcon(icon_filename.format(icon_state)))
            item.setData(Qt.UserRole, account.get_id())
            item.setText(account.display_name())
            item.setToolTip(tooltip_text)
            self._selection_list.addItem(item)

    def _create_account_menu(self, position) -> None:
        item = self._selection_list.currentItem()
        if not item:
            return

        account_id = item.data(Qt.UserRole)
        account = self._wallet.get_account(account_id)

        menu = QMenu()
        menu.addAction(_("&Information"),
                       partial(self._show_account_information, account_id))
        seed_menu = menu.addAction(
            _("View &Secured Data"),
            partial(self._view_secured_data,
                    main_window=self._main_window,
                    account_id=account_id))
        seed_menu.setEnabled(
            not account.is_watching_only() and not isinstance(account, MultisigAccount) \
            and not account.is_hardware_wallet())
        menu.addSeparator()

        private_keys_menu = menu.addMenu(_("&Private keys"))
        import_menu = private_keys_menu.addAction(
            _("&Import"),
            partial(self._import_privkey,
                    main_window=self._main_window,
                    account_id=account_id))
        import_menu.setEnabled(account.can_import_privkey())
        export_menu = private_keys_menu.addAction(
            _("&Export"),
            partial(self._export_privkeys,
                    main_window=self._main_window,
                    account_id=account_id))
        export_menu.setEnabled(account.can_export())
        if account.can_import_address():
            menu.addAction(_("Import addresses"),
                           partial(self._import_addresses, account_id))

        menu.addSeparator()

        labels_menu = menu.addMenu(_("&Labels"))
        action = labels_menu.addAction(
            _("&Import"),
            partial(self._main_window.do_import_labels, account_id))
        # TODO(rt12) BACKLOG The plan is to implement this in a way that lets the user specify
        # whether to skip importing entries that already have a label (skip / overwrite).
        action.setEnabled(False)
        labels_menu.addAction(
            _("&Export"),
            partial(self._main_window.do_export_labels, account_id))

        menu.exec_(self._selection_list.viewport().mapToGlobal(position))

    def _show_account_information(self, account_id: int) -> None:
        dialog = AccountInformationDialog(self._main_window, self._wallet,
                                          account_id, self)
        dialog.exec_()

    @protected
    def _view_secured_data(self,
                           main_window: ElectrumWindow,
                           account_id: int = -1,
                           password: Optional[str] = None) -> None:
        # account_id is a keyword argument so that 'protected' can identity the correct wallet
        # window to do the password request in the context of.
        account = self._wallet.get_account(account_id)
        keystore = account.get_keystore()
        from .secured_data_dialog import SecuredDataDialog
        d = SecuredDataDialog(self._main_window, self, keystore, password)
        d.exec_()

    @protected
    def _import_privkey(self,
                        main_window: ElectrumWindow,
                        account_id: int = -1,
                        password: Optional[str] = None) -> None:
        # account_id is a keyword argument so that 'protected' can identity the correct wallet
        # window to do the password request in the context of.
        account = self._wallet.get_account(account_id)

        title, msg = _('Import private keys'), _("Enter private keys")
        self._main_window._do_import(
            title, msg, lambda x: account.import_private_key(x, password))

    def _import_addresses(self, account_id: int) -> None:
        account = self._wallet.get_account(account_id)

        title, msg = _('Import addresses'), _("Enter addresses")

        def import_addr(addr):
            address = address_from_string(addr)
            if account.import_address(address):
                return addr
            # Show duplicate addition same as good addition.
            return addr

        self._main_window._do_import(title, msg, import_addr)

    @protected
    def _export_privkeys(self,
                         main_window: ElectrumWindow,
                         account_id: int = -1,
                         password: Optional[str] = None) -> None:
        account = self._wallet.get_account(account_id)

        if isinstance(self._wallet, MultisigAccount):
            self.show_message(
                _('WARNING: This is a multi-signature wallet.') + '\n' +
                _('It can not be "backed up" by simply exporting these private keys.'
                  ))

        d = WindowModalDialog(self, _('Private keys'))
        d.setMinimumSize(850, 300)
        vbox = QVBoxLayout(d)

        msg = "\n".join([
            _("WARNING: ALL your private keys are secret."),
            _("Exposing a single private key can compromise your entire wallet!"
              ),
            _("In particular, DO NOT use 'redeem private key' services proposed by third parties."
              )
        ])
        vbox.addWidget(QLabel(msg))

        e = QTextEdit()
        e.setReadOnly(True)
        vbox.addWidget(e)

        defaultname = 'electrumsv-private-keys.csv'
        select_msg = _('Select file to export your private keys to')
        hbox, filename_e, csv_button = filename_field(self._main_window.config,
                                                      defaultname, select_msg)
        vbox.addLayout(hbox)

        b = OkButton(d, _('Export'))
        b.setEnabled(False)
        vbox.addLayout(Buttons(CancelButton(d), b))

        private_keys = {}
        keyinstance_ids = account.get_keyinstance_ids()
        done = False
        cancelled = False

        def privkeys_thread():
            for keyinstance_id in keyinstance_ids:
                time.sleep(0.1)
                if done or cancelled:
                    break
                privkey = account.export_private_key(keyinstance_id, password)
                script_template = account.get_script_template_for_id(
                    keyinstance_id)
                script_text = script_template_to_string(script_template)
                private_keys[script_text] = privkey
                self.computing_privkeys_signal.emit()
            if not cancelled:
                self.computing_privkeys_signal.disconnect()
                self.show_privkeys_signal.emit()

        def show_privkeys():
            s = "\n".join('{}\t{}'.format(script_text, privkey)
                          for script_text, privkey in private_keys.items())
            e.setText(s)
            b.setEnabled(True)
            self.show_privkeys_signal.disconnect()
            nonlocal done
            done = True

        def on_dialog_closed(*args):
            nonlocal done
            nonlocal cancelled
            if not done:
                cancelled = True
                self.computing_privkeys_signal.disconnect()
                self.show_privkeys_signal.disconnect()

        self.computing_privkeys_signal.connect(
            lambda: e.setText("Please wait... %d/%d" %
                              (len(private_keys), len(keyinstance_ids))))
        self.show_privkeys_signal.connect(show_privkeys)
        d.finished.connect(on_dialog_closed)
        threading.Thread(target=privkeys_thread).start()

        if not d.exec_():
            done = True
            return

        filename = filename_e.text()
        if not filename:
            return

        try:
            self.do_export_privkeys(filename, private_keys,
                                    csv_button.isChecked())
        except (IOError, os.error) as reason:
            txt = "\n".join([
                _("ElectrumSV was unable to produce a private key-export."),
                str(reason)
            ])
            MessageBox.show_error(txt, title=_("Unable to create csv"))
        except Exception as e:
            self.show_message(str(e))
            return

        MessageBox.show_message(_('Private keys exported'), self._main_window)

    def do_export_privkeys(self, fileName: str, pklist, is_csv):
        with open(fileName, "w+") as f:
            if is_csv:
                transaction = csv.writer(f)
                transaction.writerow(["reference", "private_key"])
                for key_text, pk in pklist.items():
                    transaction.writerow([key_text, pk])
            else:
                f.write(json.dumps(pklist, indent=4))
Пример #20
0
class NewProjectManager(QDialog):
    def __init__(self, parent=None):
        super(NewProjectManager, self).__init__(parent, Qt.Dialog)
        self.setWindowTitle(translations.TR_NEW_PROJECT)
        self.setMinimumHeight(500)
        vbox = QVBoxLayout(self)
        vbox.addWidget(QLabel(translations.TR_CHOOSE_TEMPLATE))
        vbox.addWidget(QLabel(translations.TR_TAB_PROJECTS))

        hbox = QHBoxLayout()
        self.list_projects = QListWidget()
        self.list_projects.setProperty("wizard", True)
        hbox.addWidget(self.list_projects)

        self.list_templates = QListWidget()
        self.list_templates.setProperty("wizard", True)
        hbox.addWidget(self.list_templates)

        self.text_info = QTextBrowser()
        self.text_info.setProperty("wizard", True)
        hbox.addWidget(self.text_info)

        vbox.addLayout(hbox)

        button_box = QDialogButtonBox(QDialogButtonBox.Cancel
                                      | QDialogButtonBox.Ok)
        choose_button = button_box.button(QDialogButtonBox.Ok)
        choose_button.setText(translations.TR_CHOOSE)
        # hbox2 = QHBoxLayout()
        # cancel = QPushButton(translations.TR_CANCEL)
        # choose = QPushButton(translations.TR_CHOOSE)
        # hbox2.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding,
        #                    QSizePolicy.Fixed))
        # hbox2.addWidget(cancel)
        # hbox2.addWidget(choose)
        # vbox.addLayout(button_box)
        vbox.addWidget(button_box)

        self.template_registry = IDE.get_service("template_registry")
        categories = self.template_registry.list_project_categories()
        for category in categories:
            self.list_projects.addItem(category)

        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        # cancel.clicked.connect(self.close)
        # choose.clicked.connect(self._start_wizard)
        self.list_projects.itemSelectionChanged.connect(self._project_selected)
        self.list_templates.itemSelectionChanged.connect(
            self._template_selected)
        self.list_projects.setCurrentRow(0)

    def accept(self):
        logger.debug("Accept...")
        self._start_wizard()
        super().accept()

    def _project_selected(self):
        self.list_templates.clear()
        item = self.list_projects.currentItem()
        category = item.text()
        for template in self.template_registry.list_templates_for_cateogory(
                category):
            item = QListWidgetItem(template.type_name)
            item.setData(Qt.UserRole, template)
            item = self.list_templates.addItem(item)
        self.list_templates.setCurrentRow(0)

    def _template_selected(self):
        item = self.list_templates.currentItem()
        ptype = item.data(Qt.UserRole)
        self.text_info.setText(ptype.description)

    def _start_wizard(self):
        item = self.list_templates.currentItem()
        if item is not None:
            project_type = item.data(Qt.UserRole)

        wizard = WizardProject(project_type, self)
        wizard.show()
Пример #21
0
class Thumbnail(DockWidget):

    item_double_clicked = pyqtSignal(int)

    current_index_changed = pyqtSignal(int)
    remove_project_signal = pyqtSignal(int)
    selected_project_changed = pyqtSignal(ProjectDocument)
    analysis_compare = pyqtSignal(int)

    synchronize_changed_signal = pyqtSignal(bool)

    def __init__(self,
                 history_project_manager: HistoryProjectManager,
                 origin_project,
                 parent=None):
        DockWidget.__init__(self, widget_title="历史项目", parent=parent)

        self.content_widget = QWidget()
        self.setWidget(self.content_widget)

        # 初始化窗口内组件
        self.tb = QToolBar(self)
        self.list_widget = QListWidget()
        self.layout = QVBoxLayout()

        self._origin_project = origin_project
        self._list_item_to_project = {}
        self._history_project_manger = history_project_manager
        self.__create_layout()
        self.__create_tool_bar(self.tb)
        self.__create_list_widget()

        projects = self._history_project_manger.get_projects_document()
        for project in projects:
            self.add_project(project)

    def __del__(self):
        del self.list_widget
        del self.tb
        del self._history_project_manger

    # 创建布局
    def __create_layout(self):
        self.layout.addWidget(self.tb)
        self.layout.addWidget(self.list_widget)
        self.content_widget.setLayout(self.layout)

    def current_project(self) -> ProjectDocument:
        return self._list_item_to_project[self.list_widget.currentItem()]

    # 创建工具栏
    def __create_tool_bar(self, toolbar):
        self.new_action = QAction(QIcon(":/add.png"), "添加", self)
        self.new_action.triggered.connect(self.open_new_project)
        toolbar.addAction(self.new_action)

        self.delete_action = QAction(QIcon(':/remove.png'), "关闭", self)
        self.delete_action.triggered.connect(self.remove_project)
        toolbar.addAction(self.delete_action)

        self.analysis = QAction(QIcon(":/fenxi.png"), "历史数据分析", parent=self)
        self.analysis.triggered.connect(self.analysis_all_project)
        toolbar.addAction(self.analysis)

        self.analysis_compare = QAction(QIcon("://duibifenxi.png"),
                                        "数据对比",
                                        parent=self)
        toolbar.addAction(self.analysis_compare)
        self.analysis_compare.triggered.connect(self.analysis_project_with)

        self._is_synchronize_checked = QCheckBox("同步", self)
        self._is_synchronize_checked.setChecked(True)
        self._is_synchronize_checked.toggled.connect(
            self.synchronize_changed_signal)
        toolbar.addSeparator()
        toolbar.addWidget(self._is_synchronize_checked)

    def analysis_all_project(self):
        projects = self._history_project_manger.get_projects()
        projects.insert(0, self._origin_project.project())

        years = []
        for year in range(len(projects)):
            years.append(2014 + year)

        data = get_projects_area_data(projects, years)
        if not data:
            return

        chart = PolygonalChart("历史数据对比", data, self)
        chart.show()

    def analysis_project_with(self):
        """"""

    def __create_list_widget(self):
        # 设置列表窗口
        self.list_widget.setGeometry(QtCore.QRect(90, 330, 621, 171))
        self.list_widget.setIconSize(QtCore.QSize(100, 100))
        self.list_widget.setMovement(QtWidgets.QListView.Static)
        self.list_widget.setResizeMode(QtWidgets.QListView.Adjust)
        self.list_widget.setGridSize(QtCore.QSize(150, 150))
        self.list_widget.setViewMode(QtWidgets.QListView.IconMode)
        self.list_widget.setObjectName("listWidget")
        # item样式设置
        self.list_widget.setStyleSheet(
            "QListWidget::item{border:1px solid gray; color:black; margin-top:20px;}"
        )
        # 列表窗口右键点击菜单
        self.list_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.list_widget.customContextMenuRequested.connect(
            self.my_listwidget_context)
        # 关闭自动排序
        self.list_widget.setSortingEnabled(False)
        # 去除垂直滚动条
        self.list_widget.setWrapping(0)
        self.list_widget.setVerticalScrollBarPolicy(
            QtCore.Qt.ScrollBarAsNeeded)
        # 设置双击缩略图的信号与槽连接
        self.list_widget.itemClicked.connect(self.__item_clicked)
        self.list_widget.itemDoubleClicked.connect(self.__item_double_clicked)

    def add_project(self, project):
        fit_pixmap = project.get_pixmap()
        fit_pixmap = fit_pixmap.scaled(80, 80, QtCore.Qt.IgnoreAspectRatio,
                                       QtCore.Qt.SmoothTransformation)
        new_item = ListWidgetItem(QIcon(fit_pixmap),
                                  project.project_brief_info())
        new_item.setToolTip(project.project_brief_info())
        new_item.setSizeHint(QtCore.QSize(90, 130))
        self.list_widget.addItem(new_item)
        self.list_widget.setCurrentItem(new_item)
        self._list_item_to_project[new_item] = project

    # 右键菜单
    def my_listwidget_context(self, point):
        pop_menu = QtWidgets.QMenu()

        if self.list_widget.itemAt(point):
            pop_menu.addAction(self.new_action)
            pop_menu.addAction(self.delete_action)
        else:
            pop_menu.addAction(self.new_action)
        pop_menu.exec_(QtGui.QCursor.pos())

    # 鼠标单击
    def __item_clicked(self, clicked_item):
        """"""

    def __item_double_clicked(self, item):
        if item in self._list_item_to_project:
            self.selected_project_changed.emit(
                self._list_item_to_project[item])

    def open_new_project(self):
        file_format = "Project files (*.mfb)"
        dir_ = "."
        file_names = QFileDialog.getOpenFileNames(self, "选择遥感图片", dir_,
                                                  file_format)[0]

        if file_names:
            project_format = ProjectFormat()
            had_files = self._history_project_manger.get_all_files()

            for file in file_names:
                if file == self._origin_project.get_file_name(
                ) or file in had_files:
                    continue
                project = ProjectDocument(project_format.read_project(file))
                if not project:
                    continue
                self._history_project_manger.add_history_project(project)
                self.add_project(project)
        else:
            return None

    # 工具栏删除
    def remove_project(self):
        current_project_item = self.list_widget.currentItem()
        if current_project_item and current_project_item in self._list_item_to_project:
            project = self._list_item_to_project[current_project_item]
            self._history_project_manger.remove_history_project(project)
            self.list_widget.removeItemWidget(current_project_item)
            self.list_widget.takeItem(
                self.list_widget.row(current_project_item))
            del self._list_item_to_project[current_project_item]
            del current_project_item
            self.list_widget.update()
Пример #22
0
class ChatSetter(QWidget):
    """..."""
    saved = pyqtSignal(str, bool, list)

    def __init__(self, name_):
        super(ChatSetter, self).__init__()
        self._name = name_
        self._setup_ui()

    def enable(self, enable_):
        """..."""
        self._enable.setChecked(enable_)

    def display_filter(self, filter_list_):
        """..."""
        self._filter.clear()
        for _name in filter_list_:
            _item = QListWidgetItem(_name)
            _item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable)
            self._filter.addItem(_item)

    def _on_clicked(self, item_):
        self._filter.setCurrentItem(item_)
        for _index in range(self._filter.count()):
            self._filter.item(_index).setBackground(QColor('white'))
            self._filter.item(_index).setForeground(QColor('black'))
        item_.setBackground(QColor(0, 105, 217))
        item_.setForeground(QColor('white'))

    def _setup_ui(self):
        _vbox = QVBoxLayout()
        self._enable = QCheckBox(self._name)
        self._filter = QListWidget()
        self._filter.itemClicked.connect(self._on_clicked)
        self._filter.itemChanged.connect(self._save_filter)
        self._filter.setSelectionMode(QAbstractItemView.SingleSelection)
        _vbox.addWidget(self._enable)
        _vbox.addWidget(self._filter)
        _vbox.addLayout(self._gen_filter_btn_group())
        self.setLayout(_vbox)

    def _gen_filter_btn_group(self):
        _add = QPushButton('Add')
        _add.clicked.connect(self._add_filter)
        _delete = QPushButton('Delete')
        _delete.clicked.connect(self._delete_filter)

        _btn_group = QHBoxLayout()
        _btn_group.addWidget(_add)
        _btn_group.addWidget(_delete)
        _btn_group.setSpacing(0)
        return _btn_group

    def _add_filter(self):
        _name = GuiUtils.input_dialog(self, 'Filter', 'Add filter:')
        if _name:
            _item = QListWidgetItem(_name)
            _item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable)
            self._filter.addItem(_item)
            self._save_filter()

    def _delete_filter(self):
        try:
            _item = self._filter.currentItem()
            if GuiUtils.question_dialog(self, 'Filter',
                                        'Delete filter: ' + _item.text()):
                _item = self._filter.takeItem(self._filter.currentRow())
                del _item
                self._save_filter()
        except Exception as e:
            _msg = 'Choose one item before deleting.'
            print(_msg)

    def _save_filter(self):
        self.saved.emit(self._name, self._enable.isChecked(), [
            self._filter.item(_index).text()
            for _index in range(self._filter.count())
        ])
Пример #23
0
class Ui_MainWindow(object):
    def __init__(self):
        self.player = main2.player()
        self.music_titles = []
        self.music_href = []
        self.index = ""
        self.music_player = M.QMediaPlayer()
        self.searched = ""
        

    def setupUi(self, MainWindow):
        os.environ['QT_MULTIMEDIA_PREFERRED_PLUGINS'] = 'windowsmediafoundation'
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
       # self.img = QtWidgets.QLabel(self.centralwidget)
        #self.img.setGeometry(QtCore.QRect(100, 90, 511, 251))
        #self.img.setObjectName("img")




        self.currentTimeLabel = QtWidgets.QLabel(self.centralwidget)
        self.currentTimeLabel.setMinimumSize(QtCore.QSize(80, 0))
        self.currentTimeLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.currentTimeLabel.setObjectName("currentTimeLabel")
        self.currentTimeLabel.setGeometry(QtCore.QRect(70, 325, 61, 90))

        self.volumeSlider = QtWidgets.QSlider(self.centralwidget)
        self.volumeSlider.setMaximum(100)
        self.volumeSlider.setProperty("value", 100)
        self.volumeSlider.setOrientation(QtCore.Qt.Horizontal)
        self.volumeSlider.setObjectName("volumeSlider")
        self.volumeSlider.setGeometry(QtCore.QRect(550, 440, 61, 22))

        self.timeSlider = QtWidgets.QSlider(self.centralwidget)
        self.timeSlider.setOrientation(QtCore.Qt.Horizontal)
        self.timeSlider.setObjectName("timeSlider")
        self.timeSlider.setGeometry(QtCore.QRect(160, 360, 481, 22))
        self.timeSlider.setOrientation(QtCore.Qt.Horizontal)


        self.totalTimeLabel = QtWidgets.QLabel(self.centralwidget)
        self.totalTimeLabel.setMinimumSize(QtCore.QSize(80, 0))
        self.totalTimeLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
        self.totalTimeLabel.setGeometry(QtCore.QRect(650,325,61,90))
        self.timeSlider.setOrientation(QtCore.Qt.Horizontal)

        self.list=QListWidget(self.centralwidget)
        self.list.setGeometry(QtCore.QRect(100, 90, 511, 251))
        self.Play = QtWidgets.QPushButton(self.centralwidget)
        self.Play.setGeometry(QtCore.QRect(350, 440, 61, 41))
        self.Play.setObjectName("Play")
        self.Play.clicked.connect(self.Start)
        self.pause_bt = QtWidgets.QPushButton(self.centralwidget)
        self.pause_bt.setGeometry(QtCore.QRect(420,440,61,41))
        self.pause_bt.setObjectName('Pause')
        self.pause_bt.clicked.connect(self.Pause)
        self.Next = QtWidgets.QPushButton(self.centralwidget)
        self.Next.setGeometry(QtCore.QRect(310, 450, 31, 31))
        self.Next.setObjectName("Next")
        self.label_title = QtWidgets.QLabel(self.centralwidget)
        self.label_title.setGeometry(QtCore.QRect(156, 390, 421, 31))
        self.label_title.setObjectName("label_title")
        self.Search = QtWidgets.QLineEdit(self.centralwidget)
        self.Search.setGeometry(QtCore.QRect(172, 20, 411, 20))
        self.Search.setText("")
        self.Search.setObjectName("Search")
        self.Search_button = QtWidgets.QPushButton(self.centralwidget)
        self.Search_button.setGeometry(QtCore.QRect(630, 20, 75, 23))
        self.Search_button.setObjectName("Search_button")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        #self.horizontalSlider = QtWidgets.QSlider(self.centralwidget)
        #self.horizontalSlider.setGeometry(QtCore.QRect(160, 360, 481, 22))
        #self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        #self.horizontalSlider.setObjectName("horizontalSlider")
    
        


        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        
        self.Search_button.clicked.connect(self.search_clicked)
        self.list.clicked.connect(self.list_OnClicked)

    def retranslateUi(self, MainWindow):
        self._translate = QtCore.QCoreApplication.translate
        self.currentTimeLabel.setText(self._translate("MainWindow", "0:00"))
        MainWindow.setWindowTitle(self._translate("MainWindow", "Fake Spotify"))
        #self.img.setText(self._translate("MainWindow", "TextLabel"))
        self.Play.setText(self._translate("MainWindow", "Play"))
        self.Next.setText(self._translate("MainWindow", "Next"))
        self.pause_bt.setText(self._translate("MainWindow","Pause"))
        self.Search_button.setText(self._translate("MainWindow", "Search"))
        self.label_title.setText(self._translate("MainWindow", "Download complete"))
        self.music_player.durationChanged.connect(self.update_duration)
        self.music_player.positionChanged.connect(self.update_position)
        self.timeSlider.valueChanged.connect(self.music_player.setPosition)
        self.volumeSlider.valueChanged.connect(self.music_player.setVolume)
    
    def Start(self):
        self.music_player.play()
    def Pause(self):
        self.music_player.pause()

    #ilk bu çalışacak
    def search_clicked(self):
        self.searched =  self.Search.text()
        self.thread =threading.Thread(target=self.player.search, args = (self.searched,))
        self.thread.start()
        self.insert_list()

    #buna basıldığında şarkı açılması lazım
    def insert_list(self):
        self.list.clear()
        self.music_titles,self.music_href = self.player.chrome()
        cache = ""
    
         
        for title in self.music_titles:
             title = title.strip()
    
             if cache != title:
                 self.list.addItem(title)
             cache = title
    
    #when user click the  listwiew
    def list_OnClicked(self):
        self.thread = threading.Thread(target = self.play_music)
        self.thread.start()


    def set_label_title(self):
        self.label_title.setText(self._translate("MainWindow",self.music_titles[self.index]))
        
        #play music thread
    def play_music(self):
        self.index = self.list.row(self.list.currentItem())
        print(self.music_href[self.index],"index",self.index)
        name = self.player.music_choose(self.music_href[self.index],self.music_titles[self.index].strip() + ".mp4")
        self.url = QtCore.QUrl.fromLocalFile(name)
        self.content = M.QMediaContent(self.url)
        self.music_player.setMedia(self.content)
        self.music_player.play()

    def update_duration(self,duration):
        print("!", duration)
        print("?", self.music_player.duration())
 
        self.timeSlider.setMaximum(duration)
        if duration >= 0:
            self.totalTimeLabel.setText(self.hhmmss(duration))

    def update_position(self, position):
        if position >= 0:
            self.currentTimeLabel.setText(self.hhmmss(position))

        self.timeSlider.blockSignals(True)
        self.timeSlider.setValue(position)
        self.timeSlider.blockSignals(False)
    
    def hhmmss(self,ms):
        s = round(ms / 1000)
        m,s = divmod(s,60)
        h,m = divmod(m,60)
        return ("%d:%02d:%02d" % (h,m,s)) if h else ("%d:%02d" % (m,s))
Пример #24
0
class Advanced_event_filtering_dialog(QDialog):
    """
    Dialog for visualizing advanced event filtering results
    """

    summary_header = ["Observation id", "Number of occurences", "Total duration (s)", "Duration mean (s)", "Std Dev"]
    details_header = ["Observation id", "Comment", "Start time", "Stop time", "Duration (s)"]

    def __init__(self, events):
        super().__init__()

        self.events = events
        self.out = []
        self.setWindowTitle("Advanced event filtering")

        vbox = QVBoxLayout()

        lb = QLabel("Filter")
        vbox.addWidget(lb)

        hbox = QHBoxLayout()
        self.logic = QLineEdit("")
        hbox.addWidget(self.logic)
        self.pb_filter = QPushButton("Filter events", clicked=self.filter)
        hbox.addWidget(self.pb_filter)
        self.pb_clear = QPushButton("Clear", clicked=self.logic.clear)
        self.pb_clear.setIcon(QIcon.fromTheme("edit-clear"))
        hbox.addWidget(self.pb_clear)
        vbox.addLayout(hbox)

        hbox = QHBoxLayout()
        self.rb_summary = QRadioButton("Summary", toggled=self.filter)
        self.rb_summary.setChecked(True)
        hbox.addWidget(self.rb_summary)
        self.rb_details = QRadioButton("Details", toggled=self.filter)
        hbox.addWidget(self.rb_details)
        vbox.addLayout(hbox)

        hbox = QHBoxLayout()
        vbox2 = QVBoxLayout()
        vbox2.addWidget(QLabel("Subjects"))
        self.lw1 = QListWidget()
        vbox2.addWidget(self.lw1)
        hbox.addLayout(vbox2)

        vbox2 = QVBoxLayout()
        vbox2.addWidget(QLabel("Behaviors"))
        self.lw2 = QListWidget()
        vbox2.addWidget(self.lw2)
        hbox.addLayout(vbox2)
        self.add_subj_behav_button = QPushButton("", clicked=self.add_subj_behav)
        self.add_subj_behav_button.setIcon(QIcon.fromTheme("go-up"))
        hbox.addWidget(self.add_subj_behav_button)

        vbox2 = QVBoxLayout()
        vbox2.addWidget(QLabel("Logical operators"))
        self.lw3 = QListWidget()
        self.lw3.addItems(["AND", "OR"])
        vbox2.addWidget(self.lw3)
        hbox.addLayout(vbox2)
        self.add_logic_button = QPushButton("", clicked=self.add_logic)
        self.add_logic_button.setIcon(QIcon.fromTheme("go-up"))
        hbox.addWidget(self.add_logic_button)

        vbox.addLayout(hbox)

        self.lb_results = QLabel("Results")
        vbox.addWidget(self.lb_results)

        self.tw = QTableWidget(self)
        vbox.addWidget(self.tw)

        hbox = QHBoxLayout()
        hbox.addItem(QSpacerItem(241, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.pb_save = QPushButton("Save results", clicked=self.save_results)
        hbox.addWidget(self.pb_save)
        self.pb_close = QPushButton("Close", clicked=self.close)
        hbox.addWidget(self.pb_close)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

        subjects_list, behaviors_list = [], []
        for obs_id in events:
            for subj_behav in events[obs_id]:
                subj, behav = subj_behav.split("|")
                subjects_list.append(subj)
                behaviors_list.append(behav)
        subjects_set = sorted(set(subjects_list))
        behaviors_set = sorted(set(behaviors_list))

        self.lw1.addItems(subjects_set)
        self.lw2.addItems(behaviors_set)

        self.resize(640, 640)


    def add_subj_behav(self):
        """
        add subject|behavior of selected listwidgets items in lineEdit
        """
        if self.lw1.currentItem() and self.lw2.currentItem():
            self.logic.insert(f'"{self.lw1.currentItem().text()}|{self.lw2.currentItem().text()}" ')
        else:
            QMessageBox.warning(self, programName, "Select a subject and a behavior")


    def add_logic(self):
        """
        add selected logic operaton to lineedit
        """
        if self.lw3.currentItem():

            text = ""
            if self.lw3.currentItem().text() == "AND":
                text = " & "
            if self.lw3.currentItem().text() == "OR":
                text = " | "
            if text:
                self.logic.insert(text)
        else:
            QMessageBox.warning(self, programName, "Select a logical operator")


    def filter(self):
        """
        filter events
        """
        if not self.logic.text():
            return
        if self.logic.text().count('"') % 2:
            QMessageBox.warning(self, programName, f'Wrong number of double quotes (")')
            return

        sb_list = re.findall('"([^"]*)"', self.logic.text())

        self.out = []
        flag_error = False
        for obs_id in self.events:
            logic = self.logic.text()
            for sb in set(sb_list):
                logic = logic.replace(f'"{sb}"', f'self.events[obs_id]["{sb}"]')
                if sb not in self.events[obs_id]:
                    self.events[obs_id][sb] = io([0, 0])

            try:
                eval_result = eval(logic)
                for i in eval_result:
                    if not i.empty:
                        self.out.append([obs_id, "", f"{i.lower}", f"{i.upper}", f"{i.upper - i.lower:.3f}"])
            except KeyError:
                self.out.append([obs_id, "subject / behavior not found", "NA", "NA", "NA"])
            except Exception:
                # out += f"Error in {self.logic.text()}" + "\n"
                error_type, error_file_name, error_lineno = utilities.error_info(sys.exc_info())
                self.out.append([obs_id, f"Error in {self.logic.text()}: {error_type} ", "NA", "NA", "NA"])
                flag_error = True

        self.tw.clear()

        if flag_error or self.rb_details.isChecked():

            self.lb_results.setText(f"Results ({len(self.out)} event{'s'*(len(self.out) > 1)})")

            self.tw.setRowCount(len(self.out))
            self.tw.setColumnCount(len(self.details_header))  # obs_id, comment, start, stop, duration
            self.tw.setHorizontalHeaderLabels(self.details_header)

        if not flag_error and self.rb_summary.isChecked():

            summary = {}
            for row in self.out:
                obs_id, _, start, stop, duration = row
                if obs_id not in summary:
                    summary[obs_id] = []
                summary[obs_id].append(float(duration))

            self.out = []
            for obs_id in summary:

                self.out.append([
                    obs_id,
                    str(len(summary[obs_id])),
                    str(round(sum(summary[obs_id]), 3)),
                    str(round(statistics.mean(summary[obs_id]), 3)),
                    str(round(statistics.stdev(summary[obs_id]), 3))
                    if len(summary[obs_id]) > 1 else "NA"
                ])

            self.lb_results.setText(f"Results ({len(summary)} observation{'s'*(len(summary) > 1)})")
            self.tw.setRowCount(len(summary))
            self.tw.setColumnCount(len(self.summary_header))  # obs_id, mean, stdev
            self.tw.setHorizontalHeaderLabels(self.summary_header)

        for r in range(len(self.out)):
            for c in range(self.tw.columnCount()):
                item = QTableWidgetItem()
                item.setText(self.out[r][c])
                item.setFlags(Qt.ItemIsEnabled)
                self.tw.setItem(r, c, item)


    def save_results(self):
        """
        save results
        """

        extended_file_formats = ["Tab Separated Values (*.tsv)",
                                 "Comma Separated Values (*.csv)",
                                 "Open Document Spreadsheet ODS (*.ods)",
                                 "Microsoft Excel Spreadsheet XLSX (*.xlsx)",
                                 "Legacy Microsoft Excel Spreadsheet XLS (*.xls)",
                                 "HTML (*.html)"]
        file_formats = ["tsv",
                        "csv",
                        "ods",
                        "xlsx",
                        "xls",
                        "html"]

        file_name, filter_ = QFileDialog().getSaveFileName(None, "Save results", "", ";;".join(extended_file_formats))
        if not file_name:
            return

        output_format = file_formats[extended_file_formats.index(filter_)]

        if pathlib.Path(file_name).suffix != "." + output_format:
            file_name = str(pathlib.Path(file_name)) + "." + output_format
            # check if file with new extension already exists
            if pathlib.Path(file_name).is_file():
                if dialog.MessageDialog(programName,
                                        f"The file {file_name} already exists.",
                                        [CANCEL, OVERWRITE]) == CANCEL:
                    return

        if self.rb_details.isChecked():
            tablib_dataset = tablib.Dataset(headers=self.details_header)
        if self.rb_summary.isChecked():
            tablib_dataset = tablib.Dataset(headers=self.summary_header)
        tablib_dataset.title = utilities.safe_xl_worksheet_title(self.logic.text(), output_format)

        [tablib_dataset.append(x) for x in self.out]

        try:
            if output_format in ["csv", "tsv", "html"]:
                with open(file_name, "wb") as f:
                    f.write(str.encode(tablib_dataset.export(output_format)))

            if output_format in ["ods", "xlsx", "xls"]:
                with open(file_name, "wb") as f:
                    f.write(tablib_dataset.export(output_format))

        except Exception:
            QMessageBox.critical(self, programName, f"The file {file_name} can not be saved")
Пример #25
0
class ProfilesLoader(QDialog):

    def __init__(self, load_func, create_func, save_func,
                 profiles, parent=None):
        super(ProfilesLoader, self).__init__(self, parent, Qt.Dialog)
        self.setWindowTitle(_translate("ProfilesLoader", "Profile Manager"))
        self.setMinimumWidth(400)
        self._profiles = profiles
        self.load_function = load_func
        self.create_function = create_func
        self.save_function = save_func
        self.ide = parent
        vbox = QVBoxLayout(self)
        vbox.addWidget(QLabel(_translate("ProfilesLoader", "Save your opened files and projects "
                                      "into a profile and change really"
                                      "quick between projects and"
                                      "files sessions.\n This allows you to "
                                      "save your working environment, "
                                      "keep working in another\n"
                                      "project and then go back "
                                      "exactly where you left.")))
        self.profileList = QListWidget()
        self.profileList.addItems([key for key in profiles])
        self.profileList.setCurrentRow(0)
        self.contentList = QListWidget()
        self.btnDelete = QPushButton(_translate("ProfilesLoader", "Delete Profile"))
        self.btnDelete.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.btnUpdate = QPushButton(_translate("ProfilesLoader", "Update Profile"))
        self.btnUpdate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.btnCreate = QPushButton(_translate("ProfilesLoader", "Create New Profile"))
        self.btnCreate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.btnOpen = QPushButton(_translate("ProfilesLoader", "Open Profile"))
        self.btnOpen.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.btnOpen.setDefault(True)
        hbox = QHBoxLayout()
        hbox.addWidget(self.btnDelete)
        hbox.addWidget(self.btnUpdate)
        hbox.addWidget(self.btnCreate)
        hbox.addWidget(self.btnOpen)

        vbox.addWidget(self.profileList)
        vbox.addWidget(self.contentList)
        vbox.addLayout(hbox)

        self.profileList.itemSelectionChanged.connect(self.load_profile_content)
        self.btnOpen.clicked['bool'].connect(self.open_profile)
        self.btnUpdate.clicked['bool'].connect(self.save_profile)
        self.btnCreate.clicked['bool'].connect(self.create_profile)
        self.btnDelete.clicked['bool'].connect(self.delete_profile)

    def load_profile_content(self):
        item = self.profileList.currentItem()
        self.contentList.clear()
        if item is not None:
            key = item.text()
            files = [_translate("ProfilesLoader", 'Files:')] + \
                [file[0] for file in self._profiles[key][0]]
            projects = [_translate("ProfilesLoader", 'Projects:')] + self._profiles[key][1]
            content = files + projects
            self.contentList.addItems(content)

    def create_profile(self):
        profileName = self.create_function()
        self.ide.Profile = profileName
        self.close()

    def save_profile(self):
        if self.profileList.currentItem():
            profileName = self.profileList.currentItem().text()
            self.save_function(profileName)
            self.ide.show_status_message(_translate("ProfilesLoader", "Profile %s Updated!") %
                                         profileName)
            self.load_profile_content()

    def open_profile(self):
        if self.profileList.currentItem():
            key = self.profileList.currentItem().text()
            self.load_function(key)
            self.ide.Profile = key
            self.close()

    def delete_profile(self):
        if self.profileList.currentItem():
            key = self.profileList.currentItem().text()
            self._profiles.pop(key)
            self.profileList.takeItem(self.profileList.currentRow())
            self.contentList.clear()
Пример #26
0
class SubwindowMisc(QWidget):
    """Show subwindow with miscellaneous settings."""
    def createWindow(self, mainWindow, tab=''):
        """Create subwindow with miscellaneous settings."""
        try:
            parent = None
            super().__init__(parent)
            # self.setWindowFlags(Qt.WindowStaysOnTopHint)

            self.setWindowIcon(
                QIcon(scctool.settings.getResFile('settings.png')))
            self.setWindowModality(Qt.ApplicationModal)
            self.mainWindow = mainWindow
            self.passEvent = False
            self.controller = mainWindow.controller
            self.__dataChanged = False

            self.createButtonGroup()
            self.createTabs(tab)

            mainLayout = QVBoxLayout()

            mainLayout.addWidget(self.tabs)
            mainLayout.addLayout(self.buttonGroup)

            self.setLayout(mainLayout)

            self.resize(
                QSize(mainWindow.size().width() * .80,
                      self.sizeHint().height()))
            relativeChange = QPoint(mainWindow.size().width() / 2,
                                    mainWindow.size().height() / 3)\
                - QPoint(self.size().width() / 2,
                         self.size().height() / 3)
            self.move(mainWindow.pos() + relativeChange)

            self.setWindowTitle(_("Miscellaneous Settings"))

        except Exception as e:
            module_logger.exception("message")

    def createTabs(self, tab=''):
        """Create tabs."""
        self.tabs = QTabWidget()

        self.createMapsBox()
        self.createFavBox()
        self.createAliasBox()
        self.createOcrBox()
        self.createAlphaBox()

        # Add tabs
        self.tabs.addTab(self.mapsBox, _("Map Manager"))
        self.tabs.addTab(self.favBox, _("Favorites"))
        self.tabs.addTab(self.aliasBox, _("Alias"))
        self.tabs.addTab(self.ocrBox, _("OCR"))
        self.tabs.addTab(self.alphaBox, _("AlphaTL && Ingame Score"))

        table = dict()
        table['mapmanager'] = 0
        table['favorites'] = 1
        table['alias'] = 2
        table['ocr'] = 3
        table['alphatl'] = 4
        self.tabs.setCurrentIndex(table.get(tab, -1))

    def changed(self):
        """Handle changes."""
        self.__dataChanged = True

    def createAlphaBox(self):
        """Create Alpha QWidget."""
        self.alphaBox = QWidget()
        mainLayout = QVBoxLayout()

        box = QGroupBox(_("AlphaTL"))
        layout = QHBoxLayout()

        self.cb_trans_banner = QCheckBox(
            " " + _("Download transparent Banner of the Match"))
        self.cb_trans_banner.setChecked(
            scctool.settings.config.parser.getboolean(
                "SCT", "transparent_match_banner"))
        self.cb_trans_banner.stateChanged.connect(self.changed)

        layout.addWidget(self.cb_trans_banner)
        box.setLayout(layout)

        mainLayout.addWidget(box)

        box = QGroupBox(_("Set Ingame Score Task"))
        layout = QVBoxLayout()

        self.cb_ctrlx = QCheckBox(" " +
                                  _('Automatically press Ctrl+X to apply the'
                                    ' correct player order ingame'))
        self.cb_ctrlx.setToolTip(
            _("This will ensure that the player of the first team is always"
              " on the left/top in the ingame Observer UI."))
        self.cb_ctrlx.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "CtrlX"))
        self.cb_ctrlx.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_ctrlx)

        self.cb_ctrln = QCheckBox(" " + _('Automatically press Ctrl+N before'
                                          ' OCR to display player names'))
        self.cb_ctrln.setToolTip(
            _("This is recommended for Standard and Gawliq Observer UI."))
        self.cb_ctrln.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "CtrlN"))
        self.cb_ctrln.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_ctrln)

        self.cb_ctrlshifts = QCheckBox(
            " " + _('Automatically press Ctrl+Shift+S to display'
                    ' the ingame score'))
        self.cb_ctrlshifts.setToolTip(
            _("Ctrl+Shift+S is needed for the WCS-Gameheart Oberserver"
              " Overlay, but disables the sound for other overlays."))
        self.cb_ctrlshifts.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "CtrlShiftS"))
        self.cb_ctrlshifts.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_ctrlshifts)

        self.cb_ctrlshiftc = QCheckBox(
            " " + _('Automatically press Ctrl+Shift+C to toogle the clan tag'))
        self.cb_ctrlshiftc.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "CtrlShiftC"))
        self.cb_ctrlshiftc.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_ctrlshiftc)

        container = QHBoxLayout()
        self.cb_ctrlshiftr = QComboBox()
        self.cb_ctrlshiftr.addItem("0")
        self.cb_ctrlshiftr.addItem("1")
        self.cb_ctrlshiftr.addItem("2")
        try:
            self.cb_ctrlshiftr.setCurrentIndex(
                scctool.settings.config.parser.getint("SCT", "CtrlShiftR"))
        except Exception:
            self.cb_ctrlshiftr.setCurrentIndex(0)
        self.cb_ctrlshiftr.setMaximumWidth(40)
        self.cb_ctrlshiftr.currentIndexChanged.connect(self.changed)
        container.addWidget(
            QLabel(
                _('Automatically press Ctrl+Shift+R to toogle the race icon '))
        )
        container.addWidget(self.cb_ctrlshiftr)
        container.addWidget(QLabel(_(' time(s)')))
        layout.addLayout(container)

        self.cb_blacklist = QCheckBox(" " + _('Activate Blacklist for'
                                              ' Ingame Score'))
        self.cb_blacklist.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "blacklist_on"))
        self.cb_blacklist.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_blacklist)

        box.setLayout(layout)

        mainLayout.addWidget(box)

        box = QGroupBox(_("Blacklist for Ingame Score"))
        layout = QVBoxLayout()

        blacklistDesc = _("Enter your SC2 client usernames to deactivate"
                          " automatically setting the ingame score and"
                          " toogling the production tab when you are playing"
                          " yourself. Replays are exempt.")
        label = QLabel(blacklistDesc)
        label.setAlignment(Qt.AlignJustify)
        label.setWordWrap(True)
        layout.addWidget(label)

        self.list_blacklist = ListTable(4,
                                        scctool.settings.config.getBlacklist())
        self.list_blacklist.dataModified.connect(self.changed)
        self.list_blacklist.setFixedHeight(50)
        layout.addWidget(self.list_blacklist)
        box.setLayout(layout)

        mainLayout.addWidget(box)

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))

        self.alphaBox.setLayout(mainLayout)

    def createFavBox(self):
        """Create favorites box."""
        self.favBox = QWidget()
        mainLayout = QVBoxLayout()

        box = QGroupBox(_("Players"))
        layout = QHBoxLayout()

        self.list_favPlayers = ListTable(
            4, scctool.settings.config.getMyPlayers())
        self.list_favPlayers.dataModified.connect(self.changed)
        self.list_favPlayers.setFixedHeight(150)
        layout.addWidget(self.list_favPlayers)
        box.setLayout(layout)

        mainLayout.addWidget(box)

        box = QGroupBox(_("Teams"))
        layout = QVBoxLayout()

        self.list_favTeams = ListTable(3, scctool.settings.config.getMyTeams())
        self.list_favTeams.dataModified.connect(self.changed)
        self.list_favTeams.setFixedHeight(100)
        layout.addWidget(self.list_favTeams)
        self.cb_swapTeams = QCheckBox(
            _('Swap my favorite team always to the left'))
        self.cb_swapTeams.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "swap_myteam"))
        self.cb_swapTeams.stateChanged.connect(self.changed)
        layout.addWidget(self.cb_swapTeams)
        box.setLayout(layout)
        mainLayout.addWidget(box)

        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))

        self.favBox.setLayout(mainLayout)

    def createAliasBox(self):
        """Create favorites box."""
        self.aliasBox = QWidget()
        mainLayout = QGridLayout()

        aliasDesc = _(
            'Player and team aliases are replaced by the actual name when' +
            ' encountered by the match grabber. Additionally, SC2 player' +
            ' names listed as aliases are replaced in the intros' +
            ' and used to identify players by the automatic' +
            ' background tasks "Auto Score Update" and "Set Ingame Score".')
        label = QLabel(aliasDesc)
        label.setAlignment(Qt.AlignJustify)
        label.setWordWrap(True)

        mainLayout.addWidget(label, 1, 0, 1, 2)

        box = QGroupBox(_("Player Aliases"))
        layout = QVBoxLayout()
        self.list_aliasPlayers = AliasTreeView(self)
        self.list_aliasPlayers.aliasRemoved.connect(
            self.controller.aliasManager.removePlayerAlias)
        layout.addWidget(self.list_aliasPlayers)
        addButton = QPushButton(_("Add Alias"))
        addButton.clicked.connect(
            lambda: self.addAlias(self.list_aliasPlayers, _('Player Name')))
        layout.addWidget(addButton)
        box.setLayout(layout)
        mainLayout.addWidget(box, 0, 0)

        box = QGroupBox(_("Team Aliases"))
        layout = QVBoxLayout()
        self.list_aliasTeams = AliasTreeView(self)
        self.list_aliasTeams.aliasRemoved.connect(
            self.controller.aliasManager.removeTeamAlias)
        layout.addWidget(self.list_aliasTeams)
        addButton = QPushButton(_("Add Alias"))
        addButton.clicked.connect(
            lambda: self.addAlias(self.list_aliasTeams, _('Team Name')))
        layout.addWidget(addButton)
        box.setLayout(layout)
        mainLayout.addWidget(box, 0, 1)

        list = self.controller.aliasManager.playerAliasList()
        for player, aliases in list.items():
            self.list_aliasPlayers.insertAliasList(player, aliases)

        list = self.controller.aliasManager.teamAliasList()
        for team, aliases in list.items():
            self.list_aliasTeams.insertAliasList(team, aliases)

        self.aliasBox.setLayout(mainLayout)

    def addAlias(self, widget, scope, name=""):

        name, ok = QInputDialog.getText(self, scope, scope + ':', text=name)
        if not ok:
            return

        name = name.strip()
        alias, ok = QInputDialog.getText(self,
                                         _('Alias'),
                                         _('Alias of {}').format(name) + ':',
                                         text="")

        alias = alias.strip()
        if not ok:
            return

        try:
            if widget == self.list_aliasPlayers:
                self.controller.aliasManager.addPlayerAlias(name, alias)
            elif widget == self.list_aliasTeams:
                self.controller.aliasManager.addTeamAlias(name, alias)
            widget.insertAlias(name, alias, True)
        except Exception as e:
            module_logger.exception("message")
            QMessageBox.critical(self, _("Error"), str(e))

    def createOcrBox(self):
        """Create forms for OCR."""
        self.ocrBox = QWidget()

        mainLayout = QVBoxLayout()

        box = QGroupBox(
            _("Optical Character Recognition for"
              " Automatic Setting of Ingame Score"))

        layout = QGridLayout()

        self.cb_useocr = QCheckBox(" " +
                                   _("Activate Optical Character Recognition"))
        self.cb_useocr.setChecked(
            scctool.settings.config.parser.getboolean("SCT", "use_ocr"))
        self.cb_useocr.stateChanged.connect(self.changed)

        self.tesseract = MonitoredLineEdit()
        self.tesseract.setText(
            scctool.settings.config.parser.get("SCT", "tesseract"))
        self.tesseract.textModified.connect(self.changed)
        # self.tesseract.setAlignment(Qt.AlignCenter)
        self.tesseract.setPlaceholderText(
            "C:\\Program Files (x86)\\Tesseract-OCR\\tesseract")
        self.tesseract.setReadOnly(True)
        self.tesseract.setToolTip(_('Tesseract-OCR Executable'))

        self.browse = QPushButton(_("Browse..."))
        self.browse.clicked.connect(self.selectTesseract)

        text = _(
            "Sometimes the order of players given by the SC2-Client-API"
            " differs from the order in the Observer-UI resulting in a"
            " swapped match score. To correct this via Optical Character"
            " Recognition you have to download {} and install and select the"
            " exectuable below, if it is not detected automatically.")
        url = 'https://github.com/UB-Mannheim/tesseract' + \
            '/wiki#tesseract-at-ub-mannheim'
        href = "<a href='{}'>" + "Tesseract-OCR" + "</a>"
        href = href.format(url)

        label = QLabel(text.format(href))
        label.setAlignment(Qt.AlignJustify)
        label.setOpenExternalLinks(True)
        label.setWordWrap(True)
        label.setMargin(5)
        layout.addWidget(label, 1, 0, 1, 2)

        layout.addWidget(self.cb_useocr, 0, 0, 1, 2)
        layout.addWidget(QLabel(_("Tesseract-OCR Executable") + ":"), 2, 0)
        layout.addWidget(self.tesseract, 3, 0)
        layout.addWidget(self.browse, 3, 1)

        box.setLayout(layout)
        mainLayout.addWidget(box)
        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        self.ocrBox.setLayout(mainLayout)

        if (not scctool.settings.windows):
            self.cb_useocr.setEnabled(False)
            self.cb_useocr.setAttribute(Qt.WA_AlwaysShowToolTips)
            self.cb_useocr.setToolTip(
                _("This feature is only available in Windows."))
            self.tesseract.setEnabled(False)
            self.tesseract.setAttribute(Qt.WA_AlwaysShowToolTips)
            self.tesseract.setToolTip(
                _("This feature is only available in Windows."))
            self.browse.setEnabled(False)
            self.browse.setAttribute(Qt.WA_AlwaysShowToolTips)
            self.browse.setToolTip(
                _("This feature is only available in Windows."))

    def selectTesseract(self):
        """Create forms for tesseract."""
        old_exe = self.tesseract.text()
        default = scctool.settings.config.findTesserAct(old_exe)
        exe, ok = QFileDialog.getOpenFileName(
            self, _("Select Tesseract-OCR Executable"), default,
            _("Tesseract-OCR Executable") + " (tesseract.exe);; " +
            _("Executable") + " (*.exe);; " + _("All files") + " (*)")
        if (ok and exe != old_exe):
            self.tesseract.setText(exe)
            self.changed()

    def createMapsBox(self):
        """Create box for map manager."""
        self.mapsize = 300

        self.mapsBox = QWidget()

        layout = QGridLayout()

        self.maplist = QListWidget()
        self.maplist.setSortingEnabled(True)
        for map in scctool.settings.maps:
            self.maplist.addItem(QListWidgetItem(map))
        self.maplist.setCurrentItem(self.maplist.item(0))
        self.maplist.currentItemChanged.connect(self.changePreview)
        # self.maplist.setFixedHeight(self.mapsize)
        self.maplist.setMinimumWidth(150)

        layout.addWidget(self.maplist, 0, 1, 2, 1)
        self.mapPreview = QLabel()
        self.mapPreview.setFixedWidth(self.mapsize)
        self.mapPreview.setFixedHeight(self.mapsize)
        self.mapPreview.setAlignment(Qt.AlignCenter)
        layout.addWidget(self.mapPreview, 0, 0)
        self.mapInfo = QLabel()
        self.mapInfo.setIndent(10)
        layout.addWidget(self.mapInfo, 1, 0)

        self.pb_addMapLiquipedia = QPushButton(_("Add from Liquipedia"))
        self.pb_addMapLiquipedia.clicked.connect(self.addFromLquipedia)
        self.pb_addMap = QPushButton(_("Add from File"))
        self.pb_addMap.clicked.connect(self.addMap)
        self.pb_renameMap = QPushButton(_("Rename"))
        self.pb_renameMap.clicked.connect(self.renameMap)
        self.pb_changeMap = QPushButton(_("Change Image"))
        self.pb_changeMap.clicked.connect(self.changeMap)
        self.pb_removeMap = QPushButton(_("Remove"))
        self.pb_removeMap.clicked.connect(self.deleteMap)

        self.sc_removeMap = QShortcut(QKeySequence("Del"), self)
        self.sc_removeMap.setAutoRepeat(False)
        self.sc_removeMap.activated.connect(self.deleteMap)

        box = QWidget()
        container = QHBoxLayout()

        container.addWidget(self.pb_addMapLiquipedia, 0)
        container.addWidget(self.pb_addMap, 0)
        container.addWidget(QLabel(), 4)
        container.addWidget(self.pb_renameMap, 0)
        container.addWidget(self.pb_changeMap, 0)
        container.addWidget(self.pb_removeMap, 0)
        box.setLayout(container)

        layout.addWidget(box, 2, 0, 1, 2)

        layout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding), 3,
            0, 1, 2)

        self.changePreview()
        self.mapsBox.setLayout(layout)

    def renameMap(self):
        """Rename maps."""
        item = self.maplist.currentItem()
        map = item.text()
        text, ok = QInputDialog.getText(self,
                                        _('Map Name'),
                                        _('Map Name') + ':',
                                        text=map)
        if not ok:
            return
        text = text.strip()
        if (text == map):
            return
        if text.lower() == 'tbd':
            QMessageBox.critical(
                self, _("Error"),
                _('"{}" is not a valid map name.').format(text))
            return
        if (text in scctool.settings.maps):
            buttonReply = QMessageBox.warning(
                self, _("Duplicate Entry"),
                _("Map is already in list! Overwrite?"),
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if buttonReply == QMessageBox.No:
                return

        self.controller.addMap(self.controller.getMapImg(map, True), text)
        self.controller.deleteMap(map)
        item.setText(text)

    def changeMap(self):
        """Change a map."""
        map = self.maplist.currentItem().text()
        fileName, ok = QFileDialog.getOpenFileName(
            self, _("Select Map Image (> 500x500px recommended)"), "",
            _("Supported Images") + " (*.png *.jpg)")
        if ok:
            base = os.path.basename(fileName)
            name, ext = os.path.splitext(base)
            name = name.replace("_", " ")
            self.controller.deleteMap(map)
            self.controller.addMap(fileName, map)
            self.changePreview()

    def addMap(self):
        """Add a map."""
        fileName, ok = QFileDialog.getOpenFileName(
            self, _("Select Map Image (> 500x500px recommended)"), "",
            _("Supported Images") + " (*.png *.jpg)")
        if ok:
            base = os.path.basename(fileName)
            name, ext = os.path.splitext(base)
            name = name.replace("_", " ")
            map_name, ok = QInputDialog.getText(self,
                                                _('Map Name'),
                                                _('Map Name') + ':',
                                                text=name)
            map_name = map_name.strip()
            if ok:
                if map_name.lower() == 'tbd':
                    QMessageBox.critical(
                        self, _("Error"),
                        _('"{}" is not a valid map name.').format(map_name))
                    return

                if (map_name in scctool.settings.maps):
                    buttonReply = QMessageBox.warning(
                        self, _("Duplicate Entry"),
                        _("Map is already in list! Overwrite?"),
                        QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                    if buttonReply == QMessageBox.No:
                        return
                    else:
                        self.controller.deleteMap(map_name)

                self.controller.addMap(fileName, map_name)
                items = self.maplist.findItems(map_name, Qt.MatchExactly)
                if len(items) == 0:
                    item = QListWidgetItem(map_name)
                    self.maplist.addItem(item)
                    self.maplist.setCurrentItem(item)
                else:
                    self.maplist.setCurrentItem(items[0])
                self.changePreview()

    def addFromLquipedia(self):
        grabber = LiquipediaGrabber()
        search_str = ''
        while True:
            search_str, ok = QInputDialog.getText(self,
                                                  _('Map Name'),
                                                  _('Map Name') + ':',
                                                  text=search_str)
            search_str.strip()
            try:
                if ok and search_str:
                    if search_str.lower() == 'tbd':
                        QMessageBox.critical(
                            self, _("Error"),
                            _('"{}" is not a valid map name.').format(
                                search_str))
                        continue
                    try:
                        map = grabber.get_map(search_str)
                    except MapNotFound:
                        QMessageBox.critical(
                            self, _("Map not found"),
                            _('"{}" was not found on Liquipedia.').format(
                                search_str))
                        continue
                    map_name = map.get_name()

                    if (map_name in scctool.settings.maps):
                        buttonReply = QMessageBox.warning(
                            self, _("Duplicate Entry"),
                            _("Map {} is already in list! Overwrite?".format(
                                map_name)), QMessageBox.Yes | QMessageBox.No,
                            QMessageBox.No)
                        if buttonReply == QMessageBox.No:
                            break
                        else:
                            self.controller.deleteMap(map_name)

                    images = grabber.get_images(map.get_map_images())
                    image = ""
                    for size in sorted(images):
                        if not image or size <= 2500 * 2500:
                            image = images[size]
                    url = grabber._base_url + image

                    downloader = MapDownloader(self, map_name, url)
                    downloader.download()
                    if map_name not in scctool.settings.maps:
                        scctool.settings.maps.append(map_name)
                    items = self.maplist.findItems(map_name, Qt.MatchExactly)
                    if len(items) == 0:
                        item = QListWidgetItem(map_name)
                        self.maplist.addItem(item)
                        self.maplist.setCurrentItem(item)
                    else:
                        self.maplist.setCurrentItem(items[0])
                    self.changePreview()
            except Exception as e:
                module_logger.exception("message")
                QMessageBox.critical(self, _("Error"), str(e))
            finally:
                break

    def deleteMap(self):
        """Delete a map."""
        item = self.maplist.currentItem()
        map = item.text()
        buttonReply = QMessageBox.question(
            self, _('Delete map?'),
            _("Delete '{}' permanently?").format(map),
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if buttonReply == QMessageBox.Yes:
            self.controller.deleteMap(map)
            self.maplist.takeItem(self.maplist.currentRow())

    def changePreview(self):
        """Change the map preview."""
        if self.maplist.count() < 1:
            return

        map = self.maplist.currentItem().text()
        if (map == "TBD"):
            self.pb_renameMap.setEnabled(False)
            self.pb_removeMap.setEnabled(False)
            self.sc_removeMap.setEnabled(False)
        else:
            self.pb_removeMap.setEnabled(True)
            self.pb_renameMap.setEnabled(True)
            self.sc_removeMap.setEnabled(True)

        file = self.controller.getMapImg(map, True)
        map = QPixmap(file)
        width = map.height()
        height = map.width()
        ext = os.path.splitext(file)[1].replace(".", "").upper()
        size = humanize.naturalsize(os.path.getsize(file))
        map = QPixmap(file).scaled(self.mapsize, self.mapsize,
                                   Qt.KeepAspectRatio)
        self.mapPreview.setPixmap(map)
        text = "{}x{}px, {}, {}".format(width, height, str(size), ext)
        self.mapInfo.setText(text)

    def createButtonGroup(self):
        """Create buttons."""
        try:
            layout = QHBoxLayout()

            layout.addWidget(QLabel(""))

            buttonCancel = QPushButton(_('Cancel'))
            buttonCancel.clicked.connect(self.closeWindow)
            layout.addWidget(buttonCancel)

            buttonSave = QPushButton(_('&Save && Close'))
            buttonSave.setToolTip(_("Shortcut: {}").format("Ctrl+S"))
            self.shortcut = QShortcut(QKeySequence("Ctrl+S"), self)
            self.shortcut.setAutoRepeat(False)
            self.shortcut.activated.connect(self.saveCloseWindow)
            buttonSave.clicked.connect(self.saveCloseWindow)
            layout.addWidget(buttonSave)

            self.buttonGroup = layout
        except Exception as e:
            module_logger.exception("message")

    def saveData(self):
        """Save the data."""
        if (self.__dataChanged):
            scctool.settings.config.parser.set(
                "SCT", "myteams", ", ".join(self.list_favTeams.getData()))
            scctool.settings.config.parser.set(
                "SCT", "commonplayers",
                ", ".join(self.list_favPlayers.getData()))
            scctool.settings.config.parser.set("SCT", "tesseract",
                                               self.tesseract.text().strip())
            scctool.settings.config.parser.set("SCT", "use_ocr",
                                               str(self.cb_useocr.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "transparent_match_banner",
                str(self.cb_trans_banner.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "CtrlShiftS", str(self.cb_ctrlshifts.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "CtrlShiftC", str(self.cb_ctrlshiftc.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "swap_myteam", str(self.cb_swapTeams.isChecked()))
            scctool.settings.config.parser.set("SCT", "CtrlN",
                                               str(self.cb_ctrln.isChecked()))
            scctool.settings.config.parser.set("SCT", "CtrlX",
                                               str(self.cb_ctrlx.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "CtrlShiftR", str(self.cb_ctrlshiftr.currentText()))
            scctool.settings.config.parser.set(
                "SCT", "blacklist_on", str(self.cb_blacklist.isChecked()))
            scctool.settings.config.parser.set(
                "SCT", "blacklist", ", ".join(self.list_blacklist.getData()))

            self.__dataChanged = False

    def saveCloseWindow(self):
        """Save and close window."""
        self.saveData()
        self.passEvent = True
        self.close()

    def closeWindow(self):
        """Close window."""
        self.passEvent = True
        self.close()

    def closeEvent(self, event):
        """Handle close event."""
        try:
            self.mainWindow.updateMapCompleters()
            if (not self.__dataChanged):
                event.accept()
                return
            if (not self.passEvent):
                if (self.isMinimized()):
                    self.showNormal()
                buttonReply = QMessageBox.question(
                    self, _('Save data?'), _("Save data?"),
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if buttonReply == QMessageBox.Yes:
                    self.saveData()
            event.accept()
        except Exception as e:
            module_logger.exception("message")
class EditorGeneral(QWidget):
    """EditorGeneral widget class."""

    def __init__(self, parent):
        super(EditorGeneral, self).__init__()
        self._preferences, vbox = parent, QVBoxLayout(self)
        self.original_style = copy.copy(resources.CUSTOM_SCHEME)
        self.current_scheme, self._modified_editors = 'default', []
        self._font = settings.FONT

        groupBoxMini = QGroupBox(
            translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP)
        groupBoxTypo = QGroupBox(
            translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY)
        groupBoxScheme = QGroupBox(
            translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME)

        #Minimap
        formMini = QGridLayout(groupBoxMini)
        formMini.setContentsMargins(5, 15, 5, 5)
        self._checkShowMinimap = QCheckBox(
            translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP)
        self._spinMaxOpacity = QSpinBox()
        self._spinMaxOpacity.setRange(0, 100)
        self._spinMaxOpacity.setSuffix("% Max.")
        self._spinMinOpacity = QSpinBox()
        self._spinMinOpacity.setRange(0, 100)
        self._spinMinOpacity.setSuffix("% Min.")
        self._spinSize = QSpinBox()
        self._spinSize.setMaximum(100)
        self._spinSize.setMinimum(0)
        self._spinSize.setSuffix(
            translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP)
        formMini.addWidget(self._checkShowMinimap, 0, 1)
        formMini.addWidget(QLabel(
            translations.TR_PREFERENCES_EDITOR_GENERAL_SIZE_MINIMAP), 1, 0,
            Qt.AlignRight)
        formMini.addWidget(self._spinSize, 1, 1)
        formMini.addWidget(QLabel(
            translations.TR_PREFERENCES_EDITOR_GENERAL_OPACITY), 2, 0,
            Qt.AlignRight)
        formMini.addWidget(self._spinMinOpacity, 2, 1)
        formMini.addWidget(self._spinMaxOpacity, 2, 2)
        #Typo
        gridTypo = QGridLayout(groupBoxTypo)
        gridTypo.setContentsMargins(5, 15, 5, 5)
        self._btnEditorFont = QPushButton('')
        gridTypo.addWidget(QLabel(
            translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0,
            Qt.AlignRight)
        gridTypo.addWidget(self._btnEditorFont, 0, 1)
        #Scheme
        vboxScheme = QVBoxLayout(groupBoxScheme)
        vboxScheme.setContentsMargins(5, 15, 5, 5)
        self._listScheme = QListWidget()
        vboxScheme.addWidget(self._listScheme)
        hbox = QHBoxLayout()
        btnDownload = QPushButton(
            translations.TR_PREFERENCES_EDITOR_DOWNLOAD_SCHEME)
        btnDownload.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        btnDownload.clicked['bool'].connect(self._open_schemes_manager)
        hbox.addWidget(btnDownload)
        btnAdd = QPushButton(QIcon(":img/add"),
                             translations.TR_EDITOR_CREATE_SCHEME)
        btnAdd.setIconSize(QSize(16, 16))
        btnAdd.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        btnAdd.clicked['bool'].connect(self._open_schemes_designer)
        btnRemove = QPushButton(QIcon(":img/delete"),
                                translations.TR_EDITOR_REMOVE_SCHEME)
        btnRemove.setIconSize(QSize(16, 16))
        btnRemove.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        btnRemove.clicked['bool'].connect(self._remove_scheme)
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox.addWidget(btnAdd)
        hbox.addWidget(btnRemove)
        vboxScheme.addLayout(hbox)

        vbox.addWidget(groupBoxMini)
        vbox.addWidget(groupBoxTypo)
        vbox.addWidget(groupBoxScheme)

        #Settings
        qsettings = IDE.ninja_settings()
        qsettings.beginGroup('preferences')
        qsettings.beginGroup('editor')
        self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP)
        if settings.IS_MAC_OS:
            self._spinMinOpacity.setValue(100)
            self._spinMaxOpacity.setValue(100)
            self._spinMinOpacity.setDisabled(True)
            self._spinMaxOpacity.setDisabled(True)
        else:
            self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100)
            self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100)
        self._spinSize.setValue(settings.SIZE_PROPORTION * 100)
        btnText = ', '.join(self._font.toString().split(',')[0:2])
        self._btnEditorFont.setText(btnText)
        self._listScheme.clear()
        self._listScheme.addItem('default')
        self._schemes = json_manager.load_editor_skins()
        for item in self._schemes:
            self._listScheme.addItem(item)
        items = self._listScheme.findItems(
            qsettings.value('scheme', defaultValue='',
                            type='QString'), Qt.MatchExactly)
        if items:
            self._listScheme.setCurrentItem(items[0])
        else:
            self._listScheme.setCurrentRow(0)
        qsettings.endGroup()
        qsettings.endGroup()

        #Signals
        self._btnEditorFont.clicked['bool'].connect(self._load_editor_font)
        self._listScheme.itemSelectionChanged.connect(self._preview_style)
        self._preferences.savePreferences.connect(self.save)

    def _open_schemes_manager(self):
        ninjaide = IDE.getInstance()
        ninjaide.show_schemes()
        # refresh schemes

    def _open_schemes_designer(self):
        name = self._listScheme.currentItem().text()
        scheme = self._schemes.get(name, resources.COLOR_SCHEME)
        designer = preferences_editor_scheme_designer.EditorSchemeDesigner(
            scheme, self)
        designer.exec_()
        if designer.saved:
            scheme_name = designer.line_name.text()
            scheme = designer.original_style
            self._schemes[scheme_name] = scheme
            result = self._listScheme.findItems(scheme_name, Qt.MatchExactly)
            if not result:
                self._listScheme.addItem(scheme_name)

    def _remove_scheme(self):
        name = self._listScheme.currentItem().text()
        fileName = ('{0}.color'.format(
            file_manager.create_path(resources.EDITOR_SKINS, name)))
        file_manager.delete_file(fileName)
        item = self._listScheme.takeItem(self._listScheme.currentRow())
        del item

    def hideEvent(self, event):
        super(EditorGeneral, self).hideEvent(event)
        resources.CUSTOM_SCHEME = self.original_style
        for editorWidget in self._modified_editors:
            try:
                editorWidget.restyle(editorWidget.lang)
            except RuntimeError:
                print('the editor has been removed')

    def _preview_style(self):
        scheme = self._listScheme.currentItem().text()
        if scheme == self.current_scheme:
            return
        main_container = IDE.get_service('main_container')
        if not main_container:
            return
        editorWidget = main_container.get_current_editor()
        if editorWidget is not None:
            resources.CUSTOM_SCHEME = self._schemes.get(
                scheme,
                resources.COLOR_SCHEME)
            editorWidget.restyle(editorWidget.lang)
            self._modified_editors.append(editorWidget)
        self.current_scheme = scheme

    def _load_editor_font(self):
        try:
            font, ok = QFontDialog.getFont(self._font, self)
            if ok:
                self._font = font
                btnText = ', '.join(self._font.toString().split(',')[0:2])
                self._btnEditorFont.setText(btnText)
        except:
            QMessageBox.warning(
                self,
                translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE,
                translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY)

    def save(self):
        qsettings = IDE.ninja_settings()
        settings.FONT = self._font
        qsettings.setValue('preferences/editor/font', settings.FONT)
        settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked()
        settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0
        settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0
        settings.SIZE_PROPORTION = self._spinSize.value() / 100.0
        qsettings.setValue('preferences/editor/minimapMaxOpacity',
                           settings.MINIMAP_MAX_OPACITY)
        qsettings.setValue('preferences/editor/minimapMinOpacity',
                           settings.MINIMAP_MIN_OPACITY)
        qsettings.setValue('preferences/editor/minimapSizeProportion',
                           settings.SIZE_PROPORTION)
        qsettings.setValue('preferences/editor/minimapShow',
                           settings.SHOW_MINIMAP)
        scheme = self._listScheme.currentItem().text()
        resources.CUSTOM_SCHEME = self._schemes.get(scheme,
                                                    resources.COLOR_SCHEME)
        qsettings.setValue('preferences/editor/scheme', scheme)
Пример #28
0
class GlyphSetTab(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.name = self.tr("Glyph sets")

        self.defaultGlyphSetBox = QCheckBox(
            self.tr("Default glyph set:"), self)
        self.defaultGlyphSetDrop = QComboBox(self)
        self.defaultGlyphSetBox.toggled.connect(self.toggleGlyphSetDrop)

        self.glyphSetList = QListWidget(self)
        self.glyphSetList.setSortingEnabled(True)
        self.glyphSetContents = QPlainTextEdit(self)
        self.glyphSetList.currentItemChanged.connect(
            self.updateGlyphSetContents)
        self.glyphSetList.itemChanged.connect(self.renameGlyphSet)
        self._cachedName = None
        splitter = QSplitter(self)
        splitter.addWidget(self.glyphSetList)
        splitter.addWidget(self.glyphSetContents)
        self.addGlyphSetButton = QPushButton(self)
        self.addGlyphSetButton.setIcon(icons.i_plus())
        self.addGlyphSetButton.clicked.connect(lambda: self.addGlyphSet())
        self.removeGlyphSetButton = QPushButton(self)
        self.removeGlyphSetButton.setIcon(icons.i_minus())
        self.removeGlyphSetButton.clicked.connect(self.removeGlyphSet)
        self.importButton = QPushButton(self.tr("Import"), self)
        importMenu = QMenu(self)
        importMenu.addAction(
            self.tr("Import from Current Font"), self.importFromCurrentFont)
        self.importButton.setMenu(importMenu)
        self.glyphListBox = QCheckBox(self.tr("Glyph list path:"), self)
        self.glyphListEdit = QLineEdit(self)
        self.glyphListEdit.setReadOnly(True)
        self.glyphListButton = QPushButton(self.tr("Browse…"), self)
        self.glyphListButton.clicked.connect(self.getGlyphList)
        self.glyphListBox.toggled.connect(self.glyphListEdit.setEnabled)
        self.glyphListBox.toggled.connect(self.glyphListButton.setEnabled)

        buttonsLayout = QHBoxLayout()
        buttonsLayout.addWidget(self.addGlyphSetButton)
        buttonsLayout.addWidget(self.removeGlyphSetButton)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        buttonsLayout.addWidget(spacer)
        buttonsLayout.addWidget(self.importButton)

        firstLayout = QGridLayout()
        line = 0
        firstLayout.addWidget(self.defaultGlyphSetBox, line, 0, 1, 2)
        firstLayout.addWidget(self.defaultGlyphSetDrop, line, 3, 1, 3)
        line += 1
        firstLayout.addWidget(splitter, line, 0, 1, 6)
        line += 1
        firstLayout.addLayout(buttonsLayout, line, 0, 1, 3)
        secondLayout = QHBoxLayout()
        secondLayout.addWidget(self.glyphListBox)
        secondLayout.addWidget(self.glyphListEdit)
        secondLayout.addWidget(self.glyphListButton)
        mainLayout = QVBoxLayout(self)
        mainLayout.addLayout(firstLayout)
        mainLayout.addLayout(secondLayout)
        self.setLayout(mainLayout)

        self.readSettings()

    def addGlyphSet(self, glyphNames=[], glyphSetName=None):
        if glyphSetName is None:
            glyphSetName = self.tr("New glyph set")
        if glyphSetName in self.glyphSets:
            index = 1
            while "%s %d" % (glyphSetName, index) in self.glyphSets:
                index += 1
            glyphSetName = "%s %d" % (glyphSetName, index)
        self.glyphSets[glyphSetName] = glyphNames
        item = QListWidgetItem(glyphSetName, self.glyphSetList)
        item.setFlags(item.flags() | Qt.ItemIsEditable)
        self.glyphSetList.setCurrentItem(item)
        self.glyphSetList.editItem(item)
        self.removeGlyphSetButton.setEnabled(True)

    def removeGlyphSet(self):
        i = self.glyphSetList.currentRow()
        text = self.glyphSetList.takeItem(i).text()
        del self.glyphSets[text]
        if self.glyphSetList.count() < 2:
            self.removeGlyphSetButton.setEnabled(False)

    def renameGlyphSet(self):
        newKey = self.glyphSetList.currentItem()
        if newKey is None:
            return
        newKey = newKey.text()
        self.glyphSets[newKey] = self.glyphSets[self._cachedName]
        del self.glyphSets[self._cachedName]

    def importFromCurrentFont(self):
        font = QApplication.instance().currentFont()
        name = "%s %s" % (font.info.familyName, font.info.styleName)
        self.addGlyphSet(font.glyphOrder, name)

    def toggleGlyphSetDrop(self):
        sender = self.sender()
        self.defaultGlyphSetDrop.setEnabled(sender.isChecked())

    def updateGlyphSetContents(self, current, previous):
        # store content of the textEdit in the glyphSet dict
        if previous is not None:
            glyphNames = self.glyphSetContents.toPlainText().split()
            self.glyphSets[previous.text()] = glyphNames
        # now update the text edit to current glyphSet
        glyphSetName = current.text()
        text = " ".join(self.glyphSets[glyphSetName])
        self.glyphSetContents.setPlainText(text)
        # cache current name for renames
        self._cachedName = glyphSetName

    def getGlyphList(self):
        fileFormats = (
            self.tr("Text file {}").format("(*.txt)"),
            self.tr("All files {}").format("(*.*)"),
        )
        path, _ = QFileDialog.getOpenFileName(
            self, self.tr("Open File"), '', ";;".join(fileFormats)
        )
        if path:
            self.glyphListEdit.setText(path)

    def readSettings(self):
        defaultGlyphSet = settings.defaultGlyphSet()
        self.defaultGlyphSetBox.setChecked(len(defaultGlyphSet))

        self.glyphSets = settings.readGlyphSets()
        self.defaultGlyphSetDrop.clear()
        self.defaultGlyphSetDrop.addItems(self.glyphSets.keys())

        self.glyphSetList.clear()
        glyphSetNames = self.glyphSets.keys()
        # Normally we should be enforcing this rather decently in the interface
        # already
        if glyphSetNames:
            for glyphSetName in glyphSetNames:
                item = QListWidgetItem(glyphSetName, self.glyphSetList)
                item.setFlags(item.flags() | Qt.ItemIsEditable)
            self.glyphSetList.setCurrentRow(0)
        self.removeGlyphSetButton.setEnabled(len(self.glyphSets) > 1)

        glyphListPath = settings.glyphListPath()
        self.glyphListBox.setChecked(bool(glyphListPath))
        self.glyphListEdit.setEnabled(bool(glyphListPath))
        self.glyphListEdit.setText(glyphListPath)
        self.glyphListButton.setEnabled(bool(glyphListPath))

    def writeSettings(self):
        # store content of the textEdit in the glyphSet dict
        glyphNames = self.glyphSetContents.toPlainText().split()
        currentGlyphSet = self.glyphSetList.currentItem().text()
        self.glyphSets[currentGlyphSet] = glyphNames

        settings.writeGlyphSets(self.glyphSets)
        if not self.defaultGlyphSetBox.isChecked():
            settings.setDefaultGlyphSet(None)
        else:
            defaultGlyphSet = self.defaultGlyphSetDrop.currentText()
            settings.setDefaultGlyphSet(defaultGlyphSet)
        if not self.glyphListBox.isChecked():
            settings.setGlyphListPath(None)
        else:
            glyphListPath = self.glyphListEdit.text()
            if glyphListPath:
                settings.setGlyphListPath(glyphListPath)
                QApplication.instance().loadGlyphList()
class NewProjectManager(QDialog):

    def __init__(self, parent=None):
        super(NewProjectManager, self).__init__(parent, Qt.Dialog)
        self.setWindowTitle(translations.TR_NEW_PROJECT)
        self.setMinimumHeight(500)
        vbox = QVBoxLayout(self)
        vbox.addWidget(QLabel(translations.TR_CHOOSE_TEMPLATE))
        vbox.addWidget(QLabel(translations.TR_TAB_PROJECTS))

        hbox = QHBoxLayout()
        self.list_projects = QListWidget()
        self.list_projects.setProperty("wizard", True)
        hbox.addWidget(self.list_projects)

        self.list_templates = QListWidget()
        self.list_templates.setProperty("wizard", True)
        hbox.addWidget(self.list_templates)

        self.text_info = QTextBrowser()
        self.text_info.setProperty("wizard", True)
        hbox.addWidget(self.text_info)

        vbox.addLayout(hbox)

        hbox2 = QHBoxLayout()
        cancel = QPushButton(translations.TR_CANCEL)
        choose = QPushButton(translations.TR_CHOOSE)
        hbox2.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding,
                            QSizePolicy.Fixed))
        hbox2.addWidget(cancel)
        hbox2.addWidget(choose)
        vbox.addLayout(hbox2)

        self.template_registry = IDE.get_service("template_registry")
        categories = self.template_registry.list_project_categories()
        for category in categories:
            self.list_projects.addItem(category)

        cancel.clicked['bool'].connect(self.close)
        choose.clicked['bool'].connect(self._start_wizard)
        self.list_projects.itemSelectionChanged.connect(self._project_selected)
        self.list_templates.itemSelectionChanged.connect(self._template_selected)

    def _project_selected(self):
        self.list_templates.clear()
        item = self.list_projects.currentItem()
        category = item.text()
        for template in self.template_registry.list_templates_for_cateogory(
                category):
            item = QListWidgetItem(template.type_name)
            item.setData(Qt.UserRole, template)
            item = self.list_templates.addItem(item)

    def _template_selected(self):
        item = self.list_templates.currentItem()
        ptype = item.data(Qt.UserRole)
        self.text_info.setText(ptype.description)

    def _start_wizard(self):
        return QMessageBox.critical(self, "Beta Info", "Can not construct this segment!")
        item = self.list_templates.currentItem()
        if item is not None:
            ptype = item.data(Qt.UserRole)
Пример #30
0
class ListEdit(QWidget):
    """A widget to edit a list of items (e.g. a list of directories)."""

    # emitted when anything changed in the listbox.
    changed = pyqtSignal()

    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        layout = QGridLayout(self)
        self.setLayout(layout)

        self.addButton = QPushButton(icons.get('list-add'), '')
        self.editButton = QPushButton(icons.get('document-edit'), '')
        self.removeButton = QPushButton(icons.get('list-remove'), '')
        self.listBox = QListWidget()

        layout.setContentsMargins(1, 1, 1, 1)
        layout.setSpacing(0)
        layout.addWidget(self.listBox, 0, 0, 8, 1)
        layout.addWidget(self.addButton, 0, 1)
        layout.addWidget(self.editButton, 1, 1)
        layout.addWidget(self.removeButton, 2, 1)

        self.changed.connect(self.updateSelection)
        self.listBox.itemSelectionChanged.connect(self.updateSelection)
        self.updateSelection()
        self.connectSlots()
        app.translateUI(self)

    def connectSlots(self):
        self.addButton.clicked.connect(self.addClicked)
        self.editButton.clicked.connect(self.editClicked)
        self.removeButton.clicked.connect(self.removeClicked)
        self.listBox.itemDoubleClicked.connect(self.itemDoubleClicked)
        self.listBox.model().layoutChanged.connect(self.changed)

    def translateUI(self):
        self.addButton.setText(_("&Add..."))
        self.editButton.setText(_("&Edit..."))
        self.removeButton.setText(_("&Remove"))

    def addClicked(self, button):
        item = self.createItem()
        if self.openEditor(item):
            self.addItem(item)

    def editClicked(self, button):
        item = self.listBox.currentItem()
        item and self.editItem(item)

    def removeClicked(self, button):
        item = self.listBox.currentItem()
        if item:
            self.removeItem(item)
            
    def updateSelection(self):
        selected = bool(self.listBox.currentItem())
        self.editButton.setEnabled(selected)
        self.removeButton.setEnabled(selected)

    def itemDoubleClicked(self, item):
        item and self.editItem(item)

    def createItem(self):
        return QListWidgetItem()

    def addItem(self, item):
        self.listBox.addItem(item)
        self.itemChanged(item)
        self.changed.emit()

    def removeItem(self, item):
        self.listBox.takeItem(self.listBox.row(item))
        self.changed.emit()

    def editItem(self, item):
        if self.openEditor(item):
            self.itemChanged(item)
            self.changed.emit()

    def setCurrentItem(self, item):
        self.listBox.setCurrentItem(item)

    def setCurrentRow(self, row):
        self.listBox.setCurrentRow(row)

    def openEditor(self, item):
        """Opens an editor (dialog) for the item.

        Returns True if the dialog was accepted and the item edited.
        Returns False if the dialog was cancelled (the item must be left
        unedited).
        """
        pass

    def itemChanged(self, item):
        """Called after an item has been added or edited.

        Re-implement to do something at this moment if needed, e.g. alter the
        text or display of other items.
        """
        pass

    def setValue(self, strings):
        """Sets the listbox to a list of strings."""
        self.listBox.clear()
        self.listBox.addItems(strings)
        self.changed.emit()

    def value(self):
        """Returns the list of paths in the listbox."""
        return [self.listBox.item(i).text()
            for i in range(self.listBox.count())]

    def setItems(self, items):
        """Sets the listbox to a list of items."""
        self.listBox.clear()
        for item in items:
            self.listBox.addItem(item)
            self.itemChanged(item)
        self.changed.emit()

    def items(self):
        """Returns the list of items in the listbox."""
        return [self.listBox.item(i)
            for i in range(self.listBox.count())]

    def clear(self):
        """Clears the listbox."""
        self.listBox.clear()
        self.changed.emit()
Пример #31
0
class SessionsManager(QDialog):

    """Session Manager, to load different configurations of ninja."""

    def __init__(self, parent=None):
        super(SessionsManager, self).__init__(parent, Qt.Dialog)
        self._ide = parent
        self.setWindowTitle(translations.TR_SESSIONS_TITLE)
        self.setMinimumWidth(400)
        vbox = QVBoxLayout(self)
        vbox.addWidget(QLabel(translations.TR_SESSIONS_DIALOG_BODY))
        self.sessionList = QListWidget()
        self.sessionList.addItems([key for key in settings.SESSIONS])
        self.sessionList.setCurrentRow(0)
        self.contentList = QListWidget()
        self.btnDelete = QPushButton(translations.TR_SESSIONS_BTN_DELETE)
        self.btnDelete.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.btnUpdate = QPushButton(translations.TR_SESSIONS_BTN_UPDATE)
        self.btnUpdate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.btnCreate = QPushButton(translations.TR_SESSIONS_BTN_CREATE)
        self.btnCreate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.btnOpen = QPushButton(translations.TR_SESSIONS_BTN_ACTIVATE)
        self.btnOpen.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.btnOpen.setDefault(True)
        hbox = QHBoxLayout()
        hbox.addWidget(self.btnDelete)
        hbox.addWidget(self.btnUpdate)
        hbox.addWidget(self.btnCreate)
        hbox.addWidget(self.btnOpen)

        vbox.addWidget(self.sessionList)
        vbox.addWidget(self.contentList)
        vbox.addLayout(hbox)

        self.sessionList.itemSelectionChanged.connect(self.load_session_content)
        self.btnOpen.clicked['bool'].connect(self.open_session)
        self.btnUpdate.clicked['bool'].connect(self.save_session)
        self.btnCreate.clicked['bool'].connect(self.create_session)
        self.btnDelete.clicked['bool'].connect(self.delete_session)
        self.load_session_content()

    def load_session_content(self):
        """Load the selected session, replacing the current session."""
        item = self.sessionList.currentItem()
        self.contentList.clear()
        if item is not None:
            key = item.text()
            files = [translations.TR_FILES] + \
                [file[0] for file in settings.SESSIONS[key][0]]
            projects = [translations.TR_PROJECT] + settings.SESSIONS[key][1]
            content = files + projects
            self.contentList.addItems(content)

    def create_session(self):
        """Create a new Session."""
        sessionInfo = QInputDialog.getText(None,
            translations.TR_SESSIONS_CREATE_TITLE,
            translations.TR_SESSIONS_CREATE_BODY)
        if sessionInfo[1]:
            sessionName = sessionInfo[0]
            if not sessionName or sessionName in settings.SESSIONS:
                QMessageBox.information(self,
                    translations.TR_SESSIONS_MESSAGE_TITLE,
                    translations.TR_SESSIONS_MESSAGE_BODY)
                return
            SessionsManager.save_session_data(sessionName, self._ide)
        self._ide.Session = sessionName
        self.close()

    @classmethod
    def save_session_data(cls, sessionName, ide):
        """Save the updates from a session."""
        openedFiles = ide.filesystem.get_files()
        files_info = []
        for path in openedFiles:
            editable = ide.get_or_create_editable(path)
            if editable.is_dirty:
                stat_value = 0
            else:
                stat_value = os.stat(path).st_mtime
            files_info.append([path,
                               editable.editor.getCursorPosition(), stat_value])
        projects_obj = ide.filesystem.get_projects()
        projects = [projects_obj[proj].path for proj in projects_obj]
        settings.SESSIONS[sessionName] = [files_info, projects]
        qsettings = ide.data_settings()
        qsettings.setValue('ide/sessions', settings.SESSIONS)

    def save_session(self):
        """Save current session"""
        if self.sessionList.currentItem():
            sessionName = self.sessionList.currentItem().text()
            SessionsManager.save_session_data(sessionName, self._ide)
            self._ide.show_message(translations.TR_SESSIONS_UPDATED_NOTIF %
                                   {'session': sessionName}, 2000)
            self.load_session_content()

    def open_session(self):
        """Open a saved session"""
        if self.sessionList.currentItem():
            key = self.sessionList.currentItem().text()
            self._load_session_data(key)
            self._ide.Session = key
            self.close()

    def delete_session(self):
        """Delete a session"""
        if self.sessionList.currentItem():
            key = self.sessionList.currentItem().text()
            settings.SESSIONS.pop(key)
            self.sessionList.takeItem(self.sessionList.currentRow())
            self.contentList.clear()
            qsettings = self._ide.data_settings()
            qsettings.setValue('ide/sessions', settings.SESSIONS)

    def _load_session_data(self, key):
        """Activate the selected session, closing the current files/projects"""
        main_container = self._ide.get_service('main_container')
        projects_explorer = self._ide.get_service('projects_explorer')
        if projects_explorer and main_container:
            projects_explorer.close_opened_projects()
            for fileData in settings.SESSIONS[key][0]:
                path, line, stat_value = fileData
                if file_manager.file_exists(path):
                    mtime = os.stat(path).st_mtime
                    ignore_checkers = (mtime == stat_value)
                    main_container.open_file(path, line,
                                             ignore_checkers=ignore_checkers)
            if projects_explorer:
                projects_explorer.load_session_projects(
                    settings.SESSIONS[key][1])
Пример #32
0
class ListEntry(BaseParamWidget):
    def __init__(self, layout_dir: str, title: str,
                 initial_value: List[List[str]], new_id_func: Callable):
        super().__init__(layout_dir)
        self.choices = []
        self.text_list = []
        lab_title = QLabel(text=title)
        layout = QHBoxLayout()
        self.central_layout.addWidget(lab_title)
        self.on_check_callback = None
        self.list_widget = QListWidget()
        self.set_value(initial_value)
        layout_tools = QVBoxLayout()
        self.button_add_item = QPushButton('+')
        self.button_delete_item = QPushButton('-')
        self.button_delete_item.clicked.connect(self.delete_row)
        self.button_add_item.clicked.connect(self.add_row)
        self.button_add_item.setMaximumWidth(20)
        self.button_delete_item.setMaximumWidth(20)
        layout_tools.addWidget(self.button_add_item)
        layout_tools.addWidget(self.button_delete_item)
        layout.addLayout(layout_tools)
        layout.addWidget(self.list_widget)
        self.central_layout.addLayout(layout)
        self.data = initial_value
        self.new_id_func = new_id_func

    def new_id(self):
        if callable(self.new_id_func):
            return self.new_id_func()
        else:
            return None

    def add_row(self):
        self.data[0].append(self.new_id())
        self.data[1].append('Unnamed')
        self.set_value(self.data)

    def delete_row(self):
        # item = self.list_widget.currentItem()
        index = self.list_widget.currentIndex().row()
        self.data[0].pop(index)
        self.data[1].pop(index)
        self.set_value(self.data)

    def on_listwidget_double_cicked(self):
        print('edit')
        item = self.list_widget.currentItem()
        self.list_widget.editItem(item)

    def get_value(self):
        text = []
        for i in range(self.list_widget.count()):
            text.append(self.list_widget.item(i).text())
        self.data[1] = text
        return self.data

    def set_value(self, data: List[List[str]]):
        self.list_widget.clear()
        self.list_widget.addItems(data[1])
        self.data = data
        for index in range(self.list_widget.count()):
            item = self.list_widget.item(index)
            item.setFlags(item.flags() | Qt.ItemIsEditable)
Пример #33
0
class MainWindow(QMainWindow):
    def __init__(self, *args):
        QMainWindow.__init__(self)
        self.current_image = None
        self.createComponents()
        self.loadFromBufferMemory()
        #print("Input file type", type(input_file))
        self.createMenu()
        self.createLayout()
        self.createConnects()
        self.setWindowTitle('Micrograph Selection Tool')

    def createComponents(self):
        self.buttonLoad = QPushButton('Load')
        self.buttonSave = QPushButton('Save')
        self.buttonKeep = QPushButton('Keep (Right arrow key)')
        self.buttonKeep.setStyleSheet('QPushButton {color: green;}')
        self.buttonDiscard = QPushButton('Discard (Left arrow key)')
        self.buttonDiscard.setStyleSheet('QPushButton {color: red;}')
        self.fileList = QListWidget()
        self.micrograph = emimage2d.EMImage2DWidget(image=EMAN2.EMData(
            700, 700),
                                                    application=app,
                                                    parent=self)
        self.powerSpectrum = emimage2d.EMImage2DWidget(image=EMAN2.EMData(
            700, 700),
                                                       application=app,
                                                       parent=self)
        self.all_items = []

    def loadFromBufferMemory(self):
        """loads the content from the buffer database"""
        image_list = []
        buffer_lines = []
        self.buffer_path = "/home/turi/Schreibtisch/buffermemory.txt"

        with open(self.buffer_path) as buffer:
            buffer = buffer.read()
            if len(buffer) > 0:
                buffer_lines = buffer.split(',')
                print("buffer", buffer_lines)
            else:
                print("Buffer is empty")

        for image_index in range(len(buffer_lines)):
            # cleans the image name and status to add them in the GUI
            image_path = str(buffer_lines[image_index].split(':')[0])
            print("imagepath", image_path)
            image_status = str(buffer_lines[image_index].split(':')[1])
            print("imagestatus", image_status)

            # remove symbols from the image_name string
            if "(u'" in image_path:
                image_path = image_path.replace("(u'", "")
            if "',)" in image_path:
                image_path = image_path.replace("',)", "")
            if "\n" in image_path:
                image_path = image_path.replace("\n", "")
            if "'" in image_path:
                image_path = image_path.replace("'", "")
            if "\"" in image_path:
                image_path = image_path.replace("\"", "")
            if "[" in image_path:
                image_path = image_path.replace("[", "")
            if "]" in image_path:
                image_path = image_path.replace("]", "")
            if "\\" in image_path:
                image_path = image_path.replace("\\", "")

            image_name = QFileInfo(image_path).fileName()
            image_list.append(image_path)  # adds the name
            item = QListWidgetItem(image_name)

            # remove symbols from the status string
            if "(u'" in image_status:
                image_status = image_status.replace("(u'", "")
            if "',)" in image_status:
                image_status = image_status.replace("',)", "")
            if "\n" in image_status:
                image_status = image_status.replace("\n", "")
            if "'" in image_status:
                image_status = image_status.replace("'", "")
            if "[" in image_status:
                image_status = image_status.replace("[", "")
            if "]" in image_status:
                image_status = image_status.replace("]", "")

            if image_status == "checked":
                item.setCheckState(Qt.Checked)
            if image_status == "unchecked":
                item.setCheckState(Qt.Unchecked)

            self.fileList.addItem(item)

        if len(image_list) > 0:
            self.uploadMicrographs(image_list=image_list,
                                   upload_from_buffer=True)
        else:
            pass

    def createLayout(self):
        """layout: left, middle, right layouts, all three are vertically structured"""
        layoutMain = QHBoxLayout()

        layoutLeft = QVBoxLayout()
        layoutLeft.addWidget(self.buttonLoad)
        layoutLeft.addWidget(self.fileList)
        layoutLeft.addWidget(self.buttonSave)

        layoutMiddle = QVBoxLayout()
        layoutMiddle.addWidget(self.micrograph)
        layoutMiddle.addWidget(self.buttonKeep)

        layoutRight = QVBoxLayout()
        layoutRight.addWidget(self.powerSpectrum)
        layoutRight.addWidget(self.buttonDiscard)

        layoutMain.addLayout(layoutLeft, stretch=1)
        layoutMain.addLayout(layoutMiddle, stretch=2)
        layoutMain.addLayout(layoutRight, stretch=2)

        widgetMain = QWidget()
        widgetMain.setLayout(layoutMain)
        self.setCentralWidget(widgetMain)

    def createMenu(self):
        self.actionOpenData = QAction(("Open file.."), self)
        self.actionSaveData = QAction(("Save"), self)
        self.actionSelectAll = QAction(("Select all"), self)
        self.actionDeselectAll = QAction(("Deselect all"), self)
        self.actionSetCheck_fromKeepFile = QAction("Upload Keep/Discard Files",
                                                   self)
        self.actionQuit = QAction(("Quit"), self)
        self.actionQuit.setMenuRole(QAction.QuitRole)

        menu_file = self.menuBar().addMenu("File")
        menu_file.addAction(self.actionOpenData)
        menu_file.addAction(self.actionSaveData)
        menu_file.addAction(self.actionSelectAll)
        menu_file.addAction(self.actionDeselectAll)
        menu_file.addAction(self.actionSetCheck_fromKeepFile)
        menu_file.addSeparator()
        menu_file.addAction(self.actionQuit)

        self.menuBar().addMenu("Help")

    def createConnects(self):
        self.buttonLoad.clicked.connect(
            self.buttonLoad_clicked)  # function call without ()-sign
        self.buttonSave.clicked.connect(self.buttonSave_clicked)
        self.buttonKeep.clicked.connect(self.buttonKeep_clicked)
        self.buttonDiscard.clicked.connect(self.buttonDiscard_clicked)
        self.fileList.clicked.connect(self.changeImageByMouse)
        self.fileList.keyPressEvent = self.myKeyPressEvent
        self.micrograph.keyPressEvent = self.myKeyPressEvent
        self.powerSpectrum.keyPressEvent = self.myKeyPressEvent
        self.actionSelectAll.triggered.connect(self.selectAll)
        self.actionDeselectAll.triggered.connect(self.deselectAll)
        self.actionSetCheck_fromKeepFile.triggered.connect(
            self.setCheck_fromKeepFile)

    def myKeyPressEvent(self, buttonSignal):
        if self.fileList.count() > 0:
            if buttonSignal.key() == Qt.Key_Right:
                print
                "Right"
                self.arrowKeyRight_clicked()
            elif buttonSignal.key() == Qt.Key_Left:
                print
                "Left"
                self.arrowKeyLeft_clicked()
            elif buttonSignal.key() == Qt.Key_Up:
                print
                "Up"
                self.arrowKeyUp_clicked()
            elif buttonSignal.key() == Qt.Key_Down:
                print
                "Down!"
                self.arrowKeyDown_clicked()

    def loadMicrographsFromItemList(self, image_index):
        """creates an EMImage-Widget"""
        if self.current_image is None:
            image_path = self.all_items[image_index]  #
            self.current_image = EMAN2.EMData(image_path)
        self.micrograph.set_data(
            self.current_image
        )  # in project description as 'aaa' instead of 'micrograph'

    def loadPowerSpectrumFromItemList(self, image_index):
        """creates power spectrum of a micrograph"""
        # Try to load image from buffer
        # If buffer is empty, wait the image appears
        while True:
            load_successfull = False
            try:
                preload_image_path, preload_image_index, img, fft_img = img_buffer.popleft(
                )
                if preload_image_index == image_index:
                    load_successfull = True
            except IndexError as e:
                print("Index error", e)
                time.sleep(1)

            if load_successfull:
                break

        self.current_image = img
        self.powerSpectrum.set_data(fft_img)

    def preload_images(self, micrograph_list, img_buffer):
        """
        Preloads IMG_BUFFER_SIZE number of images into the memory.

        :param micrograph_list: list of all micrographs ######## mistake --> here it gets just a string not a list
        :param img_buffer: deque as buffer for images
        :return: None
        """
        print("preload_images micrograph_list", micrograph_list)
        offset = 0
        last_index = -1
        while True:
            index = self.fileList.row(self.fileList.currentItem())
            if last_index != -1:
                if index - last_index == 1:
                    offset = offset - 1
                elif index - last_index != 0:
                    offset = 0

            if len(img_buffer) < IMG_BUFFER_SIZE and (
                    index + offset) < len(micrograph_list):
                start = time.time()
                print("in", index + offset)
                print("micrograph_list", micrograph_list)
                filename = str(micrograph_list[index + offset])

                print("filename", filename)
                image = EMAN2.EMData(filename)

                fft_img = image.do_fft()

                fft_img.set_value_at(0, 0, 0, 0)
                fft_img.set_value_at(1, 0, 0, 0)
                fft_img.process_inplace("xform.phaseorigin.tocorner")
                fft_img.process_inplace("xform.fourierorigin.tocenter")
                fft_img = fft_img.get_fft_amplitude()

                img_buffer.append((filename, index + offset, image, fft_img))
                end = time.time()
                print("Put new image:", filename, "Current index", index,
                      "Image+offset:", index + offset, "offset", offset,
                      "time", end - start)
                offset = offset + 1
            else:
                time.sleep(1)

            last_index = index

    def buttonLoad_clicked(self):
        """"opens dialog for folder selection, """

        image_dir = QFileDialog.getExistingDirectory(parent=None,
                                                     caption=u"Open directory")
        image_dir = str(image_dir)

        image_list = []
        for root, dirs, files in os.walk(image_dir):
            for file in files:
                if (".mrc" or ".tiff" or ".tif" or ".hdf" or ".png") in file:
                    image_list.append(image_dir + "/" + file)
        #if no micrograph loaded
        if len(image_list) == 0:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Information)
            msg.setInformativeText("No images in the selected folder")
            msg.setStandardButtons(QMessageBox.Ok)
            msg.exec_()

        if len(image_list) > 0:
            self.uploadMicrographs(image_list=image_list,
                                   upload_from_buffer=False)
        else:
            pass

    def buttonSave_clicked(self):
        """the keep and discard image names are added to two independent text files one for keep one for discard"""

        save_dir = QFileDialog.getExistingDirectory(
            parent=None,
            caption="Directory of selected and discarded file with image names"
        )
        path_selected = str(save_dir) + "/" + "selected_images.txt"
        path_discarded = str(save_dir) + "/" + "discarded_images.txt"

        try:
            file_selected = open(path_selected, "w+")
            file_discarded = open(path_discarded, "w+")
        except IOError:
            return

        number_of_items = self.fileList.count()
        for index in range(number_of_items):  # as often as number of files
            if (self.fileList.item(index).checkState()) == Qt.Checked:
                file_selected.write(
                    os.path.basename(self.all_items[index]) + "\n")
            else:
                file_discarded.write(
                    os.path.basename(self.all_items[index]) + "\n")
        file_selected.close()
        file_discarded.close()

    def uploadMicrographs(self, image_list, upload_from_buffer):
        """loads the micrograph into the GUI and saves their path and status in buffer memory"""
        #global all_items  # maybe problematic?
        #all_items = []
        self.all_items = []
        image_path_and_status = []

        if upload_from_buffer == True:
            for image_path in image_list:
                # loads the micrograph names and status into the GUI
                self.all_items.append(image_path)

        if upload_from_buffer == False:
            self.fileList.clear()
            # add a try except tree
            for image_path in image_list:
                print
                "Path", image_path
                image_name = QFileInfo(image_path).fileName()
                item = QListWidgetItem(image_name)
                image_path = str(
                    image_path)  # contains the path and the name of the image
                self.all_items.append(image_path)

                image_path_and_status.append(image_path + ":" + "checked")

                item.setCheckState(Qt.Checked)
                self.fileList.addItem(item)

            # remove symbols from the list
            image_path_and_status = str(image_path_and_status)
            if "'" in image_path_and_status:
                image_path_and_status = image_path_and_status.replace("'", "")
            if "[" in image_path_and_status:
                image_path_and_status = image_path_and_status.replace("[", "")
            if "]" in image_path_and_status:
                image_path_and_status = image_path_and_status.replace("]", "")
            if " " in image_path_and_status:
                image_path_and_status = image_path_and_status.replace(" ", "")

            with open(self.buffer_path, "w") as buffer:
                buffer.write(image_path_and_status)

        if len(image_list) > 0:
            # loads the micrographs into the GUI
            self.fileList.setCurrentRow(0)
            thread.start_new_thread(self.preload_images, (
                image_list,
                img_buffer,
            ))
            self.loadPowerSpectrumFromItemList(0)
            self.loadMicrographsFromItemList(0)
            last_loaded_image = 0

    def writeToBuffer_check(self):
        """the status of the image is written to the buffer"""
        row_index = self.fileList.row(self.fileList.currentItem())

        with open(self.buffer_path, "r") as buffer:
            buffer_lines = buffer.read().split(",")
            buffer_line = buffer_lines[row_index].split(":")
            print(buffer_line)
            image_path = buffer_line[0]
            image_status = buffer_line[1]
            # order of checking importance: checked is included in unchecked !!!
            if "unchecked" in image_status:
                image_status = image_status.replace("unchecked", "checked")
            elif "checked" in image_status:
                pass
            buffer_lines[row_index] = str(image_path + ":" + image_status)

        buffer_lines = str(buffer_lines)
        if "'" in buffer_lines:
            buffer_lines = buffer_lines.replace("'", "")
        if "\"" in buffer_lines:
            buffer_lines = buffer_lines.replace("\"", "")
        if "[" in buffer_lines:
            buffer_lines = buffer_lines.replace("[", "")
        if "]" in buffer_lines:
            buffer_lines = buffer_lines.replace("]", "")
        if " " in buffer_lines:
            buffer_lines = buffer_lines.replace(" ", "")
        if "\\" in buffer_lines:
            buffer_lines = buffer_lines.replace("\\", "")

        print("Bufferline", str(buffer_lines))
        with open(self.buffer_path, "w") as buffer:
            buffer.write(str(buffer_lines))

    def writeToBuffer_uncheck(self):
        """the status of the image is written to the buffer"""
        row_index = self.fileList.row(self.fileList.currentItem())

        with open(self.buffer_path, "r") as buffer:
            buffer_lines = buffer.read().split(",")
            buffer_line = buffer_lines[row_index].split(":")
            image_path = buffer_line[0]
            image_status = buffer_line[1]
            # order of checking importance: checked is included in unchecked !!!
            if "unchecked" in image_status:
                pass
            elif "checked" in image_status:
                image_status = image_status.replace("checked", "unchecked")
            buffer_lines[row_index] = str(image_path + ":" + image_status)
            print("Puffer", buffer_lines)

        buffer_lines = str(buffer_lines)
        if "'" in buffer_lines:
            buffer_lines = buffer_lines.replace("'", "")
        if "\"" in buffer_lines:
            buffer_lines = buffer_lines.replace("\"", "")
        if "[" in buffer_lines:
            buffer_lines = buffer_lines.replace("[", "")
        if "]" in buffer_lines:
            buffer_lines = buffer_lines.replace("]", "")
        if " " in buffer_lines:
            buffer_lines = buffer_lines.replace(" ", "")
        if "\\" in buffer_lines:
            buffer_lines = buffer_lines.replace("\\", "")

        print("Bufferline", str(buffer_lines))
        with open(self.buffer_path, "w") as buffer:
            buffer.write(str(buffer_lines))

    def setCheck_fromKeepFile(self):
        """images are automatically selected or discarded according to saved keep files"""
        file_dirs = QFileDialog.getExistingDirectory(parent=None,
                                                     caption=u"Open files")

        file_list = []
        files_selected = []
        for root, dirs, files in os.walk(file_dirs):
            for file in files:
                if ("selected_images.txt") in file:
                    file_list.append(file_dirs + "/" + file)
                    files_selected.append(file_dirs + "/" + file)
                if ("discarded_images.txt") in file:
                    file_list.append(file_dirs + "/" + file)

        # if no micrograph loaded
        if len(file_list) == 0:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Information)
            msg.setInformativeText("No textfile in the selected folder")
            msg.setStandardButtons(QMessageBox.Ok)
            msg.exec_()

        else:
            for index in range(len(files_selected)):

                with open(files_selected[index], "r") as file:
                    selected_images = file.readlines()

                if len(selected_images) > 0:

                    if self.fileList.currentItem() is not None:
                        self.fileList.setCurrentRow(0)

                        for uploaded_image in self.all_items:
                            # image contains name and path
                            # all_items has the same order like self.fileList
                            uploaded_image = str(uploaded_image)
                            uploaded_image = uploaded_image.split("/")[
                                -1]  # removes the path, extracts the name

                            for index in range(len(selected_images)):
                                if "\n" in selected_images[index]:
                                    selected_images[index] = selected_images[
                                        index].replace("\n", "")

                            if uploaded_image in selected_images:
                                self.setCheck()
                                self.moveToNextItem()
                            else:
                                self.setUncheck()
                                self.moveToNextItem()

                    else:
                        pass

    def buttonKeep_clicked(self):
        if self.fileList.currentItem() is not None:
            self.setCheck()
            self.moveToNextItem()
            self.showImageOfCurrentRow()

    def buttonDiscard_clicked(self):
        if self.fileList.currentItem() is not None:
            self.setUncheck()
            self.moveToNextItem()
            self.showImageOfCurrentRow()

    def arrowKeyRight_clicked(self):
        self.setCheck()
        self.moveToNextItem()
        self.showImageOfCurrentRow()

    def arrowKeyLeft_clicked(self):
        self.setUncheck()
        self.moveToNextItem()
        self.showImageOfCurrentRow()

    def arrowKeyUp_clicked(self):
        self.moveToPrevItem()
        self.showImageOfCurrentRow()

    def arrowKeyDown_clicked(self):
        self.moveToNextItem()
        self.showImageOfCurrentRow()

    def setCheck(self):
        self.fileList.currentItem().setCheckState(Qt.Checked)
        self.writeToBuffer_check()

    def setUncheck(self):
        self.fileList.currentItem().setCheckState(Qt.Unchecked)
        self.writeToBuffer_uncheck()

    def selectAll(self):
        """all images get the checked status"""
        print("bbb")
        self.fileList.setCurrentRow(0)
        self.loadPowerSpectrumFromItemList(0)
        self.loadMicrographsFromItemList(0)
        print(len(self.all_items))

        for row_index in range(len(self.all_items)):
            print("bbbbb")
            self.setCheck()
            self.moveToNextItem()

    def deselectAll(self):
        """all images get the unchecked status"""
        print("ccc")
        self.fileList.setCurrentRow(0)
        self.loadPowerSpectrumFromItemList(0)
        self.loadMicrographsFromItemList(0)
        print(len(self.all_items))

        for row_index in range(len(self.all_items)):
            print("ccccc")
            self.setUncheck()
            self.moveToNextItem()

    def moveToNextItem(self):
        row_index = self.fileList.row(self.fileList.currentItem())
        self.fileList.setCurrentRow(row_index + 1)
        if row_index >= (self.fileList.count()) - 1:
            self.fileList.setCurrentRow(0)

    def moveToPrevItem(self):
        row_index = self.fileList.row(self.fileList.currentItem())
        self.fileList.setCurrentRow(row_index - 1)
        if row_index >= (self.fileList.count()) - 1:
            self.fileList.setCurrentRow(0)

    def changeImageByMouse(self):
        self.showImageOfCurrentRow()

    def showImageOfCurrentRow(self):
        """the image of current row is shown"""
        global last_loaded_image  # maybe problematic?
        row_index = self.fileList.row(self.fileList.currentItem())
        if last_loaded_image - row_index != 0:
            self.loadPowerSpectrumFromItemList(row_index)
            self.loadMicrographsFromItemList(row_index)
            last_loaded_image = row_index
Пример #34
0
class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
#        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)
#        self.setAttribute(Qt.WA_TranslucentBackground)
        self.resize(900, 700)
        self.__search_mode = {'fuzzy':   'fuzzy_search',
                              'precise': 'precise_search',
                              'reg':     'reg_search'}
        # self.__pbn_switch_view = None

        # 创建窗口部件
        self.__widget_frame = QLabel()

        # window title
        self.__lab_title_fram = QLabel()
        self.__lab_title = QLabel('搜索辅助工具')
        self.__lab_title.setAlignment(Qt.AlignCenter)

        self.__lab_open_tool = QLabel('打开文件方式')
        self.__ln_open_tool = QLineEdit()
        self.__pbn_open_tool = QToolButton()
        self.__pbn_open_tool.setText('选择...')
        self.__ln_open_tool.setFixedHeight(20)
        self.__ln_open_tool.setFixedWidth(150)
        self.__pbn_open_tool.setFixedSize(48, 20)
        self.__lab_title_fram.setFixedHeight(50)

        # search mode
        self.__lab_mode_fram = QLabel()
        self.__rbn_fuzzy = QRadioButton('模糊搜索')
        self.__rbn_precise = QRadioButton('精确搜索')
        self.__rbn_reg = QRadioButton('正则表达式搜索')
        self.__rbn_fuzzy.setChecked(True)
        self.__lab_mode_fram.setFixedHeight(22)

        # search pattern
        self.__lab_pattern_fram = QLabel()
        self.__ln_file_name = QLineEdit()
        self.__ln_file_name.setPlaceholderText('请输入搜索条件或正则表达式......')
        self.__rbn_reg_Iyes = QRadioButton('区分大小写')
        self.__rbn_reg_Ino = QRadioButton('不区分大小写')
        self.__lab_pattern_fram.setFixedHeight(20)

        # search path
        self.__lab_path_fram = QLabel()
        self.__ln_file_path = QLineEdit()
        self.__ln_file_path.setPlaceholderText('请选择或输入路径......')
        self.__pbn_file_path = QToolButton()
        self.__pbn_file_path.setText('浏览...')
        self.__rbn_search_file = QRadioButton('检索文件名')
        self.__rbn_search_content = QRadioButton('检索文件内容')
        self.__pbn_file_path.setFixedSize(48, 20)
        self.__lab_path_fram.setFixedHeight(20)

        # search state
        self.__lab_state_fram = QLabel()
        self.__lab_state = QLabel('状态:暂无搜索结果!')
        self.__pbn_search = QPushButton('开始')
        self.__pbn_stop = QPushButton('停止')
        self.__pbn_search.setFixedWidth(89)
        self.__pbn_stop.setFixedWidth(89)
        self.__lab_state_fram.setFixedHeight(35)

        # search result
        self.__tabView = QTabWidget()
        self.__browser_result = QListWidget()
        self.__browser_error = QTextBrowser()
        self.__tabView.addTab(self.__browser_result, '匹配结果')
        self.__tabView.addTab(self.__browser_error, '错误结果')

        self.__btn_group_type = QButtonGroup()
        self.__btn_group_type.addButton(self.__rbn_search_file)
        self.__btn_group_type.addButton(self.__rbn_search_content)
        self.__rbn_search_file.setChecked(True)

        # radiobutton group
        self.__btn_group_re_I = QButtonGroup()
        self.__btn_group_re_I.addButton(self.__rbn_reg_Iyes)
        self.__btn_group_re_I.addButton(self.__rbn_reg_Ino)
        self.__rbn_reg_Iyes.setChecked(True)

        # lines
        '''
        self.__line_1 = QFrame()
        self.__line_1.setFrameStyle(QFrame.HLine | QFrame.Sunken)
        '''

        # 布局
        # open tool
        self.__layout_tool_choose = QHBoxLayout()
        self.__layout_tool_choose.addWidget(self.__ln_open_tool)
        self.__layout_tool_choose.addWidget(self.__pbn_open_tool)
        self.__layout_tool_choose.setSpacing(0)
        self.__layout_tool_choose.setContentsMargins(0, 0, 0, 0)
        
        self.__layout_open_tool = QHBoxLayout()
        self.__layout_open_tool.addWidget(self.__lab_open_tool)
        self.__layout_open_tool.addLayout(self.__layout_tool_choose)
        self.__layout_open_tool.setSpacing(2)

        # window title
        self.__layout_title = QHBoxLayout()
        self.__layout_title.addStretch(5)
        self.__layout_title.addWidget(self.__lab_title)
        self.__layout_title.addStretch(1)
        self.__layout_title.addLayout(self.__layout_open_tool)
        self.__layout_title.setContentsMargins(0, 0, 0, 20)
        self.__lab_title_fram.setLayout(self.__layout_title)

        # search mode
        self.__layout_search_mode = QHBoxLayout()
        self.__layout_search_mode.addWidget(self.__rbn_fuzzy)
        self.__layout_search_mode.addStretch()
        self.__layout_search_mode.addWidget(self.__rbn_precise)
        self.__layout_search_mode.addStretch()
        self.__layout_search_mode.addWidget(self.__rbn_reg)
        self.__layout_search_mode.setContentsMargins(60, 0, 60, 0)
        self.__lab_mode_fram.setLayout(self.__layout_search_mode)

        # search pattern
        self.__layout_search_reg_I = QHBoxLayout()
        self.__layout_search_reg_I.addWidget(self.__rbn_reg_Iyes)
        self.__layout_search_reg_I.addWidget(self.__rbn_reg_Ino)

        self.__layout_pattern = QHBoxLayout()
        self.__layout_pattern.addWidget(self.__ln_file_name)
        self.__layout_pattern.addLayout(self.__layout_search_reg_I)
        self.__layout_pattern.setContentsMargins(0, 0, 0, 0)
        self.__lab_pattern_fram.setLayout(self.__layout_pattern)

        # search path
        self.__layout_choose_path = QHBoxLayout()
        self.__layout_choose_path.addWidget(self.__ln_file_path)
        self.__layout_choose_path.addWidget(self.__pbn_file_path)
        self.__layout_choose_path.setSpacing(0)

        self.__layout_path = QHBoxLayout()
        self.__layout_path.addLayout(self.__layout_choose_path)
        self.__layout_path.addWidget(self.__rbn_search_file)
        self.__layout_path.addWidget(self.__rbn_search_content)
        self.__layout_path.setContentsMargins(0, 0, 0, 0)
        self.__lab_path_fram.setLayout(self.__layout_path)

        # search state
        self.__layout_state = QHBoxLayout()
        self.__layout_state.addWidget(self.__lab_state)
        self.__layout_state.addWidget(self.__pbn_search)
        self.__layout_state.addWidget(self.__pbn_stop)
        self.__layout_state.setContentsMargins(0, 0, 0, 10)
        self.__lab_state_fram.setLayout(self.__layout_state)

        # top layout
        self.__layout_top = QVBoxLayout()
        self.__layout_top.addWidget(self.__lab_title_fram)
        self.__layout_top.addWidget(self.__lab_mode_fram)
        self.__layout_top.addWidget(self.__lab_pattern_fram)
        self.__layout_top.addWidget(self.__lab_path_fram)
        self.__layout_top.addWidget(self.__lab_state_fram)
        self.__layout_top.addWidget(self.__tabView)
        self.__layout_top.setSpacing(10)
        self.__widget_frame.setLayout(self.__layout_top)

        self.__layout_fram = QGridLayout()
        self.__layout_fram.addWidget(self.__widget_frame, 0, 0, 1, 1)
        self.__layout_fram.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.__layout_fram)

        # set object name
        self.__widget_frame.setObjectName('fram')
        self.__lab_title.setObjectName('lab_title')
        self.__ln_open_tool.setObjectName('ln_open_tool')
        self.__lab_mode_fram.setObjectName('mode_fram')
        self.__ln_file_name.setObjectName('ln_pattern')
        self.__ln_file_path.setObjectName('ln_path')
        self.__lab_state.setObjectName('state')
        self.__tabView.setObjectName('tabView')
        self.__browser_result.setObjectName('browser_result')
        self.__browser_error.setObjectName('browser_error')

        self.setStyleSheet(
            '#fram{'
                'border-image: url(Images/bg);'
            '}'
            '#lab_title{'
                'color: white;'
                'font-size: 18pt;'
            '}'
            '#open_tool{'
                'color: black;'
            '}'
            '#mode_fram{'
                # 'border-top: 1px solid rgba(20, 20, 20, 100);'
                # 'border-bottom: 1px solid rgba(20, 20, 20, 100);'
                'background: rgba(0, 0, 0, 40);'
            '}'
            '#ln_open_tool, #ln_path{'
                'border-top-left-radius:    2px;'
                'border-bottom-left-radius: 2px;'
            '}'
            '#ln_pattern{'
                'border-radius: 2px;'
            '}'
            '#state{'
                'background: rgba(0, 0, 0, 40);'
                'border-radius: 2px;'
                'padding: 1px;'
                'color: rgb(240, 240, 240);'
            '}'
            'QTabBar::tab {'
                'border: 0;'
                'width:  90px;'
                'height: 20px;'
                'margin: 0 2px 0 0;'        # top right bottom left
                # 'border-top-left-radius: 5px;'
                # 'border-top-right-radius: 5px;'
                'color: rgb(200, 255, 255;);'
            '}'
            'QTabBar::tab:selected{'
                'background: rgba(25, 0, 0, 40);'
                'border-left: 1px solid rgba(255, 255, 255, 200);'
                'border-top: 1px solid rgba(255, 255, 255, 200);'
                'border-right: 1px solid rgba(255, 255, 255, 200);'
            '}'
            'QTabWidget:pane {'
                'border: 1px solid rgba(255, 255, 255, 200);'
                'background: rgba(0, 0, 0, 80);'
            '}'
            '#browser_result, #browser_error{'
                'background: rgba(0, 0, 0, 0);'
                'border: 0;'
            '}'
            'QLineEdit{'
                'background: rgba(0, 0, 0, 40);'
                'border: 1px solid rgba(220, 220, 220, 200);'
                'color: white;'
                'height: 20px;'
            '}'
            'QPushButton{'
                'background: rgba(0, 0, 0, 100);'
                'border-radius: 5px;'
                'height: 20px;'
                'color: white;'
            '}'
            'QPushButton::hover{'
                'background: rgba(0, 0, 0, 150);'
            '}'
            'QToolButton{'
                'background: rgba(0, 0, 0, 100);'
                'color: white;'
                'border-top-right-radius:    2px;'
                'border-bottom-right-radius: 2px;'
            '}'
            'QToolButton::hover{'
                'background: rgba(0, 0, 0, 150);'
            '}'
            )

        self.__ln_file_name.setFocus()
        self.__pbn_search.setShortcut(Qt.Key_Return)

        # 关联 信号/槽
        self.__pbn_file_path.clicked.connect(self.choose_path)
        self.__pbn_search.clicked.connect(self.pbn_search_clicked)
        self.__pbn_stop.clicked.connect(self.pbn_stop)
        self.__pbn_open_tool.clicked.connect(self.choose_open_tool)
        self.__browser_result.doubleClicked.connect(self.listitem_clicked)

        # 线程间共享数据队列
        queue_size = 10000
        self.__queue_result = Queue(queue_size)
        self.__queue_error = Queue(queue_size)

        # 标记搜索状态
        self.__searching = False

        # 强制结束子线程
        self.__thread_killer = False

    # 重写鼠标按下事件
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.offset = event.globalPos() - self.pos()

    # 重写鼠标移动事件
    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() - self.offset)

    # 检测记事本程序
    def set_open_tool(self):
        if platform.architecture() == ('32bit', 'WindowsPE'):
            possible_dir = ['C:\\Program Files\\Sublime Text 2', 'C:\\Sublime Text 2',
                            'D:\\Program Files\\Sublime Text 2', 'D:\\Sublime Text 2',
                            'E:\\Program Files\\Sublime Text 2', 'E:\\Sublime Text 2',
                            'F:\\Program Files\\Sublime Text 2', 'F:\\Sublime Text 2',
                            'C:\\Program Files\\Notepad++', 'C:\\notepad++',
                            'D:\\Program Files\\Notepad++', 'D:\\notepad++',
                            'E:\\Program Files\\Notepad++', 'E:\\notepad++',
                            'F:\\Program Files\\Notepad++', 'F:\\notepad++',
                            'C:\\Windows\\System32']
        elif platform.architecture() == ('32bit', 'ELF'):
            possible_dir = ['/usr/bin']
        for rootdir in possible_dir:
            for root, dirs, files in walk(rootdir):
                for file in files:
                    if file == 'sublime_text.exe' or file == 'notepad++.exe' or file == 'notepad.exe':
                        self.__ln_open_tool.setText(join(root, file))
                        return
        
    # 搜索文件名
    def search_from_filename(self, filepath, filename, mode='fuzzy_search', I=True):
        # check arguments of searching
        if filepath == '' or not exists(filepath):
            return False
        if mode not in self.__search_mode.values():
            return False
        if filename == '':
            return False

        # count
        count = 0

        # fuzzy mode
        if mode == self.__search_mode['fuzzy']:
            for root, dirs, files in walk(filepath):
                for each_file in files:
                    # kill subThread
                    if self.__thread_killer == True:
                        return
                        
                    if filename in each_file:
                        count += 1
                        self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count)
                        self.__queue_result.put(join(root, each_file))
                        self.__tabView.setTabText(0, '匹配结果(%d)' % count)
        # precise mode
        elif mode == self.__search_mode['precise']:
            for root, dirs, files in walk(filepath):
                for each_file in files:
                    # kill subThread
                    if self.__thread_killer == True:
                        return
                        
                    if filename == splitext(each_file)[0] or filename == each_file:
                        count += 1
                        self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count)
                        self.__queue_result.put(join(root, each_file))
                        self.__tabView.setTabText(0, '匹配结果(%d)' % count)
        # regular expression mode
        elif mode == self.__search_mode['reg']:
            if I:
                pattern = re.compile(r'%s' % filename)
            else:
                pattern = re.compile(r'%s' % filename, re.I)

            for root, dirs, files in walk(filepath):
                for each_file in files:
                    # kill subThread
                    if self.__thread_killer == True:
                        return
                        
                    if re.search(pattern, each_file):
                        count += 1
                        self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count)
                        self.__queue_result.put(join(root, each_file))
                        self.__tabView.setTabText(0, '匹配结果(%d)' % count)
        self.__lab_state.setText('搜索完毕! 共搜到 %d 个文件' % count)     # finished
        self.__searching = False                # set serching flag

    # 搜索文件内容
    def search_from_content(self, path, content, mode='fuzzy_search', I=True):
        if path == '' or not exists(path):
            return False
        if mode not in self.__search_mode.values():
            return False
        if content == '':
            return False
        pass_file_count = 0
        error_number = 0
        current_file = ''
        processing_file = ''
        match_files_count = 0
        if mode == self.__search_mode['reg']:
            if I:
                pattern = re.compile(r'%s' % content)
            else:
                pattern = re.compile(r'%s' % content, re.I)
            for root, dirs, files in walk(path):
                for each_file in [file for file in files if file.endswith('.h') or file.endswith('.cpp') or file.endswith('.cs')]:
                    current_file = join(root, each_file)
                    pass_file_count += 1
                    self.__lab_state.setText('正在搜索......%s' % current_file)
                    try:
                        for line_number, line in enumerate(open(current_file)):
                            # kill subThread
                            if self.__thread_killer == True:
                                return
                            
                            if re.search(pattern, line):
                                if processing_file != current_file:
                                    self.__queue_result.put('\n%s' % current_file)
                                    processing_file = current_file
                                    match_files_count += 1
                                self.__queue_result.put('line %s: %s' % (line_number, line.strip()))
                    except Exception as error:
                        self.__queue_error.put("%s\n(%s)\n" % (error, current_file))
                        pass_file_count -= 1
                        error_number += 1
                        continue
                    self.__tabView.setTabText(0, '匹配结果(%d)' % match_files_count)
        else:
            for root, dirs, files in walk(path):
                for each_file in [file for file in files if file.endswith('.h') or file.endswith('.cpp') or file.endswith('.cs') or file.endswith('.txt') or file.endswith('.py')]:
                    current_file = join(root, each_file)
                    pass_file_count += 1
                    self.__lab_state.setText('正在搜索......%s' % current_file)
                    try:
                        for line_number, line in enumerate(open(current_file)):
                            # kill subThread
                            if self.__thread_killer == True:
                                return
                            
                            if content in line:                                         # 匹配成功
                                if processing_file != current_file:                     # 如果是新文件
                                    self.__queue_result.put('\n%s' % current_file)      # 文件名入队
                                    processing_file = current_file                      # 更新文件标记
                                    match_files_count += 1
                                self.__queue_result.put('line %s: %s' % (line_number, line.strip()))    # 匹配行入队
                    except Exception as error:
                        self.__queue_error.put("%s\n(%s)\n" % (error, current_file))
                        pass_file_count -= 1
                        error_number += 1
                        continue
                    self.__tabView.setTabText(0, '匹配结果(%d)' % match_files_count)
        # self.__queue_result.put()
        self.__lab_state.setText('搜索完毕!成功匹配 %d 个文件,处理 %s 个文件,失败 %s 文件。' % (match_files_count, pass_file_count, error_number))
        self.__searching = False

    # 单击选择路径按钮
    def choose_path(self):
        path = QFileDialog.getExistingDirectory()
        if path != '':
            path = sep.join(path.split('/'))
            self.__ln_file_path.setText(path)

    # 选择打开文件工具
    def choose_open_tool(self):
        path = QFileDialog.getOpenFileName()
        if path[0] != '':
            self.__ln_open_tool.setText(path[0])

    # 显示搜索结果
    def show_search_result(self):
        """将搜索结果加载到界面,供用户查看和操作"""
        line_block = []         # 定义临时列表,成批加载,避免刷新频率过高造成界面闪烁
        block_size = 10         # 一次性加载的个数
        while self.__searching or self.__queue_result.qsize():
            # kill subThread
            if self.__thread_killer == True:
                return
            
            # if self.__searching or self.__queue_result.qsize() >= block_size:     // 永远记住这个 bug (生产者-消费者 问题)
            if self.__queue_result.qsize() >= block_size:                           # 如果队列中不小于 block_size 个项
                for i in range(block_size):                                             # 取出 block_size 个项
                    line_block.append(self.__queue_result.get())                        # 出队操作
                self.__browser_result.addItems(line_block)                                     # 一次性添加 block_size 个条目
                line_block.clear()                                                      # 清空临时列表
            elif self.__queue_result.qsize() >= 0:                                                                   # 如果队列中小于 block_size 各项
                item = self.__queue_result.get()                                        # 出队一项
                self.__browser_result.addItem(QListWidgetItem(item))                           # 加载到界面
            #self.__browser.setCurrentRow(self.__browser.count()-1)                  # 设置列表中最后一项为当前项,使列表不停滚动
            sleep(0.05)                                                              # 给界面事件循环腾出时间,避免界面冻结
        #self.__pbn_search.setEnabled(True)

    # 显示出错结果
    def show_error_result(self):
        """打印略过的文件和出错原因,多为 I/O Error"""
        count = 0
        while self.__queue_error.qsize() or self.__searching:
            # kill subThread
            if self.__thread_killer == True:
                return
            
            if self.__queue_error.qsize() <= 0:
               continue
            self.__browser_error.append(self.__queue_error.get())
            count += 1
            self.__tabView.setTabText(1, '错误结果(%d)' % count)

    # 单击检索按钮
    def pbn_search_clicked(self):
        """To search allow the arguments from UI"""
        # 获取 UI 数据
        file_path = self.__ln_file_path.text()
        file_name = self.__ln_file_name.text()

        # 检查参数
        if file_path == '':
            QMessageBox(QMessageBox.Warning, '缺少参数!', '请输入搜索路径!', QMessageBox.Ok, self).exec_()
            return
        if file_name == '':
            QMessageBox(QMessageBox.Warning, '缺少参数!', '请输入匹配条件!', QMessageBox.Ok, self).exec_()
            return

        # 判断搜索模式
        mode = self.__search_mode['fuzzy']
        if self.__rbn_reg.isChecked():
            mode = self.__search_mode['reg']
        elif self.__rbn_fuzzy.isChecked():
            mode = self.__search_mode['fuzzy']
        elif self.__rbn_precise.isChecked():
            mode = self.__search_mode['precise']

        # 大小写敏感标记
        I = True
        if self.__rbn_reg_Ino.isChecked():
            I = False

        self.__browser_result.clear()
        self.__browser_error.clear()
        self.__tabView.setTabText(0, '匹配结果(0)')
        self.__tabView.setTabText(1, '错误结果(0)')
        self.__searching = True

        # 开启子线程,后台深度遍历
        self.__thread_killer = False
        if self.__rbn_search_file.isChecked():
            self.__lab_state.setText('正在搜索......已搜索到 0 个文件')
            self.__sub_thread_search = Thread(target=self.search_from_filename, args=(file_path, file_name, mode, I))
            self.__sub_thread_search.start()
        else:
            self.__lab_state.setText('正在搜索......')
            self.__sub_thread_search = Thread(target=self.search_from_content, args=(file_path, file_name, mode, I))
            self.__sub_thread_search.start()

        # 开启子线程,显示搜索结果
        self.__sub_thread_show_result = Thread(target=self.show_search_result)
        self.__sub_thread_show_result.start()

        # 开启子线程,显示错误结果
        self.__sub_thread_show_error = Thread(target=self.show_error_result)
        self.__sub_thread_show_error.start()

        # self.__pbn_search_file.setEnable(False)
        # self.__pbn_search_content.setEnable(False)

    # 单击停止按钮
    def pbn_stop(self):
        if not self.__searching:
            return
        self.__thread_killer = True
        while self.__queue_result.qsize():
            self.__queue_result.get()
        while self.__queue_error.qsize():
            self.__queue_error.get()
        self.__lab_state.setText('搜索已停止!')
        self.__searching = False

    # 双击搜索结果
    def listitem_clicked(self):
        """Double click to open the file from search result"""
        file_path = self.__browser_result.currentItem().text().strip()
        read_tool = self.__ln_open_tool.text()
        if not exists(file_path):
            QMessageBox.warning(self, '错误!', '请双击文件名\n%s 不是文件或打不开!' % file_path, QMessageBox.Ok)
            return
        if splitext(file_path)[1] in ['.jpg', '.png', '.jpeg', '.gif']:
            file_path = r'%s'.replace(' ', r'\ ') % file_path
            system('%s' % file_path)
        else:
            system('"%s" %s' % (read_tool, file_path))
Пример #35
0
class CityListDlg(QDialog):
    citieslist_signal = pyqtSignal([list])
    citiesdict_signal = pyqtSignal([dict])

    def __init__(self,
                 citylist,
                 accurate_url,
                 appid,
                 trans_cities_dict,
                 parent=None):
        super(CityListDlg, self).__init__(parent)
        self.settings = QSettings()
        self.citylist = citylist
        self.trans_cities_dict = trans_cities_dict
        self.accurate_url = accurate_url
        self.appid = appid
        self.listWidget = QListWidget()
        self.listWidget.itemDoubleClicked.connect(self.translate)
        cities_list = []
        for i in self.citylist:
            cities_list.append(self.trans_cities_dict.get(i, i))
        self.listWidget.addItems(cities_list)
        buttonLayout = QVBoxLayout()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)
        layoutT = QVBoxLayout()
        layout = QHBoxLayout()
        layout.addWidget(self.listWidget)
        layout.addLayout(buttonLayout)
        for text, slot in ((self.tr("&Add..."),
                            self.add), (self.tr("&Remove..."), self.remove),
                           (self.tr("&Up"), self.up),
                           (self.tr("&Down"), self.down), (self.tr("De&fault"),
                                                           self.default),
                           (self.tr("&Sort"), self.listWidget.sortItems)):
            button = QPushButton(text)
            buttonLayout.addWidget(button)
            button.clicked.connect(slot)
        self.translate_button = QPushButton(
            QCoreApplication.translate('Button', '&Translate',
                                       'Edit cities name'))
        buttonLayout.addWidget(self.translate_button)
        self.translate_button.clicked.connect(self.translate)
        buttonLayout.addWidget(self.buttonBox)
        self.status = QLabel()
        layoutT.addLayout(layout)
        layoutT.addWidget(self.status)
        self.setLayout(layoutT)
        self.setWindowTitle(
            QCoreApplication.translate('Window title', 'Cities',
                                       'Cities list dialogue'))
        self.checklength()

    def add(self):
        self.status.setText('')
        lista = []
        newitem = ''
        self.citytoadd = ''
        self.countrytoadd = ''
        self._idtoadd = ''
        dialog = searchcity.SearchCity(self.accurate_url, self.appid, self)
        dialog.id_signal.connect(self.addcity)
        dialog.city_signal.connect(self.addcity)
        dialog.country_signal.connect(self.addcity)
        if dialog.exec_() == 1:
            newitem = (self.citytoadd + '_' + self.countrytoadd + '_' +
                       self._idtoadd)
            for row in range(self.listWidget.count()):
                lista.append(self.listWidget.item(row).text())
            if newitem in lista:
                self.status.setText(
                    QCoreApplication.translate(
                        'Status bar message',
                        'The city already exists in the list',
                        'Cities list dialogue'))
                return
            else:
                self.listWidget.addItem(newitem)
                self.checklength()
                self.status.setText('ℹ ' + QCoreApplication.translate(
                    'Status bar message',
                    'Toggle cities with mouse scroll on the weather window',
                    'Cities list dialogue'))

    def addcity(self, what):
        self.status.setText('')
        if what[0] == 'ID':
            self._idtoadd = what[1]
        elif what[0] == 'City':
            self.citytoadd = what[1]
        elif what[0] == 'Country':
            self.countrytoadd = what[1]

    def remove(self):
        self.status.setText('')
        if self.listWidget.count() == 1:
            self.status.setText(
                QCoreApplication.translate(
                    'Message when trying to remove the'
                    'last and unique city in the list',
                    'This is the default city!', 'Cities list dialogue'))
            return
        row = self.listWidget.currentRow()
        item = self.listWidget.item(row)
        if item is None:
            return
        message = self.tr('The city "{0}" has been removed').format(
            self.listWidget.item(row).text())
        item = self.listWidget.takeItem(row)
        del item
        self.status.setText(message)

    def up(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row >= 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row - 1, item)
            self.listWidget.setCurrentItem(item)

    def down(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row < self.listWidget.count() - 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row + 1, item)
            self.listWidget.setCurrentItem(item)

    def default(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row >= 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(0, item)
            self.listWidget.setCurrentItem(item)

    def checklength(self):
        if self.listWidget.count() == 1:
            # After adding the first city the entry is not activated
            self.listWidget.setCurrentRow(0)
        if self.listWidget.count() > 0:
            self.translate_button.setEnabled(True)
            self.listWidget.setMinimumWidth(
                self.listWidget.sizeHintForColumn(0))
        else:
            self.translate_button.setEnabled(False)

    def translate(self):
        city = self.listWidget.currentItem().text()
        dialog = citytranslate.CityTranslate(city, self.trans_cities_dict,
                                             self)
        dialog.city_signal.connect(self.current_translation)
        if dialog.exec_() == 1:
            row = self.listWidget.currentRow()
            item = self.listWidget.takeItem(row)
            del item
            self.listWidget.insertItem(row, self.current_translated_city)
            self.listWidget.setCurrentRow(row)

    def current_translation(self, translated_city):
        for city, translated in translated_city.items():
            if translated == '':
                translated = city
            self.trans_cities_dict[city] = translated
            self.current_translated_city = translated

    def accept(self):
        listtosend = []
        for row in range(self.listWidget.count()):
            city = self.find_city_key(self.listWidget.item(row).text())
            listtosend.append(city)
        if self.listWidget.count() == 0:
            return
        self.citieslist_signal[list].emit(listtosend)
        self.citiesdict_signal[dict].emit(self.trans_cities_dict)
        QDialog.accept(self)

    def find_city_key(self, city):
        for key, value in self.trans_cities_dict.items():
            if value == city:
                return key
        return city
Пример #36
0
class MigrationWidget(QDialog):
    """2to3 Migration Assistance Widget Class"""
    
    dockedWidget = pyqtSignal("QObject*")
    undockedWidget = pyqtSignal()
    changeTitle = pyqtSignal(str)

    def __init__(self, parent=None):
        super(MigrationWidget, self).__init__(parent, Qt.WindowStaysOnTopHint)
        self._migration, vbox, hbox = {}, QVBoxLayout(self), QHBoxLayout()
        lbl_title = QLabel(translations.TR_CURRENT_CODE)
        lbl_suggestion = QLabel(translations.TR_SUGGESTED_CHANGES)
        self.current_list, self.suggestion = QListWidget(), QPlainTextEdit()
        self.suggestion.setReadOnly(True)
        self.btn_apply = QPushButton(translations.TR_APPLY_CHANGES + " !")
        self.suggestion.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !")
        self.btn_apply.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !")
        # pack up all widgets
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox.addWidget(self.btn_apply)
        vbox.addWidget(lbl_title)
        vbox.addWidget(self.current_list)
        vbox.addWidget(lbl_suggestion)
        vbox.addWidget(self.suggestion)
        vbox.addLayout(hbox)
        # connections
        self.current_list.itemClicked['QListWidgetItem*'].connect(self.load_suggestion)
        self.btn_apply.clicked['bool'].connect(self.apply_changes)
        # registers
        IDE.register_service('tab_migration', self)
        ExplorerContainer.register_tab(translations.TR_TAB_MIGRATION, self)

    def install_tab(self):
        """Install the Tab on the IDE."""
        ide = IDE.getInstance()
        ide.goingDown.connect(self.close)

    def apply_changes(self):
        """Apply the suggested changes on the Python code."""
        lineno = int(self.current_list.currentItem().data(Qt.UserRole))
        lines = self._migration[lineno][0].split('\n')
        remove, code = -1, ""
        for line in lines:
            if line.startswith('-'):
                remove += 1  # line to remove
            elif line.startswith('+'):
                code += '{line_to_add}\n'.format(line_to_add=line[1:])
        # get and apply changes on editor
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            block_start = editorWidget.document().findBlockByLineNumber(lineno)
            block_end = editorWidget.document().findBlockByLineNumber(lineno +
                                                                      remove)
            cursor = editorWidget.textCursor()
            cursor.setPosition(block_start.position())
            cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor)
            cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
            cursor.insertText(code[:-1])

    def load_suggestion(self, item):
        """Take an argument item and load the suggestion."""
        lineno, code = int(item.data(Qt.UserRole)), ""
        lines = self._migration[lineno][0].split('\n')
        for line in lines:
            if line.startswith('+'):
                code += '{line_to_add}\n'.format(line_to_add=line[1:])
        self.suggestion.setPlainText(code)
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            if editorWidget:
                editorWidget.jump_to_line(lineno)
                editorWidget.setFocus()

    def refresh_lists(self, migration):
        """Refresh the list of code suggestions."""
        self._migration, base_lineno = migration, -1
        self.current_list.clear()
        for lineno in sorted(migration.keys()):
            linenostr = 'L{line_number}\n'.format(line_number=str(lineno + 1))
            data = migration[lineno]
            lines = data[0].split('\n')
            if base_lineno == data[1]:
                continue
            base_lineno = data[1]
            message = ''
            for line in lines:
                if line.startswith('-'):
                    message += '{line_to_load}\n'.format(line_to_load=line)
            item = QListWidgetItem(linenostr + message)
            item.setToolTip(linenostr + message)
            item.setData(Qt.UserRole, lineno)
            self.current_list.addItem(item)

    def clear(self):
        """Clear the widget."""
        self.current_list.clear()
        self.suggestion.clear()

    def reject(self):
        """Reject"""
        if self.parent() is None:
            self.dockedWidget.emit(self)

    def closeEvent(self, event):
        """Close"""
        self.dockedWidget.emit(self)
        event.ignore()
Пример #37
0
class ClippingsPanel(SettingsPanel):
    def __init__(self, parent=None):
        super(ClippingsPanel, self).__init__(parent)
        self.setWindowTitle(tr("Clippings Manager"))

        coreColumn = custom_widgets.Column(self)
        self.layout().addWidget(coreColumn)
        
        # Title
        self.title = QLabel(tr("<b>Clippings</b>"), self)
        coreColumn.addWidget(self.title)
        
        howToUse = QLabel(tr("To use Clippings, Shift+right click a textbox on the page."), self)
        coreColumn.addWidget(howToUse)

        row1 = custom_widgets.Row(self)
        coreColumn.addWidget(row1)

        column1 = custom_widgets.Column(self)
        column2 = custom_widgets.Column(self)
        row1.addWidget(column1)
        row1.addWidget(column2)

        # Clipping list.
        self.clippingList = QListWidget(self)
        self.clippingList.currentTextChanged.connect(self.loadClipping)
        column1.addWidget(self.clippingList)

        self.removeClippingButton = QPushButton(tr("Remove"))
        self.removeClippingButton.clicked.connect(lambda: self.removeClipping(True))
        column1.addWidget(self.removeClippingButton)

        self.removeAction = QAction(self)
        self.removeAction.setShortcut("Del")
        self.removeAction.triggered.connect(self.removeClipping)
        self.addAction(self.removeAction)

        clippingNameRow = custom_widgets.LineEditRow(tr("Name:"), self)
        self.nameEntry = clippingNameRow.lineEdit
        self.nameEntry.returnPressed.connect(self.addClipping)
        column2.addWidget(clippingNameRow)

        self.addClippingButton = QPushButton(tr("Add"))
        self.addClippingButton.clicked.connect(self.addClipping)
        clippingNameRow.layout().addWidget(self.addClippingButton)

        self.clippingEntry = QTextEdit(self)
        column2.addWidget(self.clippingEntry)

    def show(self):
        self.setVisible(True)
        self.loadSettings()

    def loadSettings(self):
        data.load_clippings()
        self.clippingList.clear()
        for item in sorted(list(data.clippings.keys())):
            self.clippingList.addItem(item)

    def saveSettings(self):
        data.save_clippings()

    def removeClipping(self, forceFocus=False):
        if self.clippingList.hasFocus() or forceFocus:
            name = self.clippingList.currentItem().text()
            del data.clippings[name]
            self.clippingList.takeItem(self.clippingList.row(self.clippingList.currentItem()))
            self.saveSettings()

    def loadClipping(self, text):
        try:
            self.nameEntry.setText(text)
            self.clippingEntry.setPlainText(data.clippings[text])
        except:
            pass

    def addClipping(self):
        data.clippings[self.nameEntry.text()] = self.clippingEntry.toPlainText()
        self.saveSettings()
        self.loadSettings()
Пример #38
0
class App(QMainWindow):
    @pyqtSlot()
    def __init__(self):
        super().__init__()
        self.title = 'Google Drive Connection'
        self.left = 1000
        self.top = 1000
        self.width = 1000
        self.height = 5000
        self.initUI()

    @pyqtSlot()
    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        #self.setStyleSheet("""QMainWindow{ background: yellow; }""")

        # Create textbox
        self.textbox = QLineEdit(self)
        self.textbox.move(20, 20)
        self.textbox.resize(280, 40)

        # Create a button in the window
        self.button = QPushButton('Add URL', self)
        self.button.move(20, 80)

        self.listwidget = QListWidget(self)
        self.listwidget.move(200, 200)
        self.listwidget.resize(1000, 1000)
        self.setStyleSheet("""QListWidget{ background: green; }""")

        #goolle coneect

        self.btn = QPushButton('Connect To Google Drive', self)
        self.btn.resize(289, 49)
        self.btn.move(1000, 50)

        self.button3 = QPushButton('Download', self)
        self.button3.resize(289, 49)
        self.button3.move(1500, 50)

        self.button4 = QPushButton('Upload', self)
        self.button4.resize(289, 49)
        self.button4.move(2000, 50)

        # connect button to function on_click
        self.button.clicked.connect(self.addUrl)
        self.listwidget.clicked.connect(self.removeURL)
        self.btn.clicked.connect(self.auth)
        # self.button3.clicked.connect(self.downloadFile)
        # self.button4.clicked.connect(self.uploadFile)

    def addUrl(self):
        textboxValue = self.textbox.text()
        subString = textboxValue[0:23]
        print(subString)

        if subString == "https://www.youtube.com":
            self.listwidget.addItem(textboxValue)
        else:
            QMessageBox.question(self, 'Error',
                                 "The Url you entered is not a valid ",
                                 QMessageBox.Ok, QMessageBox.Ok)

    def removeURL(self):
        index = self.listwidget.row(self.listwidget.currentItem())
        self.listwidget.takeItem(index)

    # @pyqtSlot()
    # def downloadFile(self):
    #
    #     # Call the Drive v3 API
    #     creds = None
    #     if os.path.exists('token.pickle'):
    #         with open('token.pickle', 'rb') as token:
    #             creds = pickle.load(token)
    #     else:
    #         QMessageBox.question(self, 'Error', "Connect to google drive first ", QMessageBox.Ok,
    #                              QMessageBox.Ok)
    #         return
    #
    #     service = build('drive', 'v3', credentials=creds)
    #     results = service.files().list(
    #         pageSize=10, fields="nextPageToken, files(id, name)").execute()
    #     items = results.get('files', [])
    #
    #     if not items:
    #         print('No files found.')
    #     else:
    #         print('Files:')
    #         for item in items:
    #             print(u'{0} ({1})'.format(item['name'], item['id']))

    # @pyqtSlot()
    # def uploadFile(self):
    #     creds = None
    #     if os.path.exists('token.pickle'):
    #         with open('token.pickle', 'rb') as token:
    #             creds = pickle.load(token)
    #     else:
    #         QMessageBox.question(self, 'Error', "Connect to google drive first ", QMessageBox.Ok,
    #                              QMessageBox.Ok)
    #         return
    #
    #     service = build('drive', 'v3', credentials=creds)
    #
    #     file_metadata = {'name': 'google.jpg'}
    #     media = service('google.jpg',
    #                             mimetype='image/jpeg')
    #     file = service.files().create(body=file_metadata,
    #                                         media_body=media,
    #                                         fields='id').execute()
    #     print('File ID: %s' % file.get('id'))

    @pyqtSlot()
    def auth(self):
        """Shows basic usage of the Drive v3 API.
        Prints the names and ids of the first 10 files the user has access to.
        """
        if os.path.exists('token.pickle'):
            self.on_click()
        else:
            creds = None
            # The file token.pickle stores the user's access and refresh tokens, and is
            # created automatically when the authorization flow completes for the first
            # time.
            if os.path.exists('token.pickle'):
                with open('token.pickle', 'rb') as token:
                    creds = pickle.load(token)
            # If there are no (valid) credentials available, let the user log in.
            if not creds or not creds.valid:
                if creds and creds.expired and creds.refresh_token:
                    creds.refresh(Request())
                else:
                    flow = InstalledAppFlow.from_client_secrets_file(
                        'credentials.json', SCOPES)
                    creds = flow.run_local_server(port=0)

                # Save the credentials for the next run
                with open('token.pickle', 'wb') as token:
                    pickle.dump(creds, token)

            # service = build('drive', 'v3', credentials=creds)
            self.AuthMessage()

    @pyqtSlot()
    def on_click(self):
        QMessageBox.question(self, 'Message', "You are already connected",
                             QMessageBox.Ok, QMessageBox.Ok)

    @pyqtSlot()
    def AuthMessage(self):
        QMessageBox.question(self, 'Message',
                             "The connection was successfully done",
                             QMessageBox.Ok, QMessageBox.Ok)

    @pyqtSlot()
    def of_click(self):
        QMessageBox.question(self, 'Message - pythonspot.com',
                             "You typed: " + textboxValue, QMessageBox.Ok,
                             QMessageBox.Ok)
        self.textbox.setText("")
Пример #39
0
class MigrationWidget(QDialog):
    """2to3 Migration Assistance Widget Class"""
    
    dockWidget = pyqtSignal("QObject*")
    undockWidget = pyqtSignal()
    changeTitle = pyqtSignal(str)

    def __init__(self, parent=None):
        super(MigrationWidget, self).__init__(parent, Qt.WindowStaysOnTopHint)
        self._migration, vbox, hbox = {}, QVBoxLayout(self), QHBoxLayout()
        lbl_title = QLabel(translations.TR_CURRENT_CODE)
        lbl_suggestion = QLabel(translations.TR_SUGGESTED_CHANGES)
        self.current_list, self.suggestion = QListWidget(), QPlainTextEdit()
        self.suggestion.setReadOnly(True)
        self.btn_apply = QPushButton(translations.TR_APPLY_CHANGES + " !")
        self.suggestion.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !")
        self.btn_apply.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !")
        # pack up all widgets
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox.addWidget(self.btn_apply)
        vbox.addWidget(lbl_title)
        vbox.addWidget(self.current_list)
        vbox.addWidget(lbl_suggestion)
        vbox.addWidget(self.suggestion)
        vbox.addLayout(hbox)
        # connections
        self.current_list.itemClicked['QListWidgetItem*'].connect(self.load_suggestion)
        self.btn_apply.clicked['bool'].connect(self.apply_changes)
        # registers
        IDE.register_service('tab_migration', self)
        ExplorerContainer.register_tab(translations.TR_TAB_MIGRATION, self)

    def install_tab(self):
        """Install the Tab on the IDE."""
        ide = IDE.getInstance()
        ide.goingDown.connect(self.close)

    def apply_changes(self):
        """Apply the suggested changes on the Python code."""
        lineno = int(self.current_list.currentItem().data(Qt.UserRole))
        lines = self._migration[lineno][0].split('\n')
        remove, code = -1, ""
        for line in lines:
            if line.startswith('-'):
                remove += 1  # line to remove
            elif line.startswith('+'):
                code += '{line_to_add}\n'.format(line_to_add=line[1:])
        # get and apply changes on editor
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            block_start = editorWidget.document().findBlockByLineNumber(lineno)
            block_end = editorWidget.document().findBlockByLineNumber(lineno +
                                                                      remove)
            cursor = editorWidget.textCursor()
            cursor.setPosition(block_start.position())
            cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor)
            cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)
            cursor.insertText(code[:-1])

    def load_suggestion(self, item):
        """Take an argument item and load the suggestion."""
        lineno, code = int(item.data(Qt.UserRole)), ""
        lines = self._migration[lineno][0].split('\n')
        for line in lines:
            if line.startswith('+'):
                code += '{line_to_add}\n'.format(line_to_add=line[1:])
        self.suggestion.setPlainText(code)
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            if editorWidget:
                editorWidget.jump_to_line(lineno)
                editorWidget.setFocus()

    def refresh_lists(self, migration):
        """Refresh the list of code suggestions."""
        self._migration, base_lineno = migration, -1
        self.current_list.clear()
        for lineno in sorted(migration.keys()):
            linenostr = 'L{line_number}\n'.format(line_number=str(lineno + 1))
            data = migration[lineno]
            lines = data[0].split('\n')
            if base_lineno == data[1]:
                continue
            base_lineno = data[1]
            message = ''
            for line in lines:
                if line.startswith('-'):
                    message += '{line_to_load}\n'.format(line_to_load=line)
            item = QListWidgetItem(linenostr + message)
            item.setToolTip(linenostr + message)
            item.setData(Qt.UserRole, lineno)
            self.current_list.addItem(item)

    def clear(self):
        """Clear the widget."""
        self.current_list.clear()
        self.suggestion.clear()

    def reject(self):
        """Reject"""
        if self.parent() is None:
            self.dockWidget.emit(self)

    def closeEvent(self, event):
        """Close"""
        self.dockWidget.emit(self)
        event.ignore()
Пример #40
0
class CustomTextEditor(QWidget):
    def __init__(self, parent=None, txtInput=None):
        super(CustomTextEditor, self).__init__(parent)
        # met en place la coloration syntaxique
        if txtInput is None:
            self.txtInput = QTextEdit()
        else:
            self.txtInput = txtInput
        self.txtOutput = QTextEdit()
        # Search/Replace buttons :
        self.btnSearch = QPushButton('Search')
        self.btnReplaceAll = QPushButton('Replace all')
        self.btnQuickSearchImages = QPushButton('I')
        self.btnQuickSearchLinks = QPushButton('L')
        # self.btnClear = QPushButton('Clear')
        self.chkCaseSensitivity = QCheckBox('Case sensitive')
        # Line edit to search and replace :
        self.formSearch = QLineEdit()
        self.formReplace = QLineEdit()
        # Labels :
        self.labelCount = QLabel()
        self.labNotif = QLabel('')
        # List widget :
        self.listFound = QListWidget()
        # --------------------------------------
        self.mainLayout = QGridLayout()
        self.splitVLayout = QSplitter(QtCore.Qt.Vertical)
        self.layoutCommand = QGridLayout()
        # Syntax highlighting :
        self.colorSyntaxHtml = ColorSyntaxHTML(self.txtInput.document())
        self.hotkey = {}
        self.bind_key(
            'actionSearch', 'Ctrl+F',
            lambda: self.on_ctrl_f_pushed(self.formSearch, self.txtInput))
        self.bind_key('actionSearchOnReturnPress',
                      'Return',
                      lambda: self.search_and_replace(),
                      widget=self.formSearch)
        self.bind_key('actionSearchOnEnterPress',
                      'Enter',
                      lambda: self.search_and_replace(),
                      widget=self.formSearch)
        self.config()

    def set_size_policy(self,
                        widget,
                        hpolicy=QSizePolicy.Expanding,
                        vpolicy=QSizePolicy.Expanding):
        policy = QSizePolicy(hpolicy, vpolicy)
        policy.setHorizontalStretch(0)
        policy.setVerticalStretch(0)
        widget.setSizePolicy(policy)

    def config(self):
        # ---------- SET STYLES ----------------------------------------
        self.setAutoFillBackground(True)
        pal = self.palette()
        pal.setColor(self.backgroundRole(), QColor('#7FD1B9'))
        self.setPalette(pal)
        self.setStyleSheet('''QTextEdit {
			margin-right: 5px;
			background: #ffffff; color: black;
			border-radius: 4px; border: 0px solid #CBC9D2;
			selection-background-color: #ffa500;
		}
		QTextEdit:hover {
			background: #ffffff;
		}
		QListWidget {
			background: #ffffff; color: black;
		}
		QCheckBox, QLabel {
			color: #000000;
			font-size: 14px;
		}
		QPushButton {
			background: #333333; color: #ffffff;
			border-width: 2px; border-radius: 4px;
			width: 100px;
			padding: 4px;
			font-size: 13px;
		}
		QSplitter {
			background: transparent;
		}
		QPushButton:hover {
			border: 2px solid #FFFFFF;
		}
		''')
        style_btn_mini = ''' width: 20px; height: 20px; 
		border-radius: 8px;
		background-color: {bgcolor}; color: {color};		
		'''
        self.btnQuickSearchImages.setStyleSheet(
            style_btn_mini.format(bgcolor='#1e90ff', color='#ffffff'))
        self.btnQuickSearchLinks.setStyleSheet(
            style_btn_mini.format(bgcolor='#ff4500', color='#ffffff'))
        # ----------------------------------------------------------------
        self.setLayout(self.mainLayout)
        self.layoutCommand.addWidget(self.btnSearch, 0, 0)
        self.layoutCommand.addWidget(self.btnQuickSearchImages, 0, 1)
        self.layoutCommand.addWidget(self.btnReplaceAll, 1, 0)
        self.layoutCommand.addWidget(self.btnQuickSearchLinks, 1, 1)
        self.layoutCommand.addWidget(self.formSearch, 0, 2)
        self.layoutCommand.addWidget(self.formReplace, 1, 2)
        # self.layoutCommand.addWidget(self.btnClear, 0, 2)
        self.layoutCommand.addWidget(self.labelCount, 0, 3)
        self.layoutCommand.addWidget(self.labNotif, 1, 4)
        self.layoutCommand.addWidget(self.chkCaseSensitivity, 1, 3)
        self.mainLayout.addLayout(self.layoutCommand, 0, 0)
        self.splitVLayout.addWidget(self.txtInput)
        self.splitVLayout.addWidget(self.listFound)
        self.mainLayout.addWidget(self.splitVLayout, 2, 0, 1, 3)
        self.splitVLayout.setHandleWidth(6)
        self.splitVLayout.setSizes([200, 40])
        # TEXT WIDGET CONFIG :
        # Set fonts :
        font = QFont()
        font.setFamily("DejaVu Sans Mono")
        font.setStyleHint(QFont.Courier)
        font.setPointSize(10)
        self.txtInput.setFont(font)
        self.txtInput.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
        # ---------- SIGNAL CONNECTION ----------------------------------------
        self.btnSearch.clicked.connect(lambda: self.search_and_replace())
        # self.btnClear.clicked.connect(lambda: self.wash(self.txtInput))
        self.btnReplaceAll.clicked.connect(
            lambda: self.search_and_replace(replace=True))
        self.listFound.itemDoubleClicked.connect(
            lambda: self.find_on_text(self.listFound.currentItem().text()))
        self.btnQuickSearchImages.clicked.connect(
            lambda: self.search_and_replace(pattern='src'))
        self.btnQuickSearchLinks.clicked.connect(
            lambda: self.search_and_replace(pattern='href'))
        # ---------- SET POLICY ----------------------------------------
        self.set_size_policy(self.formSearch, QSizePolicy.Expanding,
                             QSizePolicy.Maximum)
        self.set_size_policy(self.formReplace, QSizePolicy.Expanding,
                             QSizePolicy.Maximum)
        self.set_size_policy(self.btnSearch, QSizePolicy.Maximum,
                             QSizePolicy.Maximum)
        self.set_size_policy(self.btnReplaceAll, QSizePolicy.Maximum,
                             QSizePolicy.Maximum)
        self.set_size_policy(self.btnQuickSearchImages, QSizePolicy.Maximum,
                             QSizePolicy.Maximum)
        self.set_size_policy(self.btnQuickSearchLinks, QSizePolicy.Maximum,
                             QSizePolicy.Maximum)
        self.set_size_policy(self.txtInput, QSizePolicy.Expanding,
                             QSizePolicy.Expanding)
        # Set listWidget cursor shape :
        self.listFound.setCursor(QtCore.Qt.IBeamCursor)

    def wash(self, text_edit):
        text_edit.clear()
        self.labelCount.setText('')
        self.listFound.clear()

    def on_ctrl_f_pushed(self, source_form, text_edit):
        text = self.current_selection(text_edit)
        source_form.clear()
        source_form.setText(text)

    def current_selection(self, text_edit):
        cursor = text_edit.textCursor()
        return cursor.selectedText()

    def bind_key(self, key_name, key_combo, func, widget=None):
        if not widget:
            widget = self
        self.hotkey[key_name] = QtWidgets.QShortcut(QKeySequence(key_combo),
                                                    widget)
        self.hotkey[key_name].activated.connect(func)

    def search_and_replace(self, replace=False, pattern=None):
        print('Search and replace function activated')
        to_search = self.formSearch.text()
        if pattern:
            to_search = pattern
        replace_with = self.formReplace.text()
        text = self.txtInput.toPlainText()
        pattern = re.escape(to_search)
        if to_search == '':
            return
        # REPLACE BLOCK ----------------------------------------------------------
        if replace:
            print('Replace now :')
            self.txtInput.clear()
            if self.chkCaseSensitivity.isChecked():
                text = re.sub(pattern, replace_with, text)
            else:
                text = re.sub(pattern, replace_with, text, flags=re.IGNORECASE)
            self.txtInput.insertPlainText(text)
            print('Updating label value')
            self.update_label(self.labNotif, '')
        # SEARCH ONLY ------------------------------------------------------------
        else:
            print('Search only :')
            if self.chkCaseSensitivity.isChecked(
            ):  # Check if case sensitive checkbox is checked
                matches = re.findall(pattern + r'.*', text)
            else:
                matches = re.findall(pattern + r'.*', text, re.IGNORECASE)
            if matches:
                # If there is any item matches :
                self.listFound.clear()  # Clear the found listWidget
                [self.listFound.addItem(match) for match in matches]
                self.labelCount.setText(
                    '<span style="color: #64ca77;">%s items found</span>' %
                    len(matches))
                print('Updating label value')
                self.update_label(self.labNotif, '')
            else:
                # If no matches :
                self.labelCount.setText(
                    '<span style="color: red;">No item found</span>')
                self.listFound.clear()
                self.listFound.addItem('No item found...')
                return None

    def detect_bads(self):
        fr = re.findall(r'\.fr', self.txtInput.toPlainText())
        com = re.findall(r'\.com', self.txtInput.toPlainText())
        pixel = re.findall(r'<img.*?width="1".*?>{1}|<img.*?height="1".*?>{1}',
                           self.txtInput.toPlainText())
        bads = [x for x in (fr + com + pixel) if x is not None]
        print('Bads :', bads)

    def find_on_text(self, pattern):
        print('Find on text')
        # self.txtInput.moveCursor(QTextCursor.Start)
        found = self.txtInput.find(pattern)
        if not found:
            found = self.txtInput.find(self.listFound.currentItem().text(),
                                       QTextDocument.FindBackward)
        # self.txtInput.moveCursor(QTextCursor.Start)

    def update_label(self, label, text=''):
        if isinstance(label, QLabel):
            old_color = label.palette().color(QPalette.Background).name()
            print(old_color)
            pick = '#%s' % ''.join(
                [random.choice(hexdigits) for i in range(6)])
            while pick.lower() == old_color.lower():
                pick = '#%s' % ''.join(
                    [random.choice(hexdigits) for i in range(6)])
            label.clear()
            label.setText(text)
            label.setFixedWidth(15)
            label.setFixedHeight(15)
            label.setStyleSheet('background: %s' % pick)
Пример #41
0
class ProjectManagerPane(QWidget):
    """UI to select a project to start.

    Users are presented a list of existing projects or the available templates
    to start a new project.

    """

    def __init__(self, main_window, projlist, parent=None):
        super().__init__(parent)
        self.layout = QHBoxLayout()
        self.setLayout(self.layout)

        self.tabs = QTabWidget()
        self.tabs.setObjectName('projectchoosertabs')

        self.layout.addWidget(self.tabs)

        self.projects = QListWidget()
        self.projects.currentItemChanged.connect(self.selected_project)

        self.templates = QListWidget()
        self.templates.currentItemChanged.connect(self.selected_template)

        if any(projlist):
            self.tabs.addTab(self.projects, "Existing Project")
        self.tabs.addTab(self.templates, "New Project")
        self.tabs.currentChanged.connect(self.tab_changed)

        self.detailspane = QVBoxLayout()
        self.layout.addLayout(self.detailspane)
        self.details = QLabel(DEFAULT_DETAILS)

        self.go = QPushButton("Go")
        self.go.setDisabled(True)
        self.go.clicked.connect(self.perform_action)
        self.detailspane.addWidget(self.details)
        self.detailspane.addWidget(self.go)

        self.action = None
        self.main_window = main_window
        self.projlist = projlist
        self.update_choices()

    def update_choices(self):
        for p in PROJECTS:
            self.templates.addItem(p.NAME)

        for name in self.projlist:
            self.projects.addItem(name)

    def tab_changed(self, index):
        """Called when the active tab is changed."""
        if self.tabs.tabText(index) == "New Project":
            self.selected_template()
        else:
            self.selected_project()

    def deselected(self):
        self.details.setText(DEFAULT_DETAILS)
        self.go.setDisabled(True)
        self.action = None

    def selected_project(self, *args):
        current = self.projects.currentItem()
        if not current:
            return
        key = current.text()
        project = self.projlist[key]
        tmpl = env.get_template('project_details.html')
        self.details.setText(tmpl.render(project=project))
        self.go.setDisabled(False)
        self.action = partial(self.open_project, project)

    def selected_template(self, *args):
        current = self.templates.currentItem()
        if not current:
            return
        key = current.text()
        tmpl = env.get_template('template_details.html')
        project = next(p for p in PROJECTS if p.NAME == key)
        self.details.setText(tmpl.render(project=project))
        self.go.setDisabled(False)
        self.action = partial(self.new_project, project)

    def perform_action(self):
        if not self.action:
            pass
        self.action()

    def new_project(self, project):
        dlg = QInputDialog()
        dlg.setLabelText("Please enter a name for your new %s project" % project.NAME)
        dlg.setOkButtonText("Create project")
        res = dlg.exec()
        if not res:
            return
        name = dlg.textValue()
        proj = self.projlist.init_project(name, project)
        self.main_window.add_project(proj)

    def open_project(self, proj):
        self.main_window.add_project(proj)
Пример #42
0
class SubwindowLiquipediaSearch(QWidget):
    """Show readme sub window."""

    nams = dict()
    results = dict()
    data = dict()

    def createWindow(self, mainWindow, placeholder, team):
        """Create readme sub window."""
        super().__init__(None)
        self.mainWindow = mainWindow
        self.controller = mainWindow.controller
        self.team = team
        self.liquipediaGrabber = LiquipediaGrabber()
        self.setWindowIcon(QIcon(
            scctool.settings.getResFile("liquipedia.png")))

        self.setWindowModality(Qt.ApplicationModal)

        mainLayout = QGridLayout()
        self.qle_search = QLineEdit(placeholder)
        self.qle_search.setAlignment(Qt.AlignCenter)
        self.qle_search.returnPressed.connect(self.search)
        completer = QCompleter(
            scctool.settings.config.getMyTeams() +
            self.controller.historyManager.getTeamList(), self.qle_search)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        completer.setWrapAround(True)
        self.qle_search.setCompleter(completer)

        mainLayout.addWidget(self.qle_search, 0, 0, 1, 2)
        searchButton = QPushButton(_("Search"))
        searchButton.clicked.connect(self.search)
        mainLayout.addWidget(searchButton, 0, 2)

        self.box = QGroupBox(_("Results"))
        layout = QHBoxLayout()
        self.result_list = QListWidget()
        self.result_list.setViewMode(QListWidget.IconMode)
        self.result_list.itemDoubleClicked.connect(self.doubleClicked)
        self.result_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.result_list.customContextMenuRequested.connect(
            self.listItemRightClicked)

        self.result_list.setIconSize(QSize(75, 75))
        # list.setWrapping(False)
        # list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.result_list.setAcceptDrops(False)
        self.result_list.setDragEnabled(False)
        layout.addWidget(self.result_list)
        self.box.setLayout(layout)

        mainLayout.addWidget(self.box, 1, 0, 1, 3)

        selectButton = QPushButton(" " + _("Use Selected Logo") + " ")
        selectButton.clicked.connect(self.applyLogo)
        closeButton = QPushButton(_("Cancel"))
        closeButton.clicked.connect(self.close)
        mainLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum), 2,
            0)
        mainLayout.addWidget(closeButton, 2, 1)
        mainLayout.addWidget(selectButton, 2, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle(_("Liqupedia Image Search"))

        self.resize(
            QSize(mainWindow.size().width() * 0.9,
                  self.sizeHint().height()))
        relativeChange = QPoint(mainWindow.size().width() / 2,
                                mainWindow.size().height() / 3)\
            - QPoint(self.size().width() / 2,
                     self.size().height() / 3)
        self.move(mainWindow.pos() + relativeChange)

    def clean(self):
        self.nams.clear()
        self.results.clear()
        self.data.clear()

    def search(self):
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.clean()
        loading_map = QPixmap(scctool.settings.getResFile("loading.png"))
        try:
            self.result_list.clear()
            idx = 0
            search_str = self.qle_search.text()
            for name, thumb in self.liquipediaGrabber.image_search(search_str):
                self.data[idx] = name
                name = name.replace('/commons/File:', '')
                self.results[idx] = QListWidgetItem(QIcon(loading_map), name)
                self.results[idx].setSizeHint(QSize(80, 90))
                url = base_url + thumb
                self.nams[idx] = QNetworkAccessManager()
                self.nams[idx].finished.connect(
                    lambda reply, i=idx: self.finishRequest(reply, i))
                self.nams[idx].get(QNetworkRequest(QUrl(url)))
                self.result_list.addItem(self.results[idx])
                if idx == 0:
                    self.result_list.setCurrentItem(self.results[idx])
                idx += 1
            self.box.setTitle(
                _("Results for '{}': {}").format(search_str, idx))
        except Exception as e:
            module_logger.exception("message")
        finally:
            QApplication.restoreOverrideCursor()

    def finishRequest(self, reply, idx):
        img = QImage()
        img.loadFromData(reply.readAll())
        map = QPixmap(img).scaled(75, 75, Qt.KeepAspectRatio)
        self.results[idx].setIcon(QIcon(map))

    def applyLogo(self, skip=False):
        item = self.result_list.currentItem()
        if item is not None and (skip or item.isSelected()):
            for idx, iteritem in self.results.items():
                if item is iteritem:
                    images = self.liquipediaGrabber.get_images(self.data[idx])
                    image = ""
                    for size in sorted(images):
                        if not image or size <= 600 * 600:
                            image = images[size]

                    self.downloadLogo(base_url + image)
                    break

        self.close()

    def doubleClicked(self, item):
        for idx, iteritem in self.results.items():
            if item is iteritem:
                images = self.liquipediaGrabber.get_images(self.data[idx])
                image = ""
                for size in sorted(images):
                    if not image or size <= 600 * 600:
                        image = images[size]

                self.downloadLogo(base_url + image)
                break

        self.close()

    def listItemRightClicked(self, QPos):
        self.listMenu = QMenu()
        menu_item = self.listMenu.addAction(_("Open on Liquipedia"))
        menu_item.triggered.connect(self.openLiquipedia)
        menu_item = self.listMenu.addAction(_("Use as Team Logo"))
        menu_item.triggered.connect(lambda: self.applyLogo(True))
        parentPosition = self.result_list.mapToGlobal(QPoint(0, 0))
        self.listMenu.move(parentPosition + QPos)
        self.listMenu.show()

    def openLiquipedia(self):
        item = self.result_list.currentItem()
        for idx, iteritem in self.results.items():
            if item is iteritem:
                url = base_url + self.data[idx]
                self.controller.openURL(url)
                break

    def downloadLogo(self, url):
        logo = LogoDownloader(self.controller, self, url).download()
        logo.refreshData()
        map = logo.provideQPixmap()

        if self.team == 1:
            self.controller.logoManager.setTeam1Logo(logo)
            self.mainWindow.team1_icon.setPixmap(map)
            self.mainWindow.refreshLastUsed()
        elif self.team == 2:
            self.controller.logoManager.setTeam2Logo(logo)
            self.mainWindow.team2_icon.setPixmap(map)
            self.mainWindow.refreshLastUsed()

    def closeEvent(self, event):
        """Handle close event."""
        try:
            self.clean()
            event.accept()
        except Exception as e:
            module_logger.exception("message")
class ScientificBasisDialog(QDialog):
    """Creates a simple about dialog.

    The about dialog contains general information about the application and
    shows the copyright notice.
    That's why the class has no attributes or return values.

    """

    def __init__(self):
        """The constructor initializes the class AboutDialog."""
        super().__init__()
        self.setAttribute(Qt.WA_DeleteOnClose)

        # initialize class constants
        self._BUTTON_MIN_WIDTH = 110
        self._OXYGEN_PATH_48 = os.path.join("resources", "icons", "oxygen", "48")

        # fonts and margins settings
        hlFont = QFont()
        hlFont.setBold(True)
        hlFont.setPointSize(14)

        # scientific logo
        logo = QLabel(pixmap=QPixmap(os.path.join(self._OXYGEN_PATH_48, "applications-science.png")))

        logoLayout = QVBoxLayout()
        logoLayout.addWidget(logo)
        logoLayout.addStretch()

        # begin the content
        # headline and description text
        self.headline = QLabel()
        self.headline.setFont(hlFont)
        self.description = QLabel(wordWrap=True)

        # the list with the open button
        self.listWidget = QListWidget()
        self.listWidget.setMinimumWidth(420)
        self.createArticles()

        self.openButton = QPushButton()
        self.openButton.clicked.connect(self.openAction)

        listLayout = QHBoxLayout()
        listLayout.addWidget(self.listWidget)
        listLayout.addWidget(self.openButton, alignment=Qt.AlignTop)

        # create a close button
        line = QFrame(frameShadow=QFrame.Sunken, frameShape=QFrame.HLine)
        self.closeButton = QPushButton()
        self.closeButton.setFixedWidth(self._BUTTON_MIN_WIDTH)
        self.closeButton.clicked.connect(self.close)

        # content layout
        contentLayout = QVBoxLayout()
        contentLayout.addWidget(self.headline)
        contentLayout.addWidget(self.description)
        contentLayout.addLayout(listLayout)
        contentLayout.addWidget(line)
        contentLayout.addWidget(self.closeButton, alignment=Qt.AlignRight)

        # main layout
        layout = QHBoxLayout(self)
        layout.addLayout(logoLayout)
        layout.addLayout(contentLayout)

        # translate the graphical user interface
        self.retranslateUi()

    def createArticles(self):
        # load articles from library
        # and add them to the list
        for article in library.SCIENTIFIC_ARTICLES:
            # list widget item with it's data
            item = QListWidgetItem()
            item.setText(article[0].strip())
            item.setData(Qt.UserRole, article[1].strip())

            # add the item to the list widget
            self.listWidget.addItem(item)

    def openAction(self):
        # get the current item from list
        item = self.listWidget.currentItem()

        # create the documentation path with
        # the current locale settings
        articleFile = os.path.join("articles", item.data(Qt.UserRole))

        # on every platfrom a different
        # start operation is needed
        if sys.platform == "win32":
            os.startfile(articleFile)
        elif sys.platform == "darwin":
            subprocess.call(("open", articleFile))
        elif sys.platform.startswith("linux"):
            subprocess.call(("xdg-open", articleFile))

    def retranslateUi(self):
        # dialog titel
        self.setWindowTitle(QApplication.translate("ScientificBasisDialog", "Specialist articles"))        # Wissenschaftliche Grundlage

        # headline and description
        self.headline.setText(QApplication.translate("ScientificBasisDialog", "Specialist articles"))   # Wissenschaftliche Beiträge
        self.description.setText(QApplication.translate("ScientificBasisDialog",
                "Hier finden Sie grundlegende Fachbeiträge zur Thematik") + ":")

        # buttons
        self.openButton.setText(QApplication.translate("ScientificBasisDialog", "Open article"))        # Beitrag öffnen
        self.closeButton.setText(QApplication.translate("ScientificBasisDialog", "Close"))              # Schließen
Пример #44
0
class ImportDialog(QDialog):
    def __init__(self, app):
        """
        Init
        """
        self.app = app

        super(ImportDialog, self).__init__()

        # define UI elements
        self.listOfProfiles = QListWidget(self)
        self.importButton = QPushButton(self)

        # initialize the UI
        self.init_ui()

    def init_ui(self):
        """
        Initialize the actual UI
        :return: 
        """
        # Main window
        desktop = QDesktopWidget()
        screen_width = desktop.screen().width()
        screen_height = desktop.screen().height()
        app_width = 450
        app_height = 375
        self.setWindowTitle('Import profile')
        self.setGeometry(  # this centers the window
            (screen_width / 2) - (app_width / 2),
            (screen_height / 2) - (app_height / 2), app_width, app_height)
        self.setFixedSize(self.size())
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        # elements
        self.create_list_of_profiles()
        self.create_import_button()

    def create_list_of_profiles(self):
        """
        Configure the list of profiles
        :return: 
        """
        self.listOfProfiles.setGeometry(20, 20, 410, 300)
        self.listOfProfiles.itemClicked.connect(self.enable_buttons)
        self.load_profiles()

    def create_import_button(self):
        """
        Configure the save button
        :return: 
        """
        self.importButton.setGeometry(351, 325, 80, 30)
        self.importButton.setText('Import')
        self.importButton.setDisabled(True)
        self.importButton.clicked.connect(self.on_import)

    def load_profiles(self):
        """
        Load mods into the list
        :param mods: 
        :return: 
        """
        self.listOfProfiles.clear()
        for m in self.get_available_profiles():
            # change the name to avoid conflicts - overwriting might cause problems
            if self.app.db.profile_exists(m[0]):
                m[0] = '{} ({})'.format(m[0], datetime.datetime.now())

            item = QListWidgetItem()
            item.setText(m[0])
            item.setData(Qt.UserRole, m[1])
            self.listOfProfiles.addItem(item)

        self.listOfProfiles.sortItems(Qt.AscendingOrder)

    @staticmethod
    def get_available_profiles():
        profiles = []
        for p in os.listdir('profiles'):
            f = open('profiles/' + p, 'r')
            profiles.append(json.loads(f.read()))
            f.close()

        return profiles

    def enable_buttons(self):
        self.importButton.setEnabled(True)

    def on_import(self):
        """
        Insert the profile into database
        :return: 
        """
        item = self.listOfProfiles.currentItem()  # type: QListWidgetItem
        mods = json.dumps(item.data(Qt.UserRole))
        self.app.db.save_mods(item.text(), mods)
        item.setFlags(item.flags() & ~Qt.ItemIsSelectable)
        item.setText(item.text() + ' *IMPORTED*')
        self.app.load_profiles()
Пример #45
0
class MikochikuAlarm(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.search_ch_id = "UC-hM6YJuNYVAmUWxeIr9FeA"
        self.ch_dic = {
            "ときのそら": "UCp6993wxpyDPHUpavwDFqgg",
            "AZKi": "UC0TXe_LYZ4scaW2XMyi5_kw",
            "ロボ子さん": "UCDqI2jOz0weumE8s7paEk6g",
            "さくらみこ": "UC-hM6YJuNYVAmUWxeIr9FeA",
            "白上フブキ": "UCdn5BQ06XqgXoAxIhbqw5Rg",
            "夏色まつり": "UCQ0UDLQCjY0rmuxCDE38FGg",
            "夜空メル": "UCD8HOxPs4Xvsm8H0ZxXGiBw",
            "赤井はあと": "UC1CfXB_kRs3C-zaeTG3oGyg",
            "アキ・ローゼンタール": "UCFTLzh12_nrtzqBPsTCqenA",
            "湊あくあ": "UC1opHUrw8rvnsadT-iGp7Cg",
            "癒月ちょこ": "UC1suqwovbL1kzsoaZgFZLKg",
            "百鬼あやめ": "UC7fk0CB07ly8oSl0aqKkqFg",
            "紫咲シオン": "UCXTpFs_3PqI41qX2d9tL2Rw",
            "大空スバル": "UCvzGlP9oQwU--Y0r9id_jnA",
            "大神ミオ": "UCp-5t9SrOQwXMU7iIjQfARg",
            "猫又おかゆ": "UCvaTdHTWBGv3MKj3KVqJVCw",
            "戌神ころね": "UChAnqc_AY5_I3Px5dig3X1Q",
            "不知火フレア": "UCvInZx9h3jC2JzsIzoOebWg",
            "白銀ノエル": "UCdyqAaZDKHXg4Ahi7VENThQ",
            "宝鐘マリン": "UCCzUftO8KOVkV4wQG1vkUvg",
            "兎田ぺこら": "UC1DCedRgGHBdm81E1llLhOQ",
            "潤羽るしあ": "UCl_gCybOJRIgOXw6Qb4qJzQ",
            "星街すいせい": "UC5CwaMl1eIgY8h02uZw7u8A",
            "天音かなた": "UCZlDXzGoo7d44bwdNObFacg",
            "桐生ココ": "UCS9uQI-jC3DE0L4IpXyvr6w",
            "角巻わため": "UCqm3BQLlJfvkTsX_hvm0UmA",
            "常闇トワ": "UC1uv2Oq6kNxgATlCiez59hw",
            "姫森ルーナ": "UCa9Y57gfeY0Zro_noHRVrnw"
        }
        self.old_video_id_list = []
        self.initUI()

    def initUI(self):

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.check_live)
        self.timer.setInterval(5000)
        self.timer.start()

        label = QLabel(self)
        label.setPixmap(QPixmap(resource_path("icon.ico")))
        label.move(60, 70)

        self.alarm_cb = QCheckBox('配信が始まったらアラームを鳴らす', self)
        self.alarm_cb.move(20, 20)
        self.alarm_cb.toggle()

        # self.loop_cb = QCheckBox('アラームをループ再生する', self)
        # self.loop_cb.move(20, 40)
        # self.loop_cb.toggle()

        self.webbrowser_cb = QCheckBox('配信が始まったら自動でブラウザを開く', self)
        self.webbrowser_cb.move(20, 40)
        self.webbrowser_cb.toggle()

        self.alarm_stop = QPushButton("待機中", self)
        # self.alarm_stop.setCheckable(True)
        # self.alarm_stop.setEnabled(False)
        self.alarm_stop.move(80, 360)
        self.alarm_stop.clicked[bool].connect(self.stop_alarm)

        self.listWidget = QListWidget(self)
        self.listWidget.resize(300, 150)
        self.listWidget.addItem("ときのそら")
        self.listWidget.addItem("AZKi")
        self.listWidget.addItem("ロボ子さん")
        self.listWidget.addItem("さくらみこ")
        self.listWidget.addItem("白上フブキ")
        self.listWidget.addItem("夏色まつり")
        self.listWidget.addItem("夜空メル")
        self.listWidget.addItem("赤井はあと")
        self.listWidget.addItem("アキ・ローゼンタール")
        self.listWidget.addItem("湊あくあ")
        self.listWidget.addItem("癒月ちょこ")
        self.listWidget.addItem("百鬼あやめ")
        self.listWidget.addItem("紫咲シオン")
        self.listWidget.addItem("大空スバル")
        self.listWidget.addItem("大神ミオ")
        self.listWidget.addItem("猫又おかゆ")
        self.listWidget.addItem("戌神ころね")
        self.listWidget.addItem("不知火フレア")
        self.listWidget.addItem("白銀ノエル")
        self.listWidget.addItem("宝鐘マリン")
        self.listWidget.addItem("兎田ぺこら")
        self.listWidget.addItem("潤羽るしあ")
        self.listWidget.addItem("星街すいせい")
        self.listWidget.addItem("天音かなた")
        self.listWidget.addItem("桐生ココ")
        self.listWidget.addItem("角巻わため")
        self.listWidget.addItem("常闇トワ")
        self.listWidget.addItem("姫森ルーナ")

        self.listWidget.move(30, 200)

        self.listWidget.itemClicked.connect(self.clicked)

        self.setGeometry(300, 300, 400, 400)
        self.setWindowTitle('みこ畜アラーム')

        self.show()

    def clicked(self, qmodelindex):
        self.search_ch_id = self.ch_dic[self.listWidget.currentItem().text()]

    def check_live(self):
        buff_video_id_set = self.get_live_video_id(self.search_ch_id)
        print(self.listWidget.selectedIndexes())
        if self.listWidget.selectedIndexes() is None:
            print("aaaa")
            self.search_ch_id = ""
        if buff_video_id_set:
            for getting_video_id in buff_video_id_set:
                if not getting_video_id == "" and not getting_video_id is None:
                    if not getting_video_id in self.old_video_id_list:
                        self.old_video_id_list.append(getting_video_id)
                        if len(self.old_video_id_list) > 30:
                            self.old_video_id_list = self.old_video_id_list[1:]
                        print("")
                        print("配信が始まりました")
                        # self.alarm_stop.setEnabled(False)
                        self.alarm_stop.click()
                        self.alarm_stop.setText("ストップ")
                        if self.webbrowser_cb.checkState():
                            webbrowser.open(
                                "https://www.youtube.com/watch?v=" +
                                getting_video_id)
                        if self.alarm_cb.checkState():
                            self.alarm_sound()

    def stop_alarm(self):
        pygame.mixer.music.stop()
        self.alarm_stop.setEnabled(True)
        self.alarm_stop.setText("待機中")

    def alarm_sound(self):
        # loop = 1
        # if self.loop_cb.checkState():
        loop_count = 5
        pygame.mixer.music.play(loop_count)
        pygame.mixer.music.play(loop_count)

    def get_live_video_id(self, search_ch_id):
        dict_str = ""
        video_id_set = set()
        try:
            session = requests.Session()
            headers = {
                'user-agent':
                'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
            }
            html = session.get("https://www.youtube.com/channel/" +
                               search_ch_id,
                               headers=headers,
                               timeout=10)
            soup = BeautifulSoup(html.text, 'html.parser')
            keyword = 'window["ytInitialData"]'
            for scrp in soup.find_all("script"):
                if keyword in str(scrp):
                    dict_str = str(scrp).split(' = ', 1)[1]
            dict_str = dict_str.replace('false', 'False')
            dict_str = dict_str.replace('true', 'True')

            index = dict_str.find("\n")
            dict_str = dict_str[:index - 1]
            dics = eval(dict_str)
            for section in dics.get("contents", {}).get(
                    "twoColumnBrowseResultsRenderer",
                {}).get("tabs",
                        {})[0].get("tabRenderer",
                                   {}).get("content",
                                           {}).get("sectionListRenderer",
                                                   {}).get("contents", {}):
                for itemsection in section.get("itemSectionRenderer",
                                               {}).get("contents", {}):
                    items = {}
                    if "shelfRenderer" in itemsection:
                        for items in itemsection.get("shelfRenderer",
                                                     {}).get("content",
                                                             {}).values():
                            for item in items.get("items", {}):
                                for videoRenderer in item.values():
                                    for badge in videoRenderer.get(
                                            "badges", {}):
                                        if badge.get(
                                                "metadataBadgeRenderer",
                                            {}).get(
                                                "style", {}
                                            ) == "BADGE_STYLE_TYPE_LIVE_NOW":
                                            video_id_set.add(
                                                videoRenderer.get(
                                                    "videoId", ""))
                    elif "channelFeaturedContentRenderer" in itemsection:
                        for item in itemsection.get(
                                "channelFeaturedContentRenderer",
                            {}).get("items", {}):
                            for badge in item.get("videoRenderer",
                                                  {}).get("badges", {}):
                                if badge.get("metadataBadgeRenderer", {}).get(
                                        "style",
                                        "") == "BADGE_STYLE_TYPE_LIVE_NOW":
                                    video_id_set.add(
                                        item.get("videoRenderer",
                                                 {}).get("videoId", ""))
        except:
            return video_id_set

        return video_id_set
Пример #46
0
class MainWin(QMainWindow):
	lis = None
	img = None
	lay = None
	button = None
	edge_cut_text_field = None
	edge_cut_label = None
	blur_radius_text_field = None
	
	def __init__(self):
		super().__init__()
		self.init_ui()

	def init_ui(self):
		self.lay = QHBoxLayout()
		self.setLayout(self.lay)
		self.statusBar().showMessage('Ready')
		self.setGeometry(100, 100, 900, 900)
		self.setMinimumSize(500, 500)
		self.setWindowTitle('Gluten Free Radioactive Green Beans')

		self.init_file_menu()
		self.init_list_view()
		self.init_image_viewer()
		self.init_text_fields()
		self.button = QPushButton("Process Image", self)
		self.button.setToolTip("This will process the given image and save it.")
		self.button.move(200, 850)
		self.button.clicked.connect(self.process_button_pressed)
		self.show()

	def init_image_viewer(self):
		self.img = QLabel(self)
		self.img.resize(800,800)
		self.img.move(200,20)
		self.lay.addWidget(self.img)

	def init_list_view(self):
		self.lis=QListWidget(self)
		self.lis.move(0, 20)
		self.lis.currentItemChanged.connect(self.list_selection_changed)
		self.lay.addWidget(self.lis)

	def init_file_menu(self):
		exit_item = QAction('&Exit', self)
		exit_item.setShortcut('Ctrl+Q')
		exit_item.setStatusTip('Exit Application')
		exit_item.triggered.connect(qApp.quit)

		import_item = QAction('&Import', self)
		import_item.setShortcut('Ctrl+I')
		import_item.triggered.connect(self.import_action)

		menubar = self.menuBar()
		file_menu = menubar.addMenu('&File')
		
		file_menu.addAction(import_item)
		file_menu.addAction(exit_item)

	def init_text_fields(self):
		self.edge_cut_text_field = QLineEdit(self)
		self.edge_cut_text_field.resize(50,24)
		self.edge_cut_text_field.textChanged.connect(self.edge_cut_changed)
		self.edge_cut_label = QLabel(self)
		self.edge_cut_label.setText("Edge Cut")
		self.edge_cut_label.resize(50,24)
		

	def edge_cut_changed(self):
		ld.set_preproc_edge_cut(int(self.edge_cut_text_field.text()))

	def import_action(self):
		filepath = self.show_import_folder_dialog()
		if(filepath == ''):
			return
		file_list = ld.clean_file_list(ld.get_files_in(filepath))
		self.lis.addItems(file_list)
		
	def show_import_folder_dialog(self):
		options = QFileDialog.Options()
		return QFileDialog.getExistingDirectory(self,"QFileDialog.getOpenFileName()", options=options)

	def resizeEvent(self,event):
		self.respond_to_resize()
	
	def respond_to_resize(self):
		self.lis.setGeometry(0, 20, self.frameGeometry().width() // 5, self.frameGeometry().height() - 80)
		self.button.move(self.frameGeometry().width() // 5, 850)
		self.img.move(self.frameGeometry().width() // 5, 20)
		self.edge_cut_text_field.move((self.frameGeometry().width() // 4) + 150, 850)
		self.edge_cut_label.move(self.frameGeometry().width()//4 + 100 , 850)

	def list_selection_changed(self):
		if(self.lis.currentItem() == None):
			return
		qpm = QPixmap(self.lis.currentItem().text())
		self.img.resize(qpm.width(),qpm.height())
		self.img.setPixmap(qpm)
		QApplication.processEvents()
	
	def process_button_pressed(self):
		self.process_image()

	def process_image(self):
		if(self.lis.currentItem() == None):
			return
		current_selection = self.lis.currentItem().text()
		ld.process_image(current_selection)
		filepath = current_selection[:current_selection.rfind('/')]
		file_list = ld.clean_file_list(ld.get_files_in(filepath))
		self.lis.clear()
		self.lis.addItems(file_list)
Пример #47
0
class window(QtWidgets.QMainWindow):   
   def __init__(self):
      super(window,self).__init__()
      self.currentlocal=0
      self.data=None
      self.checker=0
      self.lastcolored=0
      self.photo = QLabel(self)
      self.port=0
      self.pixmap = QPixmap('photo.png')
      self.pixmap = self.pixmap.scaled(600, 300, QtCore.Qt.KeepAspectRatio)
      self.photo.setPixmap(self.pixmap)

      self.labelgif=QLabel(self)      
      self.labelgif.setStyleSheet("QLabel { background-color : white;}");
      self.labelgif.setGeometry(100,50,500,430)
      self.movie = QtGui.QMovie('data.gif', QtCore.QByteArray(),self.labelgif)
      self.movie.setSpeed(100)
      self.labelgif.setMovie(self.movie) 
      self.movie.start()
      self.labelgif.setVisible(False)

      self.labelyazi=QLabel(self)
      self.labelgif1=QLabel(self)      
      self.labelgif1.setStyleSheet("QLabel { background-color : white;}")
      self.labelyazi.setText('G'+"\u00F6"+"zl"+"\u0259"+"yin..")
      font1=QtGui.QFont('Times',17)
      self.labelyazi.setFont(font1)
      self.labelyazi.setVisible(False)
      self.labelyazi.setGeometry(350,150,150,60)
      self.labelgif1.setGeometry(150,100,489,289)
      self.movie1 = QtGui.QMovie('wait.gif', QtCore.QByteArray(),self.labelgif1)
      self.movie1.setSpeed(100)
      self.labelgif1.setMovie(self.movie1) 
      self.movie1.start()
      self.labelgif1.setVisible(False)

      
      self.setWindowTitle("Diplom i\u015Fi v1")      
      self.setWindowIcon(QtGui.QIcon('pyicon.png'))
      self.button = QPushButton('PyQt5 button', self)#button yaradildi
      self.listw=QListWidget(self)#listWidget yaradildi
      self.button1=QPushButton(self)
      self.buttonlocal=QPushButton(self)
      self.buttonlocal.setText('Qo\u015F')
      self.button1.setText("Temperaturu"+" " +"\u00F6"+"l"+"\u00E7")
      self.dial=QDial(self)
      self.lcd=QLCDNumber(self)
      self.label=QLabel(self)
      self.labelrefresh=QLabel(self)
      self.obj=[]
   
      
      self.listCOM=QListWidget(self)
      self.spin=QSpinBox(self)
      self.radiosan=QRadioButton(self)
      self.radiosan.setText("Saniy"+"\u0259")
      self.radiodeq=QRadioButton(self)
      self.radiodeq.setText("D"+"\u0259"+"qiq"+"\u0259")
      self.starting()
      self.initUI()

      
   def initUI(self):                  
        self.setFixedSize(700,500)
        self.dial.setNotchesVisible(True)
        self.labelrefresh.setText('Yenil\u0259m\u0259k \u00FC\u00E7\u00FCn F5 d\u00FCym\u0259sini s\u0131x\u0131n ')
        self.labelrefresh.setStyleSheet("QLabel{background-color: yellow; }")
        font=QtGui.QFont('Times',10,QtGui.QFont.Bold)
        self.labelrefresh.setFont(font)
        self.lcd.setVisible(False)
        self.photo.setVisible(False)
        self.photo.raise_()            
        self.labelgif.raise_()
        self.labelgif1.raise_()
        self.labelyazi.raise_()
        self.spin.setRange(1,60)
        self.dial.setRange(1,60)
        self.button.setText("\u015E"+"\u0259"+"b\u0259k\u0259ni yoxla")
        self.button1.setEnabled(False)
        self.button.setEnabled(False)
        self.spin.setEnabled(False)
        self.dial.setEnabled(False)
        self.radiosan.setEnabled(False)
        self.radiodeq.setEnabled(False)
        self.label.setText('Qo\u015Fulmu'+'\u015F cihaz yoxdur')
        self.label.setStyleSheet("QLabel { background-color : #e20000; color : black; }");
        newfont = QtGui.QFont('Times',11) 
        self.label.setFont(newfont)        
        

        
        #geometries
        self.setGeometry(40,50,700,500)
        self.button.setGeometry(20,40,120,50)
        self.listw.setGeometry(380,160,300,200)
        self.button1.setGeometry(575,40,120,50)
        self.dial.setGeometry(40,400,75,70)
        self.spin.setGeometry(150,425,50,25)
        self.radiosan.setGeometry(150,400,75,25)
        self.radiodeq.setGeometry(150,380,75,25)
        self.lcd.setGeometry(300,40,100,50)
        self.buttonlocal.setGeometry(150,40,125,50)
        self.label.setGeometry(520,440,155,30)
        self.listCOM.setGeometry(20,160,300,200)
        self.labelrefresh.setGeometry(20,100,220,30)
        self.photo.setGeometry(50,100,600,300)
        
    
        #events
        self.buttonlocal.clicked.connect(self.checklocal)
        self.button.clicked.connect(self.thread1)
        self.button.clicked.connect(self.threadnetwork)
        self.dial.valueChanged.connect(self.spin.setValue)
        self.spin.valueChanged.connect(self.dial.setValue)
        self.listCOM.doubleClicked.connect(self.showdialog)
        self.listw.doubleClicked.connect(self.showdialogremote)
        self.button1.clicked.connect(self.thread) # communication
        self.radiodeq.clicked.connect(self.spinvalue)
        self.radiosan.clicked.connect(self.dialvalue)
        self.button1.clicked.connect(self.threadback)


    
   def threadback(self):
      if  self.radiodeq.isChecked() or self.radiosan.isChecked():
         self.thread1=threading.Thread(target=self.send)
         self.thread1.start()
      else:
         pass
   def loading(self):
      m=loading()
      

      
   def send(self):
      try:    
         self.currentlocal.open()
         remotestr=self.listw.currentItem().text()
         li=remotestr.split("-")
         xbee_network=self.currentlocal.get_network()         
         remote=xbee_network.get_device_by_64(XBee64BitAddress.from_hex_string(li[0]))
         arr_64=self.currentlocal.get_64bit_addr()
         NEW_TIMEOUT_FOR_SYNC_OPERATIONS = 1
         self.currentlocal.set_sync_ops_timeout(NEW_TIMEOUT_FOR_SYNC_OPERATIONS)
         if self.radiosan.isChecked():
            self.currentlocal.send_data(remote,str(arr_64)+"-"+str(self.spin.value()))
         else:
            self.currentlocal.send_data(remote,str(arr_64)+"-"+str(self.spin.value()*60))
         self.labelgif1.setVisible(False)     
         
                   
         self.labelgif1.setVisible(True)
         self.labelyazi.setVisible(True)
         while(True):
            self.data=self.currentlocal.read_data()
            if(self.data!=None):
               self.data=self.data.data.decode()
               self.labelgif1.setVisible(False)
               self.labelyazi.setVisible(False)
               break 
             
         self.currentlocal.close()
         
         data_list=self.data.split(',')
         self.labelgif.setVisible(True)
         
         objects = []
         performance=[]
         for i in range(1,len(data_list)):
            objects.append(i)
         for i in range(len(data_list)-1):
            li=data_list[i]
            li=li.split('-')
            performance.append(li[1])
         
         y_pos = np.arange(len(objects))
         objects=tuple(objects)
         plt.figure("Qrafik")
         plt.xticks(y_pos, objects)
         plt.ylabel('Temperatur')
         plt.xlabel('Zaman')
         plt.plot(y_pos,performance)
         self.labelgif.setVisible(False)
         plt.show()
         self.data=None
         
      except:
         print('salam')
         self.currentlocal.close()
      
         

         
   def showdialog(self): 
      try:
         li=self.listCOM.currentItem().text().split('-')
         local=XBeeDevice(li[2],9600)
         local.open()
         arr_64=local.get_64bit_addr()
         arr_16=local.get_16bit_addr()
         arr_node=local.get_node_id()
         arr_pro=local.get_protocol()
         arr_hard=local.get_hardware_version()
         local.close()
         dlg=dialog(arr_64,arr_16,arr_node,arr_pro,arr_hard)
      except:
         pass    #exception

      
   def showdialogremote(self): 
      li=self.listw.currentItem().text().split('-')
      if self.checker !=0:
         self.lastcolored.setBackground(QtGui.QColor(255,255,255))
         
      self.lastcolored=self.listw.currentItem()
      self.listw.currentItem().setBackground(QtGui.QColor(239, 255, 25))
      try:
         self.currentlocal.open()
         
         xbee_network=self.currentlocal.get_network()
         
         remote=xbee_network.get_device_by_64(XBee64BitAddress.from_hex_string(li[0]))
         
         arr_64=remote.get_64bit_addr()
         
         arr_16=remote.get_16bit_addr()
         arr_node=remote.get_node_id()
         arr_pro=remote.get_protocol()
         arr_hard=remote.get_hardware_version()
         self.currentlocal.close()
         dlg=dialog(arr_64,arr_16,arr_node,arr_pro,arr_hard)
         self.checker=1
      except:
         pass # exception
      

   def spinvalue(self):
      self.dial.setRange(1,60)
      self.spin.setRange(1,60)
      self.dial.setValue(1)
   def dialvalue(self):
      self.dial.setRange(4,60)
      self.spin.setRange(4,60)
      self.dial.setValue(4)
      
        
   def keyPressEvent(self, event):
      key = event.key()
      if key == QtCore.Qt.Key_F5:
         self.threadrefresh()


      

   def checklocal(self):                                               
      try:         
         if (self.currentlocal !=0):
            for i in range(0,self.listCOM.count()):
                 self.listCOM.item(i).setBackground(QtGui.QColor(255, 255, 255))
         self.listCOM.currentItem().setBackground(QtGui.QColor(97, 255, 66))
         li=self.listCOM.currentItem().text().split('-')
         self.currentlocal = XBeeDevice(li[2], 9600)
         self.port=li[2]        
         self.currentCOM=self.listCOM.currentItem().text()
         self.currentlocal.open()
         self.currentlocal.close()
         self.listw.clear()
         self.button1.setEnabled(True)
         self.button.setEnabled(True)
         self.spin.setEnabled(True)
         self.dial.setEnabled(True)     
         self.radiosan.setEnabled(True)
         self.radiodeq.setEnabled(True)
         if platform.system()=='Linux':
            self.label.setGeometry(500,440,180,30)
         self.label.setText('Qo\u015Fulmu'+'\u015F port: '+str(li[2]))
         self.checker=0  
         self.label.setStyleSheet("QLabel { background-color : #22ce00; color : white; }")
         
         
         
         
      except:
         QMessageBox.about(self, 'Yanl\u0131\u015F', 'Lokal cihaz\u0131n portu do\u011Fru deyil')

   def refresh(self):                                                                  
      self.listCOM.clear()
      index=0
      if platform.system()=='Windows':
         for i in range(0,257):
               try:               
                  local_xbee = XBeeDevice('COM'+str(i), 9600)
                  local_xbee.open()
                  addr64=local_xbee.get_64bit_addr()
                  noid=local_xbee.get_node_id()
                  local_xbee.close()
                  self.listCOM.addItem(str(addr64)+"-"+str(noid)+"-"+'COM'+str(i))
                  if(self.port=='COM'+str(i)):               
                     self.listCOM.item(index).setBackground(QtGui.QColor(97, 255, 66))
                  index+=1
               except:
                  pass
      elif platform.system()=='Linux':
         for i in range(257):
            try:               
               local_xbee = XBeeDevice('/dev/ttyUSB'+str(i), 9600)
               local_xbee.open()
               addr64=local_xbee.get_64bit_addr()
               noid=local_xbee.get_node_id()
               local_xbee.close()
               self.listCOM.addItem(str(addr64)+"-"+str(noid)+"-"+'/dev/ttyUSB'+str(i))
               if(self.port=='/dev/ttyUSB'+str(i)):               
                  self.listCOM.item(index).setBackground(QtGui.QColor(97, 255, 66))
               index+=1
            except:
               pass
      self.checker=0
         
      
      

         
        
   def thread(self):                                               
      if  self.radiodeq.isChecked() or self.radiosan.isChecked():
         self.thread=threading.Thread(target=self.timing)
         self.thread.start()
      else:
         QMessageBox.about(self, 'Yanl\u0131\u015F', 'Zaman vahidini se\u00E7in')

         
            
            
   def thread1(self):                                                          
      if  self.radiodeq.isChecked() or self.radiosan.isChecked():
         self.thread1=threading.Thread(target=self.scan)
         self.thread1.start()
      else:
         QMessageBox.about(self, 'Yanl\u0131\u015F', 'Zaman vahidini se\u00E7in')

   def threadnetwork(self):
      if  self.radiodeq.isChecked() or self.radiosan.isChecked():
         self.thread1=threading.Thread(target=self.network)
         self.thread1.start()
      else:
         pass


   def network(self):
      try:
         self.button1.setEnabled(False)
         self.buttonlocal.setEnabled(False)
         self.button.setEnabled(False)
         self.button1.setEnabled(False)
         self.spin.setEnabled(False)
         self.dial.setEnabled(False)    
         self.radiosan.setEnabled(False)
         self.radiodeq.setEnabled(False)
         self.listw.clear()
         self.currentlocal.open()
         xbee_network=self.currentlocal.get_network()
         xbee_network.clear()
         listdev=[]
         def callback_device_discovered(remote):
            listdev.append(str(remote))
         if self.radiosan.isChecked():
            if(self.spin.value()>25):
               defe=int((self.spin.value())/25)
               qaliqsan=(self.spin.value())%25
               for i in range(0,defe):
                  xbee_network.set_discovery_timeout(22)  
                  xbee_network.add_device_discovered_callback(callback_device_discovered)
                  xbee_network.start_discovery_process()
                  while xbee_network.is_discovery_running():
                     QtCore.QThread.msleep(100)
               if(qaliqsan<4):
                  add=q=4-qaliqsan
                  xbee_network.set_discovery_timeout(qaliqsan+add)  
                  xbee_network.add_device_discovered_callback(callback_device_discovered)
                  xbee_network.start_discovery_process()
                  while xbee_network.is_discovery_running():
                     QtCore.QThread.msleep(100)
               else:
                  xbee_network.set_discovery_timeout(qaliqsan) 
                  xbee_network.add_device_discovered_callback(callback_device_discovered)
                  xbee_network.start_discovery_process()
                  while xbee_network.is_discovery_running():
                     QtCore.QThread.msleep(100)
                     
               
               self.currentlocal.close()
            else:
               
               xbee_network.set_discovery_timeout(self.spin.value())   
               xbee_network.add_device_discovered_callback(callback_device_discovered)
               xbee_network.start_discovery_process()
               while xbee_network.is_discovery_running():
                  QtCore.QThread.msleep(100)
               self.currentlocal.close()
               
           
            self.photo.setVisible(True)
            listdev=list(set(listdev))
            for i in range(0,len(listdev)):
               self.listw.addItem(listdev[i])
            QtCore.QThread.msleep(1000)
            self.photo.setEnabled(True)
            self.buttonlocal.setEnabled(True)
            self.button1.setEnabled(True)
            self.button.setEnabled(True)
            self.spin.setEnabled(True)
            self.dial.setEnabled(True)     
            self.radiosan.setEnabled(True)
            self.radiodeq.setEnabled(True)
            self.photo.setVisible(False)
            
            

         if self.radiodeq.isChecked():
         
            defe=int((self.spin.value()*60)/25)
            qaliqsan=(self.spin.value()*60)%25
            for i in range(0,defe):
               xbee_network.set_discovery_timeout(22)  # 24 seconds + saniye elave.
               xbee_network.add_device_discovered_callback(callback_device_discovered)
               xbee_network.start_discovery_process()
               while xbee_network.is_discovery_running():
                  QtCore.QThread.msleep(100)
            xbee_network.set_discovery_timeout(qaliqsan)  # qaliq saniye.
            xbee_network.add_device_discovered_callback(callback_device_discovered)
            xbee_network.start_discovery_process()
            while xbee_network.is_discovery_running():
               QtCore.QThread.msleep(100)
            self.currentlocal.close()
         else:
            xbee_network.set_discovery_timeout(self.spin.value())  # qaliq saniye 
            xbee_network.add_device_discovered_callback(callback_device_discovered)
            xbee_network.start_discovery_process()
            while xbee_network.is_discovery_running():
               QtCore.QThread.msleep(100)
            self.currentlocal.close()
            
         self.photo.setVisible(True)  
         listdev=list(set(listdev))
         for i in range(0,len(listdev)):
            self.listw.addItem(listdev[i])
         QtCore.QThread.msleep(2000)
         self.buttonlocal.setEnabled(True)
         self.button1.setEnabled(True)
         self.button.setEnabled(True)
         self.spin.setEnabled(True)
         self.dial.setEnabled(True)
         self.radiosan.setEnabled(True)
         self.radiodeq.setEnabled(True)
         self.photo.setVisible(False)
         
      except:
         self.currentlocal.close()





   def threadrefresh(self):
      t=threading.Thread(target=self.refresh)
      t.start()
      


   #UI has been finished
      
   def timing(self):
      QtCore.QThread.msleep(1000)
      self.button1.setEnabled(False)
      if(self.radiodeq.isChecked()):
         self.lcd.setVisible(True)
         j=self.spin.value()*60
         k=self.spin.value()
         if(k<10):
            self.lcd.display("0{}:00".format(k))
            QtCore.QThread.msleep(1000)
         else:
            self.lcd.display("{}:00".format(k))
            QtCore.QThread.msleep(1000)
            
         j-=1
         k-=1
         while(j>-1):
            if(k<10):
               if(j%60<10):
                  if(j%60 is 0):                     
                     self.lcd.display("0{}:0{}".format(k,j%60))
                     k-=1
                     j-=1
                     QtCore.QThread.msleep(1000)
                     continue
                  self.lcd.display("0{}:0{}".format(k,j%60))
                  app.processEvents()
                  QtCore.QThread.msleep(1000)                     
                  j-=1
               else:
                  self.lcd.display("0{}:{}".format(k,j%60))
                  QtCore.QThread.msleep(1000)                     
                  j-=1
            else:
               if(j%60 is 0):
                  self.lcd.display("0{}:0{}".format(k,j%60))
                  k-=1
                  j-=1
                  QtCore.QThread.msleep(1000)
                  continue
               if(j%60<10):
                  self.lcd.display("{}:0{}".format(k,j%60))
                  QtCore.QThread.msleep(1000)
                  j-=1
               else:
                  self.lcd.display("{}:{}".format(k,j%60))
                  QtCore.QThread.msleep(1000)                     
                  j-=1
         self.lcd.setVisible(False)
         self.button1.setEnabled(True)

      elif (self.radiosan.isChecked()):
         self.lcd.setVisible(True)
         timing=self.spin.value()
         for i in range(timing,-1,-1):                     
            if(i<10):
               self.lcd.display("00:0{}".format(i))
               QtCore.QThread.msleep(1000)
               
            else:
               self.lcd.display("00:{}".format(i))
               QtCore.QThread.msleep(1000)
         self.lcd.setVisible(False)
         self.button1.setEnabled(True)

   def starting(self):
      splash=QtWidgets.QSplashScreen(QtGui.QPixmap('splash.jpg'),QtCore.Qt.WindowStaysOnTopHint)
      splash.show()
      for i in range(0,257):
         app.processEvents()
         if (i is 50):
               splash.showMessage("<h1><font color=#608fdb>Proqram başladılır!</font></h1>", QtCore.Qt.AlignTop)
               QtCore.QThread.msleep(1000)
         try:
            if (platform.system() == 'Windows'):
               local_xbee = XBeeDevice('COM'+str(i), 9600)
               local_xbee.open()
               addr64=local_xbee.get_64bit_addr()
               noid=local_xbee.get_node_id()
               local_xbee.close()
               self.listCOM.addItem(str(addr64)+"-"+str(noid)+"-"+'COM'+str(i))
            elif (platform.system() == 'Linux'):
               local_xbee = XBeeDevice('/dev/ttyUSB'+str(i), 9600)
               local_xbee.open()
               addr64=local_xbee.get_64bit_addr()
               noid=local_xbee.get_node_id()
               local_xbee.close()
               self.listCOM.addItem(str(addr64)+"-"+str(noid)+"-"+'/dev/ttyUSB'+str(i))         
         except:
            pass
      splash.close()

         
         
         



   def createlistw(self):
       self.listw.clear()
       for i in range(0,9):
          self.obj.append(i)
          self.obj[i]=elements()
          self.obj[i].t=[10,20,30,40,2,3,4,5,6]
          self.obj[i].s=[5,6,7,8,9,1,2,3,4,5,88]
          self.listw.addItem(str(self.obj[i].t[i]))

            
           

   def scan(self):
      self.button.setEnabled(False)

      if(self.radiodeq.isChecked()):
         self.lcd.setVisible(True)
         j=self.spin.value()*60
         k=self.spin.value()
         if(k<10):
            self.lcd.display("0{}:00".format(k))
            QtCore.QThread.msleep(1000)
         else:
            self.lcd.display("{}:00".format(k))
            QtCore.QThread.msleep(1000)
            
         j-=1
         k-=1
         while(j>-1):
            if(k<10):
               if(j%60<10):
                  if(j%60 is 0):
                     self.lcd.display("0{}:0{}".format(k,j%60))
                     k-=1
                     j-=1
                     QtCore.QThread.msleep(1000)
                     continue
                  self.lcd.display("0{}:0{}".format(k,j%60))
                  app.processEvents()
                  QtCore.QThread.msleep(1000)                     
                  j-=1
               else:
                  self.lcd.display("0{}:{}".format(k,j%60))
                  QtCore.QThread.msleep(1000)                     
                  j-=1
            else:
               if(j%60 is 0):
                  self.lcd.display("0{}:0{}".format(k,j%60))
                  k-=1
                  j-=1
                  QtCore.QThread.msleep(1000)
                  continue
               if(j%60<10):
                  self.lcd.display("{}:0{}".format(k,j%60))
                  QtCore.QThread.msleep(1000)
                  j-=1
               else:
                  self.lcd.display("{}:{}".format(k,j%60))
                  QtCore.QThread.msleep(1000)                     
                  j-=1
         self.lcd.setVisible(False)
         self.button.setEnabled(True)
      elif (self.radiosan.isChecked()):
         self.lcd.setVisible(True)
         timing=self.spin.value()
         for i in range(timing,-1,-1):
            if(i<10):
               self.lcd.display("00:0{}".format(i))
               QtCore.QThread.msleep(1000)                     
            else:
               self.lcd.display("00:{}".format(i))
               QtCore.QThread.msleep(1000)
         self.lcd.setVisible(False)
         self.button.setEnabled(True)
Пример #48
0
class PostProcessor(QMainWindow):

    sim_results_changed = pyqtSignal()
    post_results_changed = pyqtSignal()

    figures_changed = pyqtSignal(list, str)

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self._settings = QSettings()
        self._logger = logging.getLogger(self.__class__.__name__)

        self.setWindowTitle("Processing")
        self.setWindowIcon(QIcon(get_resource("processing.png")))
        self.mainFrame = QWidget(self)
        self.resize(1000, 600)

        # toolbar
        self.toolBar = QToolBar("file control")
        self.toolBar.setIconSize(QSize(24, 24))
        self.addToolBar(self.toolBar)

        self.actLoad = QAction(self)
        self.actLoad.setText("load result file")
        self.actLoad.setIcon(QIcon(get_resource("load.png")))
        self.actLoad.setDisabled(False)
        self.actLoad.triggered.connect(self.load_result_files)

        self.actPostLoad = QAction(self)
        self.actPostLoad.setText("load post-result file")
        self.actPostLoad.setIcon(QIcon(get_resource("load.png")))
        self.actPostLoad.setDisabled(False)
        self.actPostLoad.triggered.connect(self.load_post_result_files)

        self.actSwitch = QAction(self)
        self.actSwitch.setText("switch display mode")
        self.actSwitch.setIcon(QIcon(get_resource("left_mode.png")))
        self.actSwitch.setDisabled(False)
        self.actSwitch.triggered.connect(self.switch_sides)
        self.displayLeft = True

        self.spacer1 = QWidget()
        self.spacer2 = QWidget()
        self.spacer1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.spacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.actReloadMethods = QAction(self)
        self.actReloadMethods.setText("reload methods")
        self.actReloadMethods.setIcon(QIcon(get_resource("reload.png")))
        self.actReloadMethods.setDisabled(False)
        self.actReloadMethods.triggered.connect(self.update_post_method_list)

        self.actReloadMetaMethods = QAction(self)
        self.actReloadMetaMethods.setText("reload meta methods")
        self.actReloadMetaMethods.setIcon(QIcon(get_resource("reload.png")))
        self.actReloadMetaMethods.setDisabled(False)
        self.actReloadMetaMethods.triggered.connect(
            self.update_meta_method_list)
        
        self.toolBar.addAction(self.actLoad)
        self.toolBar.addAction(self.actReloadMethods)
        
        self.toolBar.addWidget(self.spacer1)
        self.toolBar.addAction(self.actSwitch)
        self.toolBar.addWidget(self.spacer2)

        self.toolBar.addAction(self.actReloadMetaMethods)
        self.toolBar.addAction(self.actPostLoad)

        # main window
        self.grid = QGridLayout(self.mainFrame)
        self.grid.setColumnMinimumWidth(0, 70)
        self.grid.setColumnStretch(0, 0)
        self.grid.setColumnStretch(1, 1)

        self.methodList = QListWidget(self)
        self.methodList.itemDoubleClicked.connect(
            self.post_processor_clicked)
        self.update_post_method_list()
        self.metaMethodList = QListWidget(self)
        self.metaMethodList.itemDoubleClicked.connect(
            self.meta_processor_clicked)
        self.update_meta_method_list()

        self.sim_result_list = QListWidget(self)
        self.sim_results_changed.connect(self.update_result_list)
        self.results = []

        self.delShort = QShortcut(QKeySequence(Qt.Key_Delete),
                                  self.sim_result_list)
        self.delShort.activated.connect(self.remove_result_item)

        # figures
        self._figure_dict = {}
        self.figures_changed.connect(self.update_figure_lists)

        self.post_figure_list = QListWidget(self)
        self.post_figure_list.currentItemChanged.connect(
            self.current_figure_changed)
        self.meta_figure_list = QListWidget(self)
        self.meta_figure_list.currentItemChanged.connect(
            self.current_figure_changed)

        self.plotView = QWidget()
        self.lastFigure = None

        self.post_result_list = QListWidget(self)
        self.post_results_changed.connect(self.update_post_result_list)
        self.post_results = []
        self.delShortPost = QShortcut(QKeySequence(Qt.Key_Backspace),
                                      self.post_result_list)
        self.delShortPost.activated.connect(self.remove_post_result_item)

        # log dock
        self.logBox = QPlainTextEdit(self)
        self.logBox.setReadOnly(True)

        # init logger for logging box
        self.textLogger = PlainTextLogger(logging.INFO)
        self.textLogger.set_target_cb(self.logBox.appendPlainText)
        logging.getLogger().addHandler(self.textLogger)

        self.grid.addWidget(QLabel("Result Files:"), 0, 0)
        self.grid.addWidget(self.sim_result_list, 1, 0)
        self.grid.addWidget(QLabel("Postprocessors:"), 2, 0)
        self.grid.addWidget(self.methodList, 3, 0)
        self.grid.addWidget(QLabel("Figures:"), 4, 0)
        self.grid.addWidget(self.post_figure_list, 5, 0)
        self.grid.addWidget(QLabel("Selected Figure:"), 0, 1)
        self.grid.addWidget(QLabel("Postprocessor Files:"), 0, 2)
        self.grid.addWidget(self.post_result_list, 1, 2)
        self.grid.addWidget(QLabel("Metaprocessors:"), 2, 2)
        self.grid.addWidget(self.metaMethodList, 3, 2)
        self.grid.addWidget(QLabel("Figures:"), 4, 2)
        self.grid.addWidget(self.meta_figure_list, 5, 2)
        self.grid.addWidget(self.logBox, 6, 0, 1, 3)

        self.mainFrame.setLayout(self.grid)
        self.setCentralWidget(self.mainFrame)

        # status bar
        self.statusBar = QStatusBar(self)
        self.setStatusBar(self.statusBar)

    def load_result_files(self):
        path = self._settings.value("path/simulation_results")

        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFiles)
        dialog.setDirectory(path)
        dialog.setNameFilter("PyMoskito Result files (*.pmr)")

        if dialog.exec_():
            files = dialog.selectedFiles()
            for single_file in files:
                if single_file:
                    self._load_result_file(single_file)

    def _load_result_file(self, file_name):
        """
        loads a result file
        """
        self._logger.info("loading result file {}".format(file_name))
        with open(file_name.encode(), "rb") as f:
            self.results.append(pickle.load(f))

        self.sim_results_changed.emit()

    def update_result_list(self):
        self.sim_result_list.clear()
        for res in self.results:
            name = res["regime name"]
            self.sim_result_list.addItem(name)

    def remove_result_item(self):
        if self.sim_result_list.currentRow() >= 0:
            del self.results[self.sim_result_list.currentRow()]
            self.sim_result_list.takeItem(self.sim_result_list.currentRow())

    def load_post_result_files(self):
        path = self._settings.value("path/processing_results")

        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFiles)
        dialog.setDirectory(path)
        dialog.setNameFilter("Postprocessing Output files (*.pof)")

        if dialog.exec_():
            files = dialog.selectedFiles()
            for single_file in files:
                if single_file:
                    self._load_post_result_file(single_file)

    def _load_post_result_file(self, file_name):
        """
        loads a post-result file (.pof)
        """
        name = os.path.split(file_name)[-1][:-4]
        self._logger.info("loading result file {}".format(file_name))
        with open(file_name.encode(), "rb") as f:
            results = pickle.load(f)
            results.update({"name": name})
            self.post_results.append(results)

        self.post_results_changed.emit()

    def update_post_result_list(self):
        self.post_result_list.clear()
        for res in self.post_results:
            name = res["name"]
            self.post_result_list.addItem(name)

    def remove_post_result_item(self):
        if self.post_result_list.currentRow() >= 0:
            del self.post_results[self.post_result_list.currentRow()]
            self.post_result_list.takeItem(self.post_result_list.currentRow())

    def update_post_method_list(self):
        self.methodList.clear()
        modules = pm.get_registered_processing_modules(PostProcessingModule)
        for mod in modules:
            self.methodList.addItem(mod[1])

    def update_meta_method_list(self):
        self.metaMethodList.clear()
        modules = pm.get_registered_processing_modules(MetaProcessingModule)
        for mod in modules:
            self.metaMethodList.addItem(mod[1])

    def post_processor_clicked(self, item):
        self.run_processor(str(item.text()), "post")

    def meta_processor_clicked(self, item):
        self.run_processor(str(item.text()), "meta")

    def run_processor(self, name, processor_type):
        if processor_type == "post":
            result_files = self.results
            base_cls = PostProcessingModule
        elif processor_type == "meta":
            result_files = self.post_results
            base_cls = MetaProcessingModule
        else:
            self._logger.error("unknown processor type {0}".format(
                processor_type))
            raise ValueError("unknown processor type {0}".format(
                processor_type))

        if not result_files:
            self._logger.warning("run_processor() Error: no result file loaded")
            return

        processor_cls = pm.get_processing_module_class_by_name(base_cls, name)
        processor = processor_cls()

        figs = []
        try:
            self._logger.info("executing processor '{0}'".format(name))
            figs = processor.process(result_files)
        except Exception as err:
            self._logger.exception("Error in processor")

        self.figures_changed.emit(figs, processor_type)
        self._logger.info("finished postprocessing")

    def update_figure_lists(self, figures, target_type):
        # remove no longer needed elements
        for item, fig in [(key, val[0])
                          for key, val in self._figure_dict.items()
                          if val[1] == target_type]:
            if fig not in [new_fig["figure"] for new_fig in figures]:
                if target_type == "post":
                    old_item = self.post_figure_list.takeItem(
                        self.post_figure_list.row(item))
                    del old_item
                elif target_type == "meta":
                    old_item = self.meta_figure_list.takeItem(
                        self.meta_figure_list.row(item))
                    del old_item

                del self._figure_dict[item]

        # add new ones to internal storage
        for fig in figures:
            if fig["figure"] not in self._figure_dict.values():
                new_entry = [(fig["name"],
                              (QListWidgetItem(fig["name"]),
                               fig["figure"], target_type)
                              )]
                self._figure_dict.update(new_entry)

        # add to display
        for key, val in self._figure_dict.items():
            if val[2] == "post":
                self.post_figure_list.addItem(val[0])
            elif val[2] == "meta":
                self.meta_figure_list.addItem(val[0])

        self.post_figure_list.setCurrentItem(self.post_figure_list.item(0))
        self.meta_figure_list.setCurrentItem(self.meta_figure_list.item(0))

    def current_figure_changed(self, current_item, last_item=None):
        if current_item is None:
            return

        figures = self._figure_dict

        if self.lastFigure:
            self.grid.removeWidget(self.lastFigure)
            self.lastFigure.setVisible(False)

        if current_item.text() in figures:
            figure_widget = figures[current_item.text()][1]
            self.grid.addWidget(figure_widget, 1, 1, 5, 1)
            figure_widget.setVisible(True)
            self.lastFigure = figure_widget
        
    def switch_sides(self):
        self.displayLeft = not self.displayLeft
        if self.displayLeft:
            self.actSwitch.setIcon(QIcon(get_resource("left_mode.png")))
            self.post_figure_list.setFocus()
            self.current_figure_changed(self.post_figure_list.currentItem())
        else:
            self.actSwitch.setIcon(QIcon(get_resource("right_mode.png")))
            self.meta_figure_list.setFocus()
            self.current_figure_changed(self.meta_figure_list.currentItem())
Пример #49
0
class GlyphSetTab(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.name = self.tr("Glyph sets")

        self.defaultGlyphSetBox = QCheckBox(
            self.tr("Default glyph set:"), self)
        self.defaultGlyphSetDrop = QComboBox(self)
        self.defaultGlyphSetBox.toggled.connect(self.toggleGlyphSetDrop)

        self.glyphSetList = QListWidget(self)
        self.glyphSetList.setSortingEnabled(True)
        self.glyphSetContents = QPlainTextEdit(self)
        self.glyphSetList.currentItemChanged.connect(
            self.updateGlyphSetContents)
        self.glyphSetList.itemChanged.connect(self.renameGlyphSet)
        self._cachedName = None
        splitter = QSplitter(self)
        splitter.addWidget(self.glyphSetList)
        splitter.addWidget(self.glyphSetContents)
        self.addGlyphSetButton = QPushButton("+", self)
        self.addGlyphSetButton.clicked.connect(lambda: self.addGlyphSet())
        self.removeGlyphSetButton = QPushButton("−", self)
        self.removeGlyphSetButton.clicked.connect(self.removeGlyphSet)
        self.importButton = QPushButton(self.tr("Import"), self)
        importMenu = QMenu(self)
        importMenu.addAction(
            self.tr("Import from current font"), self.importFromCurrentFont)
        self.importButton.setMenu(importMenu)
        self.glyphListBox = QCheckBox(self.tr("Glyph list path:"), self)
        self.glyphListEdit = QLineEdit(self)
        self.glyphListEdit.setReadOnly(True)
        self.glyphListButton = QPushButton(self.tr("Browse…"), self)
        self.glyphListButton.clicked.connect(self.getGlyphList)
        # TODO: find correct solution for this and maybe make a widget w
        # setSizesToText()
        # http://stackoverflow.com/a/19502467/2037879
        textWidth = self.glyphListButton.fontMetrics().boundingRect(
            self.glyphListButton.text()).width() + 16
        self.glyphListButton.setMaximumWidth(textWidth)
        self.glyphListBox.toggled.connect(self.glyphListEdit.setEnabled)
        self.glyphListBox.toggled.connect(self.glyphListButton.setEnabled)

        firstLayout = QGridLayout()
        l = 0
        firstLayout.addWidget(self.defaultGlyphSetBox, l, 0, 1, 2)
        firstLayout.addWidget(self.defaultGlyphSetDrop, l, 3, 1, 3)
        l += 1
        firstLayout.addWidget(splitter, l, 0, 1, 6)
        l += 1
        firstLayout.addWidget(self.addGlyphSetButton, l, 0)
        firstLayout.addWidget(self.removeGlyphSetButton, l, 1)
        firstLayout.addWidget(self.importButton, l, 2)
        secondLayout = QHBoxLayout()
        secondLayout.addWidget(self.glyphListBox, 0)
        secondLayout.addWidget(self.glyphListEdit, 1)
        secondLayout.addWidget(self.glyphListButton, 2)
        mainLayout = QVBoxLayout(self)
        mainLayout.addLayout(firstLayout)
        mainLayout.addLayout(secondLayout)
        self.setLayout(mainLayout)

        self.readSettings()

    def addGlyphSet(self, glyphNames=[], glyphSetName=None):
        if glyphSetName is None:
            glyphSetName = self.tr("New glyph set")
        if glyphSetName in self.glyphSets:
            index = 1
            while "%s %d" % (glyphSetName, index) in self.glyphSets:
                index += 1
            glyphSetName = "%s %d" % (glyphSetName, index)
        self.glyphSets[glyphSetName] = glyphNames
        item = QListWidgetItem(glyphSetName, self.glyphSetList)
        item.setFlags(item.flags() | Qt.ItemIsEditable)
        self.glyphSetList.setCurrentItem(item)
        self.glyphSetList.editItem(item)
        self.removeGlyphSetButton.setEnabled(True)

    def removeGlyphSet(self):
        i = self.glyphSetList.currentRow()
        text = self.glyphSetList.takeItem(i).text()
        del self.glyphSets[text]
        if self.glyphSetList.count() < 2:
            self.removeGlyphSetButton.setEnabled(False)

    def renameGlyphSet(self):
        newKey = self.glyphSetList.currentItem()
        if newKey is None:
            return
        newKey = newKey.text()
        self.glyphSets[newKey] = self.glyphSets[self._cachedName]
        del self.glyphSets[self._cachedName]

    def importFromCurrentFont(self):
        font = QApplication.instance().currentFont()
        name = "%s %s" % (font.info.familyName, font.info.styleName)
        self.addGlyphSet(font.glyphOrder, name)

    def toggleGlyphSetDrop(self):
        sender = self.sender()
        self.defaultGlyphSetDrop.setEnabled(sender.isChecked())

    def updateGlyphSetContents(self, current, previous):
        # store content of the textEdit in the glyphSet dict
        if previous is not None:
            glyphNames = self.glyphSetContents.toPlainText().split()
            self.glyphSets[previous.text()] = glyphNames
        # now update the text edit to current glyphSet
        glyphSetName = current.text()
        text = " ".join(self.glyphSets[glyphSetName])
        self.glyphSetContents.setPlainText(text)
        # cache current name for renames
        self._cachedName = glyphSetName

    def getGlyphList(self):
        fileFormats = (
            self.tr("Text file {}").format("(*.txt)"),
            self.tr("All files {}").format("(*.*)"),
        )
        path, _ = QFileDialog.getOpenFileName(
            self, self.tr("Open File"), '', ";;".join(fileFormats)
        )
        if path:
            self.glyphListEdit.setText(path)

    def readSettings(self):
        defaultGlyphSet = settings.defaultGlyphSet()
        self.defaultGlyphSetBox.setChecked(len(defaultGlyphSet))

        self.glyphSets = settings.readGlyphSets()
        self.defaultGlyphSetDrop.clear()
        self.defaultGlyphSetDrop.addItems(self.glyphSets.keys())

        self.glyphSetList.clear()
        glyphSetNames = self.glyphSets.keys()
        # Normally we should be enforcing this rather decently in the interface
        # already
        if glyphSetNames:
            for glyphSetName in glyphSetNames:
                item = QListWidgetItem(glyphSetName, self.glyphSetList)
                item.setFlags(item.flags() | Qt.ItemIsEditable)
            self.glyphSetList.setCurrentRow(0)
        self.removeGlyphSetButton.setEnabled(len(self.glyphSets) > 1)

        glyphListPath = settings.glyphListPath()
        self.glyphListBox.setChecked(bool(glyphListPath))
        self.glyphListEdit.setEnabled(bool(glyphListPath))
        self.glyphListEdit.setText(glyphListPath)
        self.glyphListButton.setEnabled(bool(glyphListPath))

    def writeSettings(self):
        # store content of the textEdit in the glyphSet dict
        glyphNames = self.glyphSetContents.toPlainText().split()
        currentGlyphSet = self.glyphSetList.currentItem().text()
        self.glyphSets[currentGlyphSet] = glyphNames

        settings.writeGlyphSets(self.glyphSets)
        if not self.defaultGlyphSetBox.isChecked():
            settings.setDefaultGlyphSet(None)
        else:
            defaultGlyphSet = self.defaultGlyphSetDrop.currentText()
            settings.setDefaultGlyphSet(defaultGlyphSet)
        if not self.glyphListBox.isChecked():
            settings.setGlyphListPath(None)
        else:
            glyphListPath = self.glyphListEdit.text()
            if glyphListPath:
                settings.setGlyphListPath(glyphListPath)
                QApplication.instance().loadGlyphList()
Пример #50
0
class PostProcessor(QMainWindow):

    sim_results_changed = pyqtSignal()
    post_results_changed = pyqtSignal()

    figures_changed = pyqtSignal(list, str)

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self._settings = QSettings()
        self._logger = logging.getLogger(self.__class__.__name__)

        self.setWindowTitle("Processing")
        self.setWindowIcon(QIcon(get_resource("processing.png")))
        self.mainFrame = QWidget(self)
        self.resize(1000, 600)

        # toolbar
        self.toolBar = QToolBar("file control")
        self.toolBar.setIconSize(QSize(24, 24))
        self.addToolBar(self.toolBar)

        self.actLoad = QAction(self)
        self.actLoad.setText("load result file")
        self.actLoad.setIcon(QIcon(get_resource("load.png")))
        self.actLoad.setDisabled(False)
        self.actLoad.triggered.connect(self.load_result_files)

        self.actPostLoad = QAction(self)
        self.actPostLoad.setText("load post-result file")
        self.actPostLoad.setIcon(QIcon(get_resource("load.png")))
        self.actPostLoad.setDisabled(False)
        self.actPostLoad.triggered.connect(self.load_post_result_files)

        self.actSwitch = QAction(self)
        self.actSwitch.setText("switch display mode")
        self.actSwitch.setIcon(QIcon(get_resource("left_mode.png")))
        self.actSwitch.setDisabled(False)
        self.actSwitch.triggered.connect(self.switch_sides)
        self.displayLeft = True

        self.spacer1 = QWidget()
        self.spacer2 = QWidget()
        self.spacer1.setSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        self.spacer2.setSizePolicy(QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)

        self.actReloadMethods = QAction(self)
        self.actReloadMethods.setText("reload methods")
        self.actReloadMethods.setIcon(QIcon(get_resource("reload.png")))
        self.actReloadMethods.setDisabled(False)
        self.actReloadMethods.triggered.connect(self.update_post_method_list)

        self.actReloadMetaMethods = QAction(self)
        self.actReloadMetaMethods.setText("reload meta methods")
        self.actReloadMetaMethods.setIcon(QIcon(get_resource("reload.png")))
        self.actReloadMetaMethods.setDisabled(False)
        self.actReloadMetaMethods.triggered.connect(
            self.update_meta_method_list)

        self.toolBar.addAction(self.actLoad)
        self.toolBar.addAction(self.actReloadMethods)

        self.toolBar.addWidget(self.spacer1)
        self.toolBar.addAction(self.actSwitch)
        self.toolBar.addWidget(self.spacer2)

        self.toolBar.addAction(self.actReloadMetaMethods)
        self.toolBar.addAction(self.actPostLoad)

        # main window
        self.grid = QGridLayout(self.mainFrame)
        self.grid.setColumnMinimumWidth(0, 70)
        self.grid.setColumnStretch(0, 0)
        self.grid.setColumnStretch(1, 1)

        self.methodList = QListWidget(self)
        self.methodList.itemDoubleClicked.connect(self.post_processor_clicked)
        self.update_post_method_list()
        self.metaMethodList = QListWidget(self)
        self.metaMethodList.itemDoubleClicked.connect(
            self.meta_processor_clicked)
        self.update_meta_method_list()

        self.sim_result_list = QListWidget(self)
        self.sim_results_changed.connect(self.update_result_list)
        self.results = []

        self.delShort = QShortcut(QKeySequence(Qt.Key_Delete),
                                  self.sim_result_list)
        self.delShort.activated.connect(self.remove_result_item)

        # figures
        self._figure_dict = {}
        self.figures_changed.connect(self.update_figure_lists)

        self.post_figure_list = QListWidget(self)
        self.post_figure_list.currentItemChanged.connect(
            self.current_figure_changed)
        self.meta_figure_list = QListWidget(self)
        self.meta_figure_list.currentItemChanged.connect(
            self.current_figure_changed)

        self.plotView = QWidget()
        self.lastFigure = None

        self.post_result_list = QListWidget(self)
        self.post_results_changed.connect(self.update_post_result_list)
        self.post_results = []
        self.delShortPost = QShortcut(QKeySequence(Qt.Key_Backspace),
                                      self.post_result_list)
        self.delShortPost.activated.connect(self.remove_post_result_item)

        # log dock
        self.logBox = QPlainTextEdit(self)
        self.logBox.setReadOnly(True)

        # init logger for logging box
        self.textLogger = PlainTextLogger(logging.INFO)
        self.textLogger.set_target_cb(self.logBox.appendPlainText)
        logging.getLogger().addHandler(self.textLogger)

        self.grid.addWidget(QLabel("Result Files:"), 0, 0)
        self.grid.addWidget(self.sim_result_list, 1, 0)
        self.grid.addWidget(QLabel("Postprocessors:"), 2, 0)
        self.grid.addWidget(self.methodList, 3, 0)
        self.grid.addWidget(QLabel("Figures:"), 4, 0)
        self.grid.addWidget(self.post_figure_list, 5, 0)
        self.grid.addWidget(QLabel("Selected Figure:"), 0, 1)
        self.grid.addWidget(QLabel("Postprocessor Files:"), 0, 2)
        self.grid.addWidget(self.post_result_list, 1, 2)
        self.grid.addWidget(QLabel("Metaprocessors:"), 2, 2)
        self.grid.addWidget(self.metaMethodList, 3, 2)
        self.grid.addWidget(QLabel("Figures:"), 4, 2)
        self.grid.addWidget(self.meta_figure_list, 5, 2)
        self.grid.addWidget(self.logBox, 6, 0, 1, 3)

        self.mainFrame.setLayout(self.grid)
        self.setCentralWidget(self.mainFrame)

        # status bar
        self.statusBar = QStatusBar(self)
        self.setStatusBar(self.statusBar)

    def load_result_files(self):
        path = self._settings.value("path/simulation_results")

        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFiles)
        dialog.setDirectory(path)
        dialog.setNameFilter("PyMoskito Result files (*.pmr)")

        if dialog.exec_():
            files = dialog.selectedFiles()
            for single_file in files:
                if single_file:
                    self._load_result_file(single_file)

    def _load_result_file(self, file_name):
        """
        loads a result file
        """
        self._logger.info("loading result file {}".format(file_name))
        with open(file_name.encode(), "rb") as f:
            self.results.append(pickle.load(f))

        self.sim_results_changed.emit()

    def update_result_list(self):
        self.sim_result_list.clear()
        for res in self.results:
            name = res["regime name"]
            self.sim_result_list.addItem(name)

    def remove_result_item(self):
        if self.sim_result_list.currentRow() >= 0:
            del self.results[self.sim_result_list.currentRow()]
            self.sim_result_list.takeItem(self.sim_result_list.currentRow())

    def load_post_result_files(self):
        path = self._settings.value("path/processing_results")

        dialog = QFileDialog(self)
        dialog.setFileMode(QFileDialog.ExistingFiles)
        dialog.setDirectory(path)
        dialog.setNameFilter("Postprocessing Output files (*.pof)")

        if dialog.exec_():
            files = dialog.selectedFiles()
            for single_file in files:
                if single_file:
                    self._load_post_result_file(single_file)

    def _load_post_result_file(self, file_name):
        """
        loads a post-result file (.pof)
        """
        name = os.path.split(file_name)[-1][:-4]
        self._logger.info("loading result file {}".format(file_name))
        with open(file_name.encode(), "rb") as f:
            results = pickle.load(f)
            results.update({"name": name})
            self.post_results.append(results)

        self.post_results_changed.emit()

    def update_post_result_list(self):
        self.post_result_list.clear()
        for res in self.post_results:
            name = res["name"]
            self.post_result_list.addItem(name)

    def remove_post_result_item(self):
        if self.post_result_list.currentRow() >= 0:
            del self.post_results[self.post_result_list.currentRow()]
            self.post_result_list.takeItem(self.post_result_list.currentRow())

    def update_post_method_list(self):
        self.methodList.clear()
        modules = pm.get_registered_processing_modules(PostProcessingModule)
        for mod in modules:
            self.methodList.addItem(mod[1])

    def update_meta_method_list(self):
        self.metaMethodList.clear()
        modules = pm.get_registered_processing_modules(MetaProcessingModule)
        for mod in modules:
            self.metaMethodList.addItem(mod[1])

    def post_processor_clicked(self, item):
        self.run_processor(str(item.text()), "post")

    def meta_processor_clicked(self, item):
        self.run_processor(str(item.text()), "meta")

    def run_processor(self, name, processor_type):
        if processor_type == "post":
            result_files = self.results
            base_cls = PostProcessingModule
        elif processor_type == "meta":
            result_files = self.post_results
            base_cls = MetaProcessingModule
        else:
            self._logger.error(
                "unknown processor type {0}".format(processor_type))
            raise ValueError(
                "unknown processor type {0}".format(processor_type))

        if not result_files:
            self._logger.warning(
                "run_processor() Error: no result file loaded")
            return

        processor_cls = pm.get_processing_module_class_by_name(base_cls, name)
        processor = processor_cls()

        figs = []
        try:
            self._logger.info("executing processor '{0}'".format(name))
            figs = processor.process(result_files)
        except Exception as err:
            self._logger.exception("Error in processor")

        self.figures_changed.emit(figs, processor_type)
        self._logger.info("finished postprocessing")

    def update_figure_lists(self, figures, target_type):
        # remove no longer needed elements
        for item, fig in [(key, val[0])
                          for key, val in self._figure_dict.items()
                          if val[1] == target_type]:
            if fig not in [new_fig["figure"] for new_fig in figures]:
                if target_type == "post":
                    old_item = self.post_figure_list.takeItem(
                        self.post_figure_list.row(item))
                    del old_item
                elif target_type == "meta":
                    old_item = self.meta_figure_list.takeItem(
                        self.meta_figure_list.row(item))
                    del old_item

                del self._figure_dict[item]

        # add new ones to internal storage
        for fig in figures:
            if fig["figure"] not in self._figure_dict.values():
                new_entry = [(fig["name"], (QListWidgetItem(fig["name"]),
                                            fig["figure"], target_type))]
                self._figure_dict.update(new_entry)

        # add to display
        for key, val in self._figure_dict.items():
            if val[2] == "post":
                self.post_figure_list.addItem(val[0])
            elif val[2] == "meta":
                self.meta_figure_list.addItem(val[0])

        self.post_figure_list.setCurrentItem(self.post_figure_list.item(0))
        self.meta_figure_list.setCurrentItem(self.meta_figure_list.item(0))

    def current_figure_changed(self, current_item, last_item=None):
        if current_item is None:
            return

        figures = self._figure_dict

        if self.lastFigure:
            self.grid.removeWidget(self.lastFigure)
            self.lastFigure.setVisible(False)

        if current_item.text() in figures:
            figure_widget = figures[current_item.text()][1]
            self.grid.addWidget(figure_widget, 1, 1, 5, 1)
            figure_widget.setVisible(True)
            self.lastFigure = figure_widget

    def switch_sides(self):
        self.displayLeft = not self.displayLeft
        if self.displayLeft:
            self.actSwitch.setIcon(QIcon(get_resource("left_mode.png")))
            self.post_figure_list.setFocus()
            self.current_figure_changed(self.post_figure_list.currentItem())
        else:
            self.actSwitch.setIcon(QIcon(get_resource("right_mode.png")))
            self.meta_figure_list.setFocus()
            self.current_figure_changed(self.meta_figure_list.currentItem())
Пример #51
0
class ErrorsWidget(QWidget):

###############################################################################
# ERRORS WIDGET SIGNALS
###############################################################################
    """
    pep8Activated(bool)
    lintActivated(bool)
    """

    pep8Activated = pyqtSignal(bool)
    lintActivated = pyqtSignal(bool)

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

    def __init__(self):
        super(ErrorsWidget, self).__init__()
        self.pep8 = None
        self._outRefresh = True

        vbox = QVBoxLayout(self)
        self.listErrors = QListWidget()
        self.listErrors.setSortingEnabled(True)
        self.listPep8 = QListWidget()
        self.listPep8.setSortingEnabled(True)
        hbox_lint = QHBoxLayout()
        if settings.FIND_ERRORS:
            self.btn_lint_activate = QPushButton(_translate("ErrorsWidget", "Lint: ON"))
        else:
            self.btn_lint_activate = QPushButton(_translate("ErrorsWidget", "Lint: OFF"))
        self.errorsLabel = QLabel(_translate("ErrorsWidget", "Static Errors: %s") % 0)
        hbox_lint.addWidget(self.errorsLabel)
        hbox_lint.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox_lint.addWidget(self.btn_lint_activate)
        vbox.addLayout(hbox_lint)
        vbox.addWidget(self.listErrors)
        hbox_pep8 = QHBoxLayout()
        if settings.CHECK_STYLE:
            self.btn_pep8_activate = QPushButton(_translate("ErrorsWidget", "PEP8: ON"))
        else:
            self.btn_pep8_activate = QPushButton(_translate("ErrorsWidget", "PEP8: OFF"))
        self.pep8Label = QLabel(_translate("ErrorsWidget", "PEP8 Errors: %s") % 0)
        hbox_pep8.addWidget(self.pep8Label)
        hbox_pep8.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox_pep8.addWidget(self.btn_pep8_activate)
        vbox.addLayout(hbox_pep8)
        vbox.addWidget(self.listPep8)

        self.listErrors.itemSelectionChanged.connect(self.errors_selected)
        self.listPep8.itemSelectionChanged.connect(self.pep8_selected)
        self.btn_lint_activate.clicked['bool'].connect(self.errors_selected)
        self.btn_pep8_activate.clicked['bool'].connect(self._turn_on_off_pep8)

    def _turn_on_off_lint(self):
        """Change the status of the lint checker state."""
        settings.FIND_ERRORS = not settings.FIND_ERRORS
        if settings.FIND_ERRORS:
            self.btn_lint_activate.setText(_translate("ErrorsWidget", "Lint: ON"))
        else:
            self.btn_lint_activate.setText(_translate("ErrorsWidget", "Lint: OFF"))
        self.lintActivated.emit(settings.FIND_ERRORS)

    def _turn_on_off_pep8(self):
        """Change the status of the lint checker state."""
        settings.CHECK_STYLE = not settings.CHECK_STYLE
        if settings.CHECK_STYLE:
            self.btn_pep8_activate.setText(_translate("ErrorsWidget", "PEP8: ON"))
        else:
            self.btn_pep8_activate.setText(_translate("ErrorsWidget", "PEP8: OFF"))
        self.pep8Activated.emit(settings.CHECK_STYLE)

    def errors_selected(self):
        editorWidget = main_container.MainContainer().get_actual_editor()
        if editorWidget and self._outRefresh:
            lineno = int(self.listErrors.currentItem().data(Qt.UserRole))
            editorWidget.jump_to_line(lineno)
            editorWidget.setFocus()

    def pep8_selected(self):
        editorWidget = main_container.MainContainer().get_actual_editor()
        if editorWidget and self._outRefresh:
            lineno = int(self.listPep8.currentItem().data(Qt.UserRole))
            editorWidget.jump_to_line(lineno)
            editorWidget.setFocus()

    def refresh_lists(self, errors, pep8):
        self._outRefresh = False
        self.listErrors.clear()
        self.listPep8.clear()
        for lineno in errors.errorsSummary:
            linenostr = 'L%s\t' % str(lineno + 1)
            for data in errors.errorsSummary[lineno]:
                item = QListWidgetItem(linenostr + data)
                item.setToolTip(linenostr + data)
                item.setData(Qt.UserRole, lineno)
                self.listErrors.addItem(item)
        self.errorsLabel.setText(_translate("ErrorsWidget", "Static Errors: %s") %
            len(errors.errorsSummary))
        for lineno in pep8.pep8checks:
            linenostr = 'L%s\t' % str(lineno + 1)
            for data in pep8.pep8checks[lineno]:
                item = QListWidgetItem(linenostr + data.split('\n')[0])
                item.setToolTip(linenostr + data.split('\n')[0])
                item.setData(Qt.UserRole, lineno)
                self.listPep8.addItem(item)
        self.pep8Label.setText(_translate("ErrorsWidget", "PEP8 Errors: %s") %
            len(pep8.pep8checks))
        self._outRefresh = True

    def clear(self):
        """
        Clear the widget
        """
        self.listErrors.clear()
        self.listPep8.clear()
Пример #52
0
class ErrorsWidget(QDialog):

    ###############################################################################
    # ERRORS WIDGET SIGNALS
    ###############################################################################
    """
    pep8Activated(bool)
    lintActivated(bool)
    """
    pep8Activated = pyqtSignal(bool)
    lintActivated = pyqtSignal(bool)
    dockWidget = pyqtSignal("QObject*")
    undockWidget = pyqtSignal()
    changeTitle = pyqtSignal(str)

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

    def __init__(self, parent=None):
        super(ErrorsWidget, self).__init__(parent, Qt.WindowStaysOnTopHint)
        self.pep8 = None
        self._outRefresh = True

        vbox = QVBoxLayout(self)
        self.listErrors = QListWidget()
        self.listErrors.setSortingEnabled(True)
        self.listPep8 = QListWidget()
        self.listPep8.setSortingEnabled(True)
        hbox_lint = QHBoxLayout()
        if settings.FIND_ERRORS:
            self.btn_lint_activate = QPushButton(self.tr("Lint: ON"))
        else:
            self.btn_lint_activate = QPushButton(self.tr("Lint: OFF"))
        self.errorsLabel = QLabel(self.tr("Static Errors: %s") % 0)
        hbox_lint.addWidget(self.errorsLabel)
        hbox_lint.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox_lint.addWidget(self.btn_lint_activate)
        vbox.addLayout(hbox_lint)
        vbox.addWidget(self.listErrors)
        hbox_pep8 = QHBoxLayout()
        if settings.CHECK_STYLE:
            self.btn_pep8_activate = QPushButton(self.tr("PEP8: ON"))
        else:
            self.btn_pep8_activate = QPushButton(self.tr("PEP8: OFF"))
        self.pep8Label = QLabel(self.tr("PEP8 Errors: %s") % 0)
        hbox_pep8.addWidget(self.pep8Label)
        hbox_pep8.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox_pep8.addWidget(self.btn_pep8_activate)
        vbox.addLayout(hbox_pep8)
        vbox.addWidget(self.listPep8)

        self.listErrors.itemClicked['QListWidgetItem*'].connect(
            self.errors_selected)
        # self.listErrors.itemActivated['QListWidgetItem*'].connect(self.errors_selected)
        self.listPep8.itemClicked['QListWidgetItem*'].connect(
            self.pep8_selected)
        # self.listPep8.itemActivated['QListWidgetItem*'].connect(self.pep8_selected)
        self.btn_lint_activate.clicked['bool'].connect(self._turn_on_off_lint)
        self.btn_pep8_activate.clicked['bool'].connect(self._turn_on_off_pep8)

        IDE.register_service('tab_errors', self)
        ExplorerContainer.register_tab(translations.TR_TAB_ERRORS, self)

    def install_tab(self):
        ide = IDE.getInstance()
        ide.goingDown.connect(self.close)

    def _turn_on_off_lint(self):
        """Change the status of the lint checker state."""
        settings.FIND_ERRORS = not settings.FIND_ERRORS
        if settings.FIND_ERRORS:
            self.btn_lint_activate.setText(self.tr("Lint: ON"))
            self.listErrors.show()
        else:
            self.btn_lint_activate.setText(self.tr("Lint: OFF"))
            self.listErrors.hide()
        self.lintActivated.emit(settings.FIND_ERRORS)

    def _turn_on_off_pep8(self):
        """Change the status of the lint checker state."""
        settings.CHECK_STYLE = not settings.CHECK_STYLE
        if settings.CHECK_STYLE:
            self.btn_pep8_activate.setText(self.tr("PEP8: ON"))
            self.listPep8.show()
        else:
            self.btn_pep8_activate.setText(self.tr("PEP8: OFF"))
            self.listPep8.hide()
        self.pep8Activated.emit(settings.CHECK_STYLE)

    def errors_selected(self):
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            if editorWidget and self._outRefresh:
                lineno = int(self.listErrors.currentItem().data(Qt.UserRole))
                editorWidget.jump_to_line(lineno)
                editorWidget.setFocus()

    def pep8_selected(self):
        main_container = IDE.get_service('main_container')
        if main_container:
            editorWidget = main_container.get_current_editor()
            if editorWidget and self._outRefresh:
                lineno = int(self.listPep8.currentItem().data(Qt.UserRole))
                editorWidget.jump_to_line(lineno)
                editorWidget.setFocus()

    def refresh_pep8_list(self, pep8):
        self._outRefresh = False
        self.listPep8.clear()
        for lineno in pep8:
            linenostr = 'L%s\t' % str(lineno + 1)
            for data in pep8[lineno]:
                item = QListWidgetItem(linenostr + data.split('\n')[0])
                item.setToolTip(linenostr + data.split('\n')[0])
                item.setData(Qt.UserRole, lineno)
                self.listPep8.addItem(item)
        self.pep8Label.setText(self.tr("PEP8 Errors: %s") % len(pep8))
        self._outRefresh = True

    def refresh_error_list(self, errors):
        self._outRefresh = False
        self.listErrors.clear()
        for lineno in errors:
            linenostr = 'L%s\t' % str(lineno + 1)
            for data in errors[lineno]:
                item = QListWidgetItem(linenostr + data)
                item.setToolTip(linenostr + data)
                item.setData(Qt.UserRole, lineno)
                self.listErrors.addItem(item)
        self.errorsLabel.setText(self.tr("Static Errors: %s") % len(errors))
        self._outRefresh = True

    def clear(self):
        """
        Clear the widget
        """
        self.listErrors.clear()
        self.listPep8.clear()

    def reject(self):
        if self.parent() is None:
            self.dockWidget.emit(self)

    def closeEvent(self, event):
        self.dockWidget.emit(self)
        event.ignore()
Пример #53
0
class DebuggerMainWindow(object):
    def __init__(self, comm):
        self.comm = comm
        self.follow_state = True
        self.init_instances()
        self.init_widgets()
        self.init_actions()
        self.window.closeEvent = self.close_handler
        self.window.showMaximized()

    def run(self):
        self.poll_timer = QTimer()
        self.poll_timer.timeout.connect(self.poll_handler)
        self.comm.start_worker()
        self.poll_timer.start(1000)

    def poll_handler(self):
        self.comm.put_job(self.comm.get_agent_track)
        data = self.comm.take_data()
        for location_info, state in data:
            file_name, node_id = location_info
            i = self.get_instance(file_name)

            if i is None:
                text = "%s:%s" % (str(location_info), state)
            else:
                node = i.model.get_node(node_id)
                if node is not None:
                    text = "%s: %s: %s" % (file_name, node.get_display_text(), state)
                else:
                    text = "%s:%s" % (str(location_info), state)
            self.add_to_history_list(location_info, text)
        if self.follow_state:
            self.focus_last()

    def init_widgets(self):
        self.window = loadUi(MAIN_UI_PATH)
        self.mdi = self.window.mdiArea
        self.mdi.setViewMode(QMdiArea.TabbedView)
        self.mdi.setTabsMovable(True)
        self.mdi.setTabsClosable(True)
        self.mdi.setTabShape(QTabWidget.Rounded)
        self.dock_anchor = self.window.dockAnchor
        self.dock_anchor.layout().setAlignment(Qt.AlignTop)

        self.history_list = QListWidget()
        self.history_list.itemSelectionChanged.connect(self.list_item_selected)
        self.add_dock_content(self.history_list)

    def list_item_selected(self):
        citem = self.history_list.currentItem()
        self.focus_on_location(citem.location_info)

    def init_instances(self):
        self.instances = {}

    def remove_instance(self, ins):
        file_name = ins.file_name
        self.instances.pop(file_name)

    def add_instance(self, ins):
        file_name = ins.file_name
        self.instances[file_name] = ins

    def get_instance(self, file_name):
        if file_name in self.instances:
            return self.instances[file_name]
        else:
            full_path = GraphInstanceVM.get_full_path(file_name)
            model = GraphInstanceVM.get_model(full_path)
            if model is None:
                return None
            ins = GraphInstanceVM(model, self, file_name)
            return ins

    def init_actions(self):
        self.window.actionResume.triggered.connect(self.action_resume_handler)
        self.window.actionStop.triggered.connect(self.action_stop_handler)
        self.window.actionFollow.triggered.connect(self.action_follow_handler)
        self.window.actionHold.triggered.connect(self.action_hold_handler)

    def action_resume_handler(self):
        self.clear_list()
        self.comm.put_job(functools.partial(self.comm.track_agent, True))

    def action_stop_handler(self):
        self.comm.put_job(functools.partial(self.comm.track_agent, False))

    def action_follow_handler(self):
        self.follow_state = True

    def action_hold_handler(self):
        self.follow_state = False

    def close_handler(self, ev):
        # disable tracking for some agents
        self.poll_timer.stop()
        self.comm.put_job(self.comm.finish)
        self.comm.shutdown()

    def add_dock_content(self, widget):
        self.clear_dock_contents()
        self.dock_anchor.layout().addWidget(widget)

    def get_dock_contents(self):
        l = self.dock_anchor.layout()
        ret = []
        for i in range(l.count()):
            ret.append(l.itemAt(i).widget())
        return ret

    def clear_dock_contents(self):
        ws = self.get_dock_contents()
        for w in ws:
            w.deleteLater()

    def focus_on_location(self, location):
        file_name, node_id = location
        instance = self.get_instance(file_name)
        if instance is None:
            logger.fatal("can not find src file for %s" % file_name)
            return False
        ret = instance.focus_on(node_id)
        if ret is False:
            logger.fatal("can not find node %s for %s" % (node_id, file_name))
            return False
        return True

    def add_to_history_list(self, location, text):
        item = HistoryListItem(location, text)
        self.history_list.addItem(item)

    def clear_list(self):
        self.history_list.clear()

    def focus_last(self):
        c = self.history_list.count()
        if c > 0:
            item = self.history_list.item(c-1)
            self.history_list.setCurrentItem(item)
            self.focus_on_location(item.location_info)
class Widget(QWidget):
    def __init__(self, gtoAction, parent=None):
        super(Widget, self).__init__(parent)
        # from gtoAction
        self.gtomain = gtoAction.gtomain
        self.info = gtoAction.info
        self.debug = gtoAction.debug
        try:
            # from main
            self.helper = self.gtomain.helper
            self.iface = self.gtomain.iface
            self.metadata = self.gtomain.metadata
            self.prj = self.gtomain.prj
            self.canvas = self.iface.mapCanvas()
            # tooldata
            self.config = gtoAction.config
            self.tools = gtoAction.tools
            self.layers = self.config.get('layers', None)

            # load ui
            uic.loadUi(
                os.path.join(os.path.dirname(__file__), 'gto_expression.ui'),
                self)
            self.btnOk.clicked.connect(lambda: self.EvalExpr(
                self.lblLayer.text(), self.lblExpr.text()))
            self.btnDelete.clicked.connect(self.deleteEntry)
            self.btnNew.clicked.connect(self.newEntry)

            self.cboQuieries.currentIndexChanged.connect(self.setData)

            self.loadData()
            self.setData()

        except Exception as e:
            self.info.err(e)

    def setIconSizes(self, toolbar):
        try:
            btns = self.findChildren(QToolButton)
            for btn in btns:
                btn.setIconSize(self.iface.iconSize())
        except Exception as e:
            self.info.err(e)

    def reset(self, *args):  # from gtotoolbar before cleared
        try:
            if self.debug: self.info.log("widget reset")
        except Exception as e:
            self.info.err(e)

    def newEntry(self):
        try:
            if self.selectLayer() == QDialog.Accepted:
                ok, sql = self.showQueryBuilder(self.iface.activeLayer(),
                                                False)
                if ok and sql:
                    newName, ok = QInputDialog().getText(
                        self, 'Neue Abfrage', "Name:")
                    if newName and ok:
                        if not self.cboQuieries.findText(
                                newName, Qt.MatchExactly):
                            self.info("Abfrage <%s> existiert bereits!" %
                                      newName)
                        else:
                            self.cboQuieries.addItem(
                                newName,
                                [sql, self.iface.activeLayer().name()])
                            self.cboQuieries.setCurrentIndex(
                                self.cboQuieries.findText(
                                    newName, Qt.MatchExactly))
                            if self.debug:
                                self.info.log(self.cboQuieries.currentData())
                            self.saveData()
        except Exception as e:
            self.info.err(e)

    def loadData(self):
        try:
            file = os.path.join(self.metadata.dirGTO, 'expressions.txt')
            if self.debug: self.info.log("Data file:", file)
            if os.path.isfile(file):
                f = open(file, 'r')
                content = f.readlines()
                for line in content:
                    try:
                        data = line.split('|')
                        self.cboQuieries.addItem(data[0], [data[1], data[2]])
                    except Exception as e:
                        self.info.err(e)
                f.close()
                os.remove(file)
                if self.debug: self.info.log("File data:", content)
            else:
                # json
                file = os.path.join(self.metadata.dirGTO, 'expressions.json')
                data = self.helper.readJson(file)
                if data is not None:
                    for k in data.keys():
                        v = data[k]
                        if self.debug: self.info.log(k, v)
                        self.cboQuieries.addItem(k,
                                                 [v["expression"], v["layer"]])
            self.cboQuieries.repaint()
        except Exception as e:
            self.info.err(e)

    def deleteEntry(self):
        try:
            if self.info.gtoQuestion(
                    'Abfrage <{0}> löschen?'.format(
                        self.cboQuieries.currentText()),
                    "Abfrage löschen") == QMessageBox.Yes:
                self.cboQuieries.removeItem(self.cboQuieries.currentIndex())
                if self.cboQuieries.count() == 0:
                    self.lblLayer.setText('')
                    self.lblExpr.setText('')
                self.saveData()
        except Exception as e:
            self.info.err(e)

    def saveData(self):
        try:
            file = os.path.join(self.metadata.dirGTO, 'expressions.json')
            if self.debug: self.info.log("saveData:", file)
            data = {}
            for i in range(self.cboQuieries.count()):
                idata = self.cboQuieries.itemData(i)
                data[self.cboQuieries.itemText(i)] = {
                    "layer": idata[1],
                    "expression": idata[0]
                }
            if self.debug: self.info.log("saveData", data)
            if os.path.isfile(file): os.remove(file)
            self.helper.writeJson(file, data)
        except Exception as e:
            self.info.err(e)

    def setData(self):
        try:
            data = self.cboQuieries.currentData()
            if data:
                expr = data[0]
                layname = data[1]
                self.lblLayer.setText(layname)
                self.lblExpr.setText(expr)
        except Exception as e:
            self.info.err(e)

    def EvalExpr(self, layername, expr):
        try:
            index = self.cboQuieries.currentIndex()
            layer = self.prj.mapLayersByName(layername)[0]
            context = QgsExpressionContext()
            scope = QgsExpressionContextScope()
            context.appendScope(scope)
            listOfResults = []
            features = [feat for feat in layer.getFeatures()]
            for feat in features:
                scope.setFeature(feat)
                exp = QgsExpression(expr)
                if exp.evaluate(context):
                    listOfResults.append(feat.id())
            if len(listOfResults) == 0:
                self.info.msg('Kein Ergebnis!')
            else:
                layer.selectByIds(listOfResults)
                self.iface.setActiveLayer(layer)
                self.gtomain.runcmd(self.tools)
            self.cboQuieries.setCurrentIndex(index)
        except Exception as e:
            self.info.err(e)

    def showQueryBuilder(self, layer, filter, sql=None):
        try:
            if not layer: layer = self.iface.activeLayer()
            self.query_builder = QgsQueryBuilder(layer,
                                                 self.iface.mainWindow())
            if sql: self.query_builder.setSql(sql)
            self.query_builder.accept()
            result = self.query_builder.exec_()
            if self.debug:
                self.info.log("QueryBuilder", self.query_builder.sql(), result,
                              layer.subsetString())
            if not filter: layer.setSubsetString(None)
            return result, self.query_builder.sql()
        except Exception as e:
            self.info.err(e)

    def selectLayer(self, editable=False):
        try:
            self.dlgLayers = QDialog(self.iface.mainWindow())
            self.dlgLayers.setWindowTitle('Neue Abfrage')
            self.lay = QVBoxLayout(self.dlgLayers)
            self.lay.addWidget(QLabel("Layerauswahl:"))
            self.LayerList = QListWidget()
            self.lay.addWidget(self.LayerList)
            self.btnBox = QDialogButtonBox(self.dlgLayers)
            self.btnBox.setStandardButtons(QDialogButtonBox.Cancel
                                           | QDialogButtonBox.Ok)
            self.lay.addWidget(self.btnBox)
            if self.layers != None:
                for ml in self.layers:
                    try:
                        lay = self.prj.mapLayersByName(ml)[0]
                        item = QListWidgetItem(lay.name())
                        self.LayerList.addItem(item)
                    except:
                        pass
            else:
                vectorLayers = [
                    layer for layer in self.iface.mapCanvas().layers()
                ]
                for ml in vectorLayers:
                    self.info.log(type(ml))
                    if isinstance(ml, QgsVectorLayer):
                        item = QListWidgetItem(ml.name())
                        self.LayerList.addItem(item)
            if self.iface.activeLayer():
                items = self.LayerList.findItems(
                    self.iface.activeLayer().name(), Qt.MatchExactly)
                if len(items) > 0:
                    self.LayerList.setCurrentItem(items[0])
            self.btnBox.accepted.connect(self.setActiveLayer)
            self.btnBox.rejected.connect(self.dlgLayers.reject)
            return self.dlgLayers.exec_()
        except Exception as e:
            self.info.err((e))

    def setActiveLayer(self):
        try:
            lay = self.LayerList.currentItem().text()
            lay = self.prj.mapLayersByName(lay)[0]
            self.iface.setActiveLayer(lay)
            self.dlgLayers.accept()
        except Exception as e:
            self.info.err((e))
Пример #55
0
class CollectionCueSettings(SettingsPage):
    Name = 'Edit Collection'

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.setLayout(QVBoxLayout(self))

        self.cuesWidget = QListWidget(self)
        self.cuesWidget.setAlternatingRowColors(True)
        self.layout().addWidget(self.cuesWidget)

        # Buttons
        self.dialogButtons = QDialogButtonBox(self)
        self.dialogButtons.setSizePolicy(QSizePolicy.Minimum,
                                         QSizePolicy.Minimum)
        self.layout().addWidget(self.dialogButtons)

        self.addButton = self.dialogButtons.addButton('Add', QDialogButtonBox.ActionRole)
        self.addButton.clicked.connect(self._add_dialog)

        self.delButton = self.dialogButtons.addButton('Remove', QDialogButtonBox.ActionRole)
        self.delButton.clicked.connect(self._remove_selected)

        self.cue_dialog = CueListDialog(cues=Application().cue_model)
        self.cue_dialog.list.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def load_settings(self, settings):
        for target_id, action in settings.get('targets', []):
            target = Application().cue_model.get(target_id)
            if target is not None:
                self._add_cue(target, action)

    def get_settings(self):
        targets = []
        for n in range(self.cuesWidget.count()):
            widget = self.cuesWidget.itemWidget(self.cuesWidget.item(n))
            target_id, action = widget.get_target()
            targets.append((target_id, action))

        return {'targets': targets}

    def _add_cue(self, cue, action):
        item = QListWidgetItem()
        item.setSizeHint(QSize(200, 30))

        widget = CueItemWidget(cue, action, self.cue_dialog)

        self.cuesWidget.addItem(item)
        self.cuesWidget.setItemWidget(item, widget)
        self.cue_dialog.remove_cue(cue)

    def _add_dialog(self):
        if self.cue_dialog.exec_() == QDialog.Accepted:
            for target in self.cue_dialog.selected_cues():
                self._add_cue(target, tuple(target.CueActions)[0].name)

    def _remove_selected(self):
        cue = self.cuesWidget.itemWidget(self.cuesWidget.currentItem()).target

        self.cuesWidget.takeItem(self.cuesWidget.currentRow())
        self.cue_dialog.add_cue(cue)
Пример #56
0
class Gui(QMainWindow):
    mainText = None
    mast = None
    tenants = None
    inc = None
    rowStore = None
    Gen = None
    gen = None
    mastInput = None
    keyNum = 1

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        app_icon = QIcon()
        app_icon.addFile("key.png", QSize(256, 256))
        self.setWindowIcon(app_icon)
        # open
        openFile = QAction('Open', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open new File')
        openFile.triggered.connect(self.fileOpen)
        # save
        saveFile = QAction('Save', self)
        saveFile.setShortcut('Ctrl+S')
        saveFile.setStatusTip('Save new File')
        saveFile.triggered.connect(self.fileSave)
        printAction = QAction("Print", self)
        printAction.triggered.connect(self.printSetup)
        # exit
        exitAction = QAction('Exit', self)
        exitAction.triggered.connect(self.closeEvent)
        # menu object
        menubar = self.menuBar()
        # file drop down
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openFile)
        fileMenu.addAction(saveFile)
        fileMenu.addAction(printAction)
        fileMenu.addAction(exitAction)
        # widgets
        grid = QGridLayout()
        horiz = QVBoxLayout()
        bigHoriz = QHBoxLayout()
        horizLayout = QHBoxLayout()
        window = QWidget()
        window.setLayout(bigHoriz)
        leftPane = QFormLayout()
        bigHoriz.addLayout(leftPane)
        bigHoriz.addLayout(horiz)
        self.setCentralWidget(window)
        btn = QPushButton('Generate', self)
        btn.clicked.connect(lambda: self.runGen())
        clearBtn = QPushButton("Clear", self)
        clearBtn.clicked.connect(self.clearList)
        self.mainText = QListWidget(self)
        self.mainText.itemSelectionChanged.connect(self.listItemClicked)
        self.mainText.setFont(
            QFontDatabase.systemFont(QFontDatabase.FixedFont))
        self.mastInput = []
        i = 0
        while i < 6:
            t = QLineEdit()
            t.setMaxLength(1)
            t.setAlignment(Qt.AlignHCenter)
            t.textChanged.connect(self.textInputed)
            self.mastInput.append(t)
            i = i + 1
        for e in self.mastInput:
            horizLayout.addWidget(e)
        self.mast = QLineEdit()
        self.tenants = QLineEdit()
        self.inc = QLineEdit()
        self.title = QLineEdit()
        self.title.setMinimumWidth(200)
        self.desc = QLineEdit()
        self.address = QLineEdit()
        self.contact = QLineEdit()
        self.phone = QLineEdit()
        self.email = QLineEdit()
        self.notes = QTextEdit()
        self.keyway = QLineEdit()
        label = QLabel("Master Cuts")
        incLabel = QLabel("Increment")
        tenantLabel = QLabel("Tenants")
        # add widgets to layouts
        leftPane.addRow(QLabel("Title"), self.title)
        leftPane.addRow(QLabel("Description"), self.desc)
        leftPane.addRow(QLabel("Keyway"), self.keyway)
        leftPane.addRow(QLabel("Address"), self.address)
        leftPane.addRow(QLabel("contact"), self.contact)
        leftPane.addRow(QLabel("Phone"), self.phone)
        leftPane.addRow(QLabel("Email"), self.email)
        leftPane.addRow(QLabel("Notes"), self.notes)
        grid.addWidget(incLabel, 3, 0)
        grid.addWidget(tenantLabel, 2, 0)
        grid.addWidget(label, 1, 0)
        grid.addWidget(btn, 0, 0)
        horiz.addWidget(self.mainText)
        horiz.addLayout(grid)
        # horiz.addLayout(horizLayout)
        grid.addWidget(clearBtn, 0, 1)
        grid.addWidget(self.tenants, 2, 1)
        grid.addWidget(self.inc, 3, 1)
        grid.addLayout(horizLayout, 1, 1)
        # window properties
        self.setGeometry(300, 300, 500, 425)
        self.setWindowTitle('PySchlageGen')
        self.show()

    def textInputed(self, string):
        if len(string) == 1:
            self.focusNextChild()

    def getGen(self):
        return self.gen

    def runGen(self):
        self.mainText.clear()
        self.keyNum = 1
        text = self.mast.text()
        mastCuts = []
        try:
            for e in self.mastInput:
                if e.text():
                    mastCuts.append(int(e.text()))
            tenants = int(self.tenants.text())
            inc = int(self.inc.text())
            mastCuts = list(map(int, mastCuts))
            self.gen = schlageGen()
            self.gen.addMasterKey(mastCuts)
            output = self.gen.genSystem(tenants, inc)
            self.displayKeys(output)
        except:
            pass

    def displayKeys(self, output):
        i = 0
        for o in output:
            if self.keyNum < 10:
                f = str(self.keyNum) + ":     "
            elif self.keyNum < 100:
                f = str(self.keyNum) + ":   "
            elif self.keyNum < 1000:
                f = str(self.keyNum) + ": "
            else:
                f = str(self.keyNum) + ":"
            for e in o:
                f = f + str(e) + " "
            item = QListWidgetItem(f)
            self.mainText.insertItem(i, item)
            i = i + 1
            self.keyNum = self.keyNum + 1

    def formatText(self, flist, space=True, inj=" "):
        out = ""
        for e in flist[:-1]:
            out = out + str(e)
            if space:
                out = out + inj
        out = out + str(flist[-1])
        return out

    def printSetup(self):
        if self.gen != None:
            printSetup = PrintSetup(self)
            printSetup.exec()
        else:
            QMessageBox.about(self, "Error","Please generate a system before printing.")

    def clearList(self):
        self.title.clear()
        self.desc.clear()
        self.address.clear()
        self.keyway.clear()
        self.contact.clear()
        self.phone.clear()
        self.email.clear()
        self.keyNum = 1
        self.notes.clear()
        self.mainText.clear()
        self.tenants.clear()
        self.inc.clear()
        for e in self.mastInput:
            e.clear()

    def listItemClicked(self):
        item = self.mainText.currentItem()
        flags = item.flags()
        if flags & Qt.ItemIsEnabled:
            if self.rowStore != None:
                self.mainText.takeItem(self.rowStore + 1)
                self.mainText.takeItem(self.rowStore + 1)
            tenCuts = self.gen.getSystem()[int(item.text().split(":")[0]) - 1]
            tenCuts = list(map(int, tenCuts))
            output = self.gen.bittingCalc(tenCuts)
            row = self.mainText.currentRow()
            self.rowStore = row
            flags = item.flags()
            flags ^= Qt.ItemIsEnabled
            item = QListWidgetItem("        " + self.formatText(output[0]))
            item.setFlags(flags)
            item2 = QListWidgetItem("        " + self.formatText(output[1]))
            item2.setFlags(flags)
            self.mainText.insertItem(row + 1, item)
            self.mainText.insertItem(row + 2, item2)

    def fileOpen(self):
        self.clearList()
        home = expanduser("~")
        fname = QFileDialog.getOpenFileName(self, 'Open file', home, "*.mks")
        data = None
        if fname[0] != '':
            with open(fname[0], 'r') as infile:
                data = infile.read()
            sys = data.split("`")
            self.gen = schlageGen()
            master = list(map(int, sys[0]))
            self.gen.addMasterKey(master)
            del sys[0]
            self.inc.setText(str(sys[0]))
            del sys[0]
            self.title.setText(str(sys[0]))
            del sys[0]
            self.desc.setText(str(sys[0]))
            del sys[0]
            self.keyway.setText(str(sys[0]))
            del sys[0]
            self.address.setText(str(sys[0]))
            del sys[0]
            self.contact.setText(str(sys[0]))
            del sys[0]
            self.phone.setText(str(sys[0]))
            del sys[0]
            self.email.setText(str(sys[0]))
            del sys[0]
            self.notes.setPlainText(str(sys[0]))
            del sys[0]
            self.gen.setTenants(sys)
            self.displayKeys(sys)
            i = 0
            while i < len(master):
                self.mastInput[i].setText(str(master[i]))
                i = i + 1
            self.tenants.setText(str(len(sys)))

    def fileSave(self):
        if self.gen != None:
            home = expanduser("~")
            fname = QFileDialog.getSaveFileName(self, 'Open file', home, "*.mks")
            if fname[0]:
                with open(fname[0], "w") as thefile:
                    thefile.write("%s`" % self.formatText(
                        self.gen.getMasterKey(), False))
                    thefile.write("%s`" % self.inc.text())
                    thefile.write("%s`" % self.title.text())
                    thefile.write("%s`" % self.desc.text())
                    thefile.write("%s`" % self.keyway.text())
                    thefile.write("%s`" % self.address.text())
                    thefile.write("%s`" % self.contact.text())
                    thefile.write("%s`" % self.phone.text())
                    thefile.write("%s`" % self.email.text())
                    thefile.write("%s`" % self.notes.toPlainText())
                    for e in self.gen.getSystem()[:-1]:
                        thefile.write("%s`" % self.formatText(e, False))
                    thefile.write("%s" % self.formatText(
                        self.gen.getSystem()[-1], False))
        else:
            QMessageBox.about(self, "Error","Please generate a system before saving.")

    def closeEvent(self, event):
        reply = QMessageBox.question(self, 'Message',
                                     "Are you sure to quit?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            sys.exit()
        else:
            if event:
                event.ignore()
Пример #57
0
class App(QDialog):
    def __init__(self):
        super().__init__()
        self.title = 'FIS results GUI'
        self.left = 50
        self.top = 50
        self.width = 1800
        self.height = 1000
        self.initUI()

        with open("config.json", "r") as config:
            self.config = json.load(config)
        with open("results.json", "r") as results:
            self.results = json.load(results)

        self.fillCategories()
        self.fillEvents()
        # Display graphs
        self.showGraphs()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        windowLayout = QGridLayout()

        self.categorySelectorGroupBox = QGroupBox("Category")
        self.eventSelectorGroupBox = QGroupBox("Event")

        self.statsGroupBox = QGroupBox("Stats")
        self.plotLine1GroupBox1 = QGroupBox("Podium per country")
        self.plotLine1GroupBox2 = QGroupBox("Controls")
        self.plotLine1GroupBox3 = QGroupBox("Breakdown per month")

        self.plotLine2GroupBox1 = QGroupBox("Race result")
        self.plotLine2GroupBox2 = QGroupBox("Statistic of the season")
        # self.plotLine2GroupBox3 = QGroupBox("Line2 Block 3")

        # self.bottomGroupBox = QGroupBox("Last Race")

        windowLayout.addWidget(self.plotLine1GroupBox1, 0, 2, 2, 3)
        windowLayout.addWidget(self.plotLine1GroupBox2, 0, 5, 2, 3)
        windowLayout.addWidget(self.plotLine1GroupBox3, 0, 8, 2, 3)

        windowLayout.addWidget(self.plotLine2GroupBox1, 2, 2, 2, 4)
        windowLayout.addWidget(self.plotLine2GroupBox2, 2, 6, 2, 5)
        # windowLayout.addWidget(self.plotLine2GroupBox3,2,8,2,3)

        windowLayout.addWidget(self.categorySelectorGroupBox, 0, 0, 2, 2)
        windowLayout.addWidget(self.eventSelectorGroupBox, 2, 0, 2, 2)

        # windowLayout.addWidget(self.bottomGroupBox,5,0,2,11)

        self.setLayout(windowLayout)
        self.show()

    def fillCategories(self):
        availablesCategories = list(self.config["resultsStruct"].keys())
        availablesCategories.insert(0, "All")
        # Set default category "All"
        self.category = "All"
        self.categoryList = QListWidget()

        for category in availablesCategories:
            self.categoryList.addItem(str(category))

        self.categoryList.itemClicked.connect(self.categorySelectedCallback)
        self.categorySelector = QVBoxLayout()
        self.categorySelector.addWidget(self.categoryList)
        self.categorySelectorGroupBox.setLayout(self.categorySelector)

    def categorySelectedCallback(self):
        newCategory = self.categoryList.currentItem().text()
        # print(f"Update selected category from {self.category} to {newCategory}")
        self.category = newCategory
        self.resetGraphsCategory()

    def fillEvents(self):
        self.availablesEvents = dataVisualisation.getEventsList(self.results)

        self.event = self.availablesEvents[0]
        self.eventList = QListWidget()

        for event in self.availablesEvents:
            # print(event)
            date = "{:02d}".format(event["date"]["day"]) + "/" + str(
                event["date"]["month"]) + "/" + str(event["date"]["year"])
            self.eventList.addItem(date + ' | ' + str(event["place"]) + " - " +
                                   event["type"])

        self.eventList.itemClicked.connect(self.eventSelectedCallback)
        self.eventSelector = QVBoxLayout()
        self.eventSelector.addWidget(self.eventList)
        self.eventSelectorGroupBox.setLayout(self.eventSelector)

    def eventSelectedCallback(self):
        newEventIndex = self.eventList.currentRow()
        # print(f"Update selected event from {self.event} to {self.availablesEvents[newEventIndex]}")
        self.event = self.availablesEvents[newEventIndex]
        self.resetGraphsEvents()

    def showGraphs(self):
        self.createCountryPodium()
        self.createEventResults()
        self.createDetailAthlete()
        self.createCountryResultsBreakdown()
        self.createControls()

    def resetGraphsCategory(self):
        # Reset podium per country
        while (self.podiumTable.rowCount() > 0):
            self.podiumTable.removeRow(0)
        self.fillCountryPodium()
        # self.resetGraphBreakdown()

    def resetGraphsEvents(self):
        while (self.eventTable.rowCount() > 0):
            self.eventTable.removeRow(0)
        self.fillEventResults()

    def resetGraphBreakdown(self):
        # discards the old graph
        self.ax.clear()
        # refresh canvas
        self.canvas.draw()

        # Reset all the labels in the controlBox
        # controlLayout.clearL

        for i in reversed(range(self.labelLayout.count())):
            # layoutToDel = self.labelLayout.itemAt(i)
            widgetToRemove = self.labelLayout.itemAt(i).widget()
            # remove it from the layout list
            self.labelLayout.removeWidget(widgetToRemove)
            # remove it from the gui
            widgetToRemove.setParent(None)

    def createControls(self):
        self.resetGraphButton = QPushButton(text="Reset graph")

        self.resetGraphButton.clicked.connect(self.resetGraphBreakdown)

        self.controlLayout = QVBoxLayout()

        self.controlLayout.addWidget(self.resetGraphButton)
        self.controlLayout.addStretch()
        self.labelLayout = QVBoxLayout()

        self.plotLine1GroupBox2.setLayout(self.controlLayout)
        self.controlLayout.addLayout(self.labelLayout)

    def createCountryPodium(self):
        self.podiumTable = QTableWidget()
        self.podiumTable.setHorizontalHeaderLabels(
            ["Country", " 1st Places ", " 2nd Places ", " 3rd Places "])
        self.fillCountryPodium()

        self.podiumTable.resizeColumnToContents(1)
        self.podiumTable.resizeColumnToContents(2)
        self.podiumTable.resizeColumnToContents(3)

        self.countryPodium = QVBoxLayout()
        self.countryPodium.addWidget(self.podiumTable)

        self.plotLine1GroupBox1.setLayout(self.countryPodium)

        self.podiumTable.cellClicked.connect(
            self.countryMedalBreakdownCallback)

    def fillCountryPodium(self):
        data = dataVisualisation.countryPodiumTable(self.results,
                                                    self.category)
        self.podiumTable.setRowCount(len(data))
        self.podiumTable.setColumnCount(4)

        for i, country in enumerate(data):
            self.podiumTable.setItem(i, 0, QTableWidgetItem(country.name))
            self.podiumTable.setItem(i, 1,
                                     QTableWidgetItem(str(country.first)))
            self.podiumTable.setItem(i, 2,
                                     QTableWidgetItem(str(country.second)))
            self.podiumTable.setItem(i, 3,
                                     QTableWidgetItem(str(country.third)))

    def countryMedalBreakdownCallback(self, row, column):
        if column == 0:
            self.country = self.podiumTable.item(row, 0).text()
            print(f"Show detailed info about the country : {self.country}")

            self.fillCountryResultsBreakdown()

    def createCountryResultsBreakdown(self):
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)

        # create an axis
        self.ax = self.figure.add_subplot(111)

        # discards the old graph
        self.ax.clear()

        self.ax.set_xlabel("Months")
        self.ax.set_ylabel("Nb of podiums")

        layout = QVBoxLayout()

        layout.addWidget(self.canvas)

        self.plotLine1GroupBox3.setLayout(layout)

    def fillCountryResultsBreakdown(self):
        data = dataVisualisation.getCountryBreakdown(self.country,
                                                     self.category)

        # plot data
        p = self.ax.plot(data[0], data[1], '*-')

        # refresh canvas
        self.canvas.draw()

        # Get color from last line added on the graph
        hexColor = p[0].get_color()

        # Show info in the control box
        desc = self.country + " : " + self.category
        labelColor = QLabel(desc)
        labelColor.setStyleSheet(
            f"background-color: {hexColor}; border: 1px solid black;")

        self.labelLayout.addWidget(labelColor)

    def createEventResults(self):
        self.eventTable = QTableWidget()
        self.fillEventResults()

        self.eventPodium = QVBoxLayout()
        self.eventPodium.addWidget(self.eventTable)

        self.plotLine2GroupBox1.setLayout(self.eventPodium)

        self.eventTable.cellClicked.connect(self.resultSelectionChanged)

    def resultSelectionChanged(self, row, column):
        if column == 0:
            self.detailedAthleteName = self.eventTable.item(row, 0).text()
            print(
                f"Show detailed info about the athlete : {self.detailedAthleteName}"
            )

            # Remove all current stats
            for i in reversed(range(self.detailLayout.count())):
                self.detailLayout.itemAt(i).widget().deleteLater()

            self.fillDetailAthlete()

    def fillEventResults(self):

        if self.event['type'] == "Slalom" or self.event[
                'type'] == "Giant Slalom":
            self.eventTable.setHorizontalHeaderLabels([
                " Athlete ", " Country ", " Run 1 ", " Run 2 ", " Diff (ms) ",
                " Total "
            ])
            self.eventTable.setColumnCount(6)
            data = dataVisualisation.eventResultTable(self.event)
            self.eventTable.setRowCount(len(data))

            for i, athlete in enumerate(data):
                self.eventTable.setItem(
                    i, 0, QTableWidgetItem(str(athlete["name"])[0:22]))
                self.eventTable.setItem(
                    i, 1, QTableWidgetItem(str(athlete["country"])))
                self.eventTable.setItem(i, 2,
                                        QTableWidgetItem(str(athlete["run1"])))
                self.eventTable.setItem(i, 3,
                                        QTableWidgetItem(str(athlete["run2"])))
                self.eventTable.setItem(i, 4,
                                        QTableWidgetItem(str(athlete["diff"])))

                if athlete["diff"] > 0:
                    self.eventTable.item(i, 4).setBackground(QColor(237, 2, 2))
                elif athlete["diff"] < 0:
                    self.eventTable.item(i,
                                         4).setBackground(QColor(98, 252, 3))

                self.eventTable.setItem(
                    i, 5, QTableWidgetItem(str(athlete["total"])))

                self.eventTable.resizeColumnsToContents()

        elif self.event['type'] == "Super G" or self.event[
                'type'] == "Downhill":
            self.eventTable.setHorizontalHeaderLabels(
                [" Athlete ", " Country ", " Time "])
            self.eventTable.setColumnCount(3)

            data = dataVisualisation.eventResultTable(self.event)
            self.eventTable.setRowCount(len(data))

            for i, athlete in enumerate(data):
                self.eventTable.setItem(
                    i, 0, QTableWidgetItem(str(athlete["name"])[0:22]))
                self.eventTable.setItem(
                    i, 1, QTableWidgetItem(str(athlete["country"])))
                self.eventTable.setItem(i, 2,
                                        QTableWidgetItem(str(athlete["time"])))

                self.eventTable.resizeColumnsToContents()

        elif self.event['type'] == "Parallel":
            self.eventTable.setHorizontalHeaderLabels(
                [" Athlete ", " Country "])
            self.eventTable.setColumnCount(2)

            data = dataVisualisation.eventResultTable(self.event)
            self.eventTable.setRowCount(len(data))

            for i, athlete in enumerate(data):
                self.eventTable.setItem(
                    i, 0, QTableWidgetItem(str(athlete["name"])[0:22]))
                self.eventTable.setItem(
                    i, 1, QTableWidgetItem(str(athlete["country"])))

                self.eventTable.resizeColumnsToContents()

    def createDetailAthlete(self):

        self.instructionAthlete = QLabel("Select an athlete first")
        self.detailLayout = QVBoxLayout()
        self.detailLayout.addWidget(self.instructionAthlete)

        self.plotLine2GroupBox2.setLayout(self.detailLayout)

    def fillDetailAthlete(self):
        data = dataVisualisation.getDetails(self.detailedAthleteName,
                                            self.results)

        # self.detailLayout.removeWidget(self.instructionAthlete)

        nameCountry = QLabel(
            f"Name : {data['name']}  |  Country : {data['country']}")
        numberOfRace = QLabel(f"Number of races : {data['numberOfRace']}")
        numberOfPodium = QLabel(
            f"Number of podiums : {data['numberOfPodium']}")
        bestRank = QLabel(f"Best rank : {data['bestRank']}")
        bestRace = QLabel(f"Best race : {data['bestRace']}")
        bestCategory = QLabel(f"Best category : {data['bestCategory']}")

        self.detailLayout.addWidget(nameCountry)
        self.detailLayout.addWidget(numberOfRace)
        self.detailLayout.addWidget(numberOfPodium)
        self.detailLayout.addWidget(bestRank)
        self.detailLayout.addWidget(bestRace)
        self.detailLayout.addWidget(bestCategory)
class SetColumnsDialog(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(SetColumnsDialog, self).__init__(parent)
        #self.setupUi(self)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.white)
        self.setPalette(p)
        self.resize(900,700)

        # attributes
        self.filename = None

        self.progress = QProgressBar(self)
        self.progress.setGeometry(20, 550, 480, 20)
        self.progress.setRange(0,0)
        self.progress.setVisible(False)

        self.progressInfo = QLabel(self)
        self.progressInfo.setText("Generando el reporte, por favor espere...")
        self.progressInfo.move(20, 570)
        newfont = QFont("Arial", 10)
        newfont.setItalic(True)
        self.progressInfo.setFont(newfont)
        self.progressInfo.setVisible(False)

    def showDialog(self, layer, columnList, fonafifoUrl):

        self.layer=layer
        self.columnList=columnList
        self.columnList.clear()
        self.fonafifoUrl = fonafifoUrl

        MAX_FOOTER = 600

        # FONAFIFO logo
        pic = QLabel(self)
        pic.setGeometry(600, MAX_FOOTER-30, 150, 50)
        pixmap = QPixmap()
        pixmap.load(fonafifoUrl);
        pic.setPixmap(pixmap)

        self.labelHeader = QLabel(self)
        self.labelHeader.setText("Selección de Criterios")
        self.labelHeader.setStyleSheet('color: #076F00')
        self.labelHeader.move(10, 20)
        newfont = QFont("Times", 20, QFont.Bold)
        self.labelHeader.setFont(newfont)

        self.frame = QFrame(self)
        self.frame.setFrameShape(QFrame.HLine)
        self.frame.setFrameShadow(QFrame.Sunken)
        self.frame.move(5,55);
        self.frame.resize(1955,5)


        self.buttonDescargar = QPushButton('Cargar Tabla', self)
        self.buttonDescargar.move(20, 590)
        self.buttonDescargar.resize(200, 30)
        self.buttonDescargar.clicked.connect(self.looping)

        self.buttonCerrar = QPushButton('Cerrar', self)
        self.buttonCerrar.move(270, 590)
        self.buttonCerrar.resize(200, 30)
        self.buttonCerrar.clicked.connect(self.close)

        X = 1500
        Y = 200

        HEIGHT=30
        WIDTH_LABEL=400
        INCREMENT_Y=20

        self.str_TOTAL = 'Total';
        self.str_AMPHIBIA = 'Amphibia';
        self.str_AVES = 'Aves';
        self.str_MAMMALIA = 'Mammalia';
        self.str_PLANTAE = 'Plantae';
        self.str_REPTILIA = 'Reptilia';
        self.str_REGISTROS_DE_PRESENCIA = 'Registros de presencia';
        self.str_AREAS_DE_DISTRIBUCION = 'Áreas de distribución';
        self.str_AMENAZADAS_UICN = 'Amenazadas IUCN';
        self.str_EN_PELIGRO_DE_EXTINCION = 'En peligro de extinción';
        self.str_CON_POBLACION_REDUCIDA = 'Con población reducida';
        self.str_VEDADA = 'Vedadas';
        self.str_CONT = ' --> ';

        self.list_class_pre = QListWidget(self)
        self.list_class_pre.addItem(self.str_TOTAL)
        self.list_class_pre.addItem(self.str_AMPHIBIA)
        self.list_class_pre.addItem(self.str_AVES)
        self.list_class_pre.addItem(self.str_MAMMALIA)
        self.list_class_pre.addItem(self.str_PLANTAE)
        self.list_class_pre.addItem(self.str_REPTILIA)
        self.list_class_pre.setCurrentRow(0)
        self.list_class_pre.setGeometry(10, 120, 150, 120)

        self.list_tipo_pre = QListWidget(self)
        self.list_tipo_pre.addItem(self.str_REGISTROS_DE_PRESENCIA)
        self.list_tipo_pre.addItem(self.str_AREAS_DE_DISTRIBUCION)
        self.list_tipo_pre.setCurrentRow(0)
        self.list_tipo_pre.setGeometry(10, 250, 150, 90)

        self.list_amenazas_pre = QListWidget(self)
        self.list_amenazas_pre.addItem("--")
        self.list_amenazas_pre.addItem(self.str_AMENAZADAS_UICN)
        self.list_amenazas_pre.addItem(self.str_EN_PELIGRO_DE_EXTINCION)
        self.list_amenazas_pre.addItem(self.str_CON_POBLACION_REDUCIDA)
        self.list_amenazas_pre.addItem(self.str_VEDADA)
        self.list_amenazas_pre.setCurrentRow(0)
        self.list_amenazas_pre.setGeometry(10, 350, 150, 90)

        self.botton_list_include = QPushButton(">>", self)
        self.botton_list_include.setGeometry(200, 120, 50, 50)
        self.botton_list_include.clicked.connect(self.chooseClassInclude)

        self.botton_list_exclude = QPushButton("<<", self)
        self.botton_list_exclude.setGeometry(200, 160, 50, 50)
        self.botton_list_exclude.clicked.connect(self.chooseClassExclude)

        self.list_class_post = QListWidget(self)
        self.list_class_post.setGeometry(300, 120, WIDTH_LABEL, 350)

        self.seleccionClass = "";
        self.seleccionTipo = "";
        self.seleccionAmenaza = "";













        self.checkbox_presencia_total_especies = QCheckBox("Riqueza total de especies por registros de presencia", self)
        self.checkbox_presencia_total_especies.setGeometry(X,Y,WIDTH_LABEL,HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_especies_amenazadas = QCheckBox("Riqueza total de especies por registros de presencia - Amenazadas UICN", self)
        self.checkbox_presencia_total_especies_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_especies_amenazadas_lcvs = QCheckBox("Riqueza total de especies por registros de presencia - Amenazadas LCVS", self)
        self.checkbox_presencia_total_especies_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_presencia_total_mammalia = QCheckBox("Riqueza total de MAMMALIA por registros de presencia", self)
        self.checkbox_presencia_total_mammalia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_mammalia_amenazadas = QCheckBox("Riqueza total de MAMMALIA por registros de presencia - Amenazadas UICN", self)
        self.checkbox_presencia_total_mammalia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_mammalia_amenazadas_lcvs = QCheckBox("Riqueza total de MAMMALIA por registros de presencia - Amenazadas LCVS", self)
        self.checkbox_presencia_total_mammalia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_presencia_total_aves = QCheckBox("Riqueza total de AVES por registros de presencia", self)
        self.checkbox_presencia_total_aves.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_aves_amenazadas = QCheckBox("Riqueza total de AVES por registros de presencia - Amenazadas UICN", self)
        self.checkbox_presencia_total_aves_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_aves_amenazadas_lcvs = QCheckBox("Riqueza total de AVES por registros de presencia - Amenazadas LCVS", self)
        self.checkbox_presencia_total_aves_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_presencia_total_reptilia = QCheckBox("Riqueza total de REPTILIA por registros de presencia", self)
        self.checkbox_presencia_total_reptilia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_reptilia_amenazadas = QCheckBox("Riqueza total de REPTILIA por registros de presencia - Amenazadas UICN", self)
        self.checkbox_presencia_total_reptilia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_reptilia_amenazadas_lcvs = QCheckBox("Riqueza total de REPTILIA por registros de presencia - Amenazadas LCVS", self)
        self.checkbox_presencia_total_reptilia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_presencia_total_amphibia = QCheckBox("Riqueza total de AMPHIBIA por registros de presencia", self)
        self.checkbox_presencia_total_amphibia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_amphibia_amenazadas = QCheckBox("Riqueza total de AMPHIBIA por registros de presencia - Amenazadas UICN", self)
        self.checkbox_presencia_total_amphibia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_amphibia_amenazadas_lcvs = QCheckBox("Riqueza total de AMPHIBIA por registros de presencia - Amenazadas LCVS", self)
        self.checkbox_presencia_total_amphibia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_presencia_total_trees = QCheckBox("Riqueza total de PLANTAE por registros de presencia", self)
        self.checkbox_presencia_total_trees.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_trees_amenazadas = QCheckBox("Riqueza total de PLANTAE por registros de presencia - Amenazadas UICN", self)
        self.checkbox_presencia_total_trees_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_presencia_total_trees_amenazadas_lcvs = QCheckBox("Riqueza total de PLANTAE por registros de presencia - Amenazadas LCVS", self)
        self.checkbox_presencia_total_trees_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)

        Y = 70
        X = 1450

        self.checkbox_distribucion_total_especies = QCheckBox("Riqueza total de especies por áreas de distribución", self)
        self.checkbox_distribucion_total_especies.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_especies_amenazadas = QCheckBox("Riqueza total de especies por áreas de distribución - Amenazadas UICN", self)
        self.checkbox_distribucion_total_especies_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_especies_amenazadas_lcvs = QCheckBox("Riqueza total de especies por áreas de distribución - Amenazadas LCVS", self)
        self.checkbox_distribucion_total_especies_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_mammalia = QCheckBox("Riqueza total de MAMMALIA por áreas de distribución", self)
        self.checkbox_distribucion_total_mammalia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_mammalia_amenazadas = QCheckBox("Riqueza total de MAMMALIA por áreas de distribución - Amenazadas UICN", self)
        self.checkbox_distribucion_total_mammalia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_mammalia_amenazadas_lcvs = QCheckBox("Riqueza total de MAMMALIA por áreas de distribución - Amenazadas LCVS", self)
        self.checkbox_distribucion_total_mammalia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_aves = QCheckBox("Riqueza total de AVES por áreas de distribución", self)
        self.checkbox_distribucion_total_aves.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_aves_amenazadas = QCheckBox("Riqueza total de AVES por áreas de distribución - Amenazadas UICN", self)
        self.checkbox_distribucion_total_aves_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_aves_amenazadas_lcvs = QCheckBox("Riqueza total de AVES por áreas de distribución - Amenazadas LCVS", self)
        self.checkbox_distribucion_total_aves_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_reptilia = QCheckBox("Riqueza total de REPTILIA por áreas de distribución", self)
        self.checkbox_distribucion_total_reptilia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_reptilia_amenazadas = QCheckBox("Riqueza total de REPTILIA por áreas de distribución - Amenazadas UICN", self)
        self.checkbox_distribucion_total_reptilia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_reptilia_amenazadas_lcvs = QCheckBox("Riqueza total de REPTILIA por áreas de distribución - Amenazadas LCVS", self)
        self.checkbox_distribucion_total_reptilia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_amphibia = QCheckBox("Riqueza total de AMPHIBIA por áreas de distribución", self)
        self.checkbox_distribucion_total_amphibia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_amphibia_amenazadas = QCheckBox("Riqueza total de AMPHIBIA por áreas de distribución - Amenazadas UICN", self)
        self.checkbox_distribucion_total_amphibia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_amphibia_amenazadas_lcvs = QCheckBox("Riqueza total de AMPHIBIA por áreas de distribución - Amenazadas LCVS", self)
        self.checkbox_distribucion_total_amphibia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_trees = QCheckBox("Riqueza total de PLANTAE por áreas de distribución", self)
        self.checkbox_distribucion_total_trees.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_trees_amenazadas = QCheckBox("Riqueza total de PLANTAE por áreas de distribución - Amenazadas UICN", self)
        self.checkbox_distribucion_total_trees_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)
        Y += INCREMENT_Y
        self.checkbox_distribucion_total_trees_amenazadas_lcvs = QCheckBox("Riqueza total de PLANTAE por áreas de distribución - Amenazadas LCVS", self)
        self.checkbox_distribucion_total_trees_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT)






        self.show()

    def looping(self):

        self.progressInfo.setVisible(True)
        self.progress.setVisible(True)
        self.looptimer = QTimer()
        self.looptimer.setSingleShot(True)
        self.looptimer.timeout.connect(self.cargarTabla)
        self.looptimer.start(5000)





    def rellenarText(self, strClass):
        if (self.seleccionClass == strClass):
            if (self.seleccionTipo == self.str_REGISTROS_DE_PRESENCIA):
                const_REG_PRESENCIA = strClass + self.str_CONT + self.str_REGISTROS_DE_PRESENCIA
                if (self.seleccionAmenaza == '--'):
                    self.list_class_post.addItem(const_REG_PRESENCIA)
                if (self.seleccionAmenaza == self.str_AMENAZADAS_UICN):
                    self.list_class_post.addItem(const_REG_PRESENCIA + self.str_CONT + self.str_AMENAZADAS_UICN);
                if (self.seleccionAmenaza == self.str_EN_PELIGRO_DE_EXTINCION):
                    self.list_class_post.addItem(const_REG_PRESENCIA + self.str_CONT + self.str_EN_PELIGRO_DE_EXTINCION);
                if (self.seleccionAmenaza == self.str_CON_POBLACION_REDUCIDA):
                    self.list_class_post.addItem(const_REG_PRESENCIA + self.str_CONT + self.str_CON_POBLACION_REDUCIDA);
                if (self.seleccionAmenaza == self.str_VEDADA):
                    if((self.seleccionClass == self.str_PLANTAE) | (self.seleccionClass == self.str_TOTAL)):
                        self.list_class_post.addItem(const_REG_PRESENCIA + self.str_CONT + self.str_VEDADA);
                    else:
                        QMessageBox.about(self, 'Alerta!', 'La categoria "VEDADA" es exclusiva para Plantae');

                self.agregarColumnas(strClass, self.seleccionAmenaza, "occurrence");

            if (self.seleccionTipo == self.str_AREAS_DE_DISTRIBUCION):
                const_REG_DISTRIBUCION = strClass + self.str_CONT + self.str_AREAS_DE_DISTRIBUCION
                if (self.seleccionAmenaza == '--'):
                    self.list_class_post.addItem(const_REG_DISTRIBUCION)
                if (self.seleccionAmenaza == self.str_AMENAZADAS_UICN):
                    self.list_class_post.addItem(const_REG_DISTRIBUCION + self.str_CONT + self.str_AMENAZADAS_UICN);
                if (self.seleccionAmenaza == self.str_EN_PELIGRO_DE_EXTINCION):
                    self.list_class_post.addItem(const_REG_DISTRIBUCION + self.str_CONT + self.str_EN_PELIGRO_DE_EXTINCION);
                if (self.seleccionAmenaza == self.str_CON_POBLACION_REDUCIDA):
                    self.list_class_post.addItem(const_REG_DISTRIBUCION + self.str_CONT + self.str_CON_POBLACION_REDUCIDA);
                if (self.seleccionAmenaza == self.str_VEDADA):
                    if((self.seleccionClass == self.str_PLANTAE) | (self.seleccionClass == self.str_TOTAL)):
                        self.list_class_post.addItem(const_REG_DISTRIBUCION + self.str_CONT + self.str_VEDADA);
                    else:
                        QMessageBox.about(self, 'Alerta!', 'La categoria "VEDADA" es exclusiva para Plantae');

                self.agregarColumnas(strClass, self.seleccionAmenaza, "distribution");

    def agregarColumnas(self, strClass, strStatus, strType):
        if (strClass == self.str_TOTAL):
            if (strStatus == '--'):
                self.columnList.append("all_" + strType);
                self.columnList.append("all_" + strType + "_names");
            if (strStatus == self.str_AMENAZADAS_UICN):
                self.columnList.append("all_iucn_threatened_" + strType);
                self.columnList.append("all_iucn_threatened_" + strType + "_names");
            if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION):
                self.columnList.append("all_lcvs_pe_" + strType);
                self.columnList.append("all_lcvs_pe_" + strType + "_names");
            if (strStatus == self.str_CON_POBLACION_REDUCIDA):
                self.columnList.append("all_lcvs_pr_" + strType);
                self.columnList.append("all_lcvs_pr_" + strType + "_names");
            if (strStatus == self.str_VEDADA):
                self.columnList.append("all_lcvs_ve_" + strType);
                self.columnList.append("all_lcvs_ve_" + strType + "_names");
        if (strClass == self.str_AMPHIBIA):
            if (strStatus == '--'):
                self.columnList.append("amphibia_" + strType);
                self.columnList.append("amphibia_" + strType + "_names");
            if (strStatus == self.str_AMENAZADAS_UICN):
                self.columnList.append("amphibia_iucn_threatened_" + strType);
                self.columnList.append("amphibia_iucn_threatened_" + strType + "_names");
            if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION):
                self.columnList.append("amphibia_lcvs_pe_" + strType);
                self.columnList.append("amphibia_lcvs_pe_" + strType + "_names");
            if (strStatus == self.str_CON_POBLACION_REDUCIDA):
                self.columnList.append("amphibia_lcvs_pr_" + strType);
                self.columnList.append("amphibia_lcvs_pr_" + strType + "_names");
        if (strClass == self.str_AVES):
            if (strStatus == '--'):
                self.columnList.append("aves_" + strType);
                self.columnList.append("aves_occurrence_names");
            if (strStatus == self.str_AMENAZADAS_UICN):
                self.columnList.append("aves_iucn_threatened_" + strType);
                self.columnList.append("aves_iucn_threatened_" + strType + "_names");
            if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION):
                self.columnList.append("aves_lcvs_pe_" + strType);
                self.columnList.append("aves_lcvs_pe_" + strType + "_names");
            if (strStatus == self.str_CON_POBLACION_REDUCIDA):
                self.columnList.append("aves_lcvs_pr_" + strType);
                self.columnList.append("aves_lcvs_pr_" + strType + "_names");
        if (strClass == self.str_MAMMALIA):
            if (strStatus == '--'):
                self.columnList.append("mammalia_" + strType);
                self.columnList.append("mammalia_" + strType + "_names");
            if (strStatus == self.str_AMENAZADAS_UICN):
                self.columnList.append("mammalia_iucn_threatened_" + strType);
                self.columnList.append("mammalia_iucn_threatened_" + strType + "_names");
            if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION):
                self.columnList.append("mammalia_lcvs_pe_" + strType);
                self.columnList.append("mammalia_lcvs_pe_" + strType + "_names");
            if (strStatus == self.str_CON_POBLACION_REDUCIDA):
                self.columnList.append("mammalia_lcvs_pr_" + strType);
                self.columnList.append("mammalia_lcvs_pr_" + strType + "_names");
        if (strClass == self.str_PLANTAE):
            if (strStatus == '--'):
                self.columnList.append("plantae_" + strType);
                self.columnList.append("plantae_" + strType + "_names");
            if (strStatus == self.str_AMENAZADAS_UICN):
                self.columnList.append("plantae_iucn_threatened_" + strType);
                self.columnList.append("plantae_iucn_threatened_" + strType + "_names");
            if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION):
                self.columnList.append("plantae_lcvs_pe_" + strType);
                self.columnList.append("plantae_lcvs_pe_" + strType + "_names");
            if (strStatus == self.str_CON_POBLACION_REDUCIDA):
                self.columnList.append("plantae_lcvs_pr_" + strType);
                self.columnList.append("plantae_lcvs_pr_" + strType + "_names");
            if (strStatus == self.str_VEDADA):
                self.columnList.append("plantae_lcvs_ve_" + strType);
                self.columnList.append("plantae_lcvs_ve_" + strType + "_names");
        if (strClass == self.str_REPTILIA):
            if (strStatus == '--'):
                self.columnList.append("reptilia_" + strType);
                self.columnList.append("reptilia_" + strType + "_names");
            if (strStatus == self.str_AMENAZADAS_UICN):
                self.columnList.append("reptilia_iucn_threatened_" + strType);
                self.columnList.append("reptilia_iucn_threatened_" + strType + "_names");
            if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION):
                self.columnList.append("reptilia_lcvs_pe_" + strType);
                self.columnList.append("reptilia_lcvs_pe_" + strType + "_names");
            if (strStatus == self.str_CON_POBLACION_REDUCIDA):
                self.columnList.append("reptilia_lcvs_pr_" + strType);
                self.columnList.append("reptilia_lcvs_pr_" + strType + "_names");



    def chooseClassInclude(self):
        for selectedItem in self.list_class_pre.selectedItems():
            self.seleccionClass = self.list_class_pre.currentItem().text();
            self.seleccionTipo = self.list_tipo_pre.currentItem().text();
            self.seleccionAmenaza = self.list_amenazas_pre.currentItem().text();

            self.rellenarText(self.str_TOTAL);
            self.rellenarText(self.str_AMPHIBIA);
            self.rellenarText(self.str_AVES);
            self.rellenarText(self.str_MAMMALIA);
            self.rellenarText(self.str_PLANTAE);
            self.rellenarText(self.str_REPTILIA);


            #self.list_class_post.addItem(self.list_class_pre.currentItem().text())
            #self.list_class_pre.takeItem(self.list_class_pre.row(selectedItem))

    def chooseClassExclude(self):
        for selectedItem in self.list_class_post.selectedItems():
            self.list_class_pre.addItem(self.list_class_post.currentItem().text())
            self.list_class_post.takeItem(self.list_class_post.row(selectedItem))






    def cargarTabla(self):




        ###############################################################################
        ### VALIDACIONES
        ###############################################################################
        if self.checkbox_presencia_total_especies.isChecked():
            self.columnList.append("spp_all_richness_occurrence")
            self.columnList.append("spp_all_richness_occurrence_names")
        if self.checkbox_presencia_total_especies_amenazadas.isChecked():
            self.columnList.append("spp_all_threatened_richness_occurrence")
            self.columnList.append("spp_all_threatened_richness_occurrence_names")
        if self.checkbox_presencia_total_especies_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_all_lcvs_richness_occurrence")
            self.columnList.append("spp_all_lcvs_richness_occurrence_names")

        if self.checkbox_presencia_total_mammalia.isChecked():
            self.columnList.append("spp_mammalia_richness_occurrence")
            self.columnList.append("spp_mammalia_richness_occurrence_names")
        if self.checkbox_presencia_total_mammalia_amenazadas.isChecked():
            self.columnList.append("spp_mammalia_threatened_richness_occurrence")
            self.columnList.append("spp_mammalia_threatened_richness_occurrence_names")
        if self.checkbox_presencia_total_mammalia_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_mammalia_lcvs_richness_occurrence")
            self.columnList.append("spp_mammalia_lcvs_richness_occurrence_names")


        if self.checkbox_presencia_total_aves.isChecked():
            self.columnList.append("spp_aves_richness_occurrence")
            self.columnList.append("spp_aves_richness_occurrence_names")
        if self.checkbox_presencia_total_aves_amenazadas.isChecked():
            self.columnList.append("spp_aves_threatened_richness_occurrence")
            self.columnList.append("spp_aves_threatened_richness_occurrence_names")
        if self.checkbox_presencia_total_aves_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_aves_lcvs_richness_occurrence")
            self.columnList.append("spp_aves_lcvs_richness_occurrence_names")

        if self.checkbox_presencia_total_reptilia.isChecked():
            self.columnList.append("spp_reptilia_richness_occurrence")
            self.columnList.append("spp_reptilia_richness_occurrence_names")
        if self.checkbox_presencia_total_reptilia_amenazadas.isChecked():
            self.columnList.append("spp_reptilia_threatened_richness_occurrence")
            self.columnList.append("spp_reptilia_threatened_richness_occurrence_names")
        if self.checkbox_presencia_total_reptilia_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_reptilia_lcvs_richness_occurrence")
            self.columnList.append("spp_reptilia_lcvs_richness_occurrence_names")


        if self.checkbox_presencia_total_amphibia.isChecked():
            self.columnList.append("spp_amphibia_richness_occurrence")
            self.columnList.append("spp_amphibia_richness_occurrence_names")
        if self.checkbox_presencia_total_amphibia_amenazadas.isChecked():
            self.columnList.append("spp_amphibia_threatened_richness_occurrence")
            self.columnList.append("spp_amphibia_threatened_richness_occurrence_names")
        if self.checkbox_presencia_total_amphibia_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_amphibia_lcvs_richness_occurrence")
            self.columnList.append("spp_amphibia_lcvs_richness_occurrence_names")


        if self.checkbox_presencia_total_trees.isChecked():
            self.columnList.append("spp_trees_richness_occurrence")
            self.columnList.append("spp_trees_richness_occurrence_names")
        if self.checkbox_presencia_total_trees_amenazadas.isChecked():
            self.columnList.append("spp_trees_threatened_richness_occurrence")
            self.columnList.append("spp_trees_threatened_richness_occurrence_names")
        if self.checkbox_presencia_total_trees_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_trees_lcvs_richness_occurrence")
            self.columnList.append("spp_trees_lcvs_richness_occurrence_names")

        # DISTRIBUTION

        if self.checkbox_distribucion_total_especies.isChecked():
            self.columnList.append("spp_all_richness_distribution")
            self.columnList.append("spp_all_richness_distribution_names")
        if self.checkbox_distribucion_total_especies_amenazadas.isChecked():
            self.columnList.append("spp_all_threatened_richness_distribution")
            self.columnList.append("spp_all_threatened_richness_distribution_names")
        if self.checkbox_distribucion_total_especies_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_all_lcvs_richness_distribution")
            self.columnList.append("spp_all_lcvs_richness_distribution_names")


        if self.checkbox_distribucion_total_mammalia.isChecked():
            self.columnList.append("spp_mammalia_richness_distribution")
            self.columnList.append("spp_mammalia_richness_distribution_names")
        if self.checkbox_distribucion_total_mammalia_amenazadas.isChecked():
            self.columnList.append("spp_mammalia_threatened_richness_distribution")
            self.columnList.append("spp_mammalia_threatened_richness_distribution_names")
        if self.checkbox_distribucion_total_mammalia_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_mammalia_lcvs_richness_distribution")
            self.columnList.append("spp_mammalia_lcvs_richness_distribution_names")


        if self.checkbox_distribucion_total_aves.isChecked():
            self.columnList.append("spp_aves_richness_distribution")
            self.columnList.append("spp_aves_richness_distribution_names")
        if self.checkbox_distribucion_total_aves_amenazadas.isChecked():
            self.columnList.append("spp_aves_threatened_richness_distribution")
            self.columnList.append("spp_aves_threatened_richness_distribution_names")
        if self.checkbox_distribucion_total_aves_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_aves_lcvs_richness_distribution")
            self.columnList.append("spp_aves_lcvs_richness_distribution_names")


        if self.checkbox_distribucion_total_reptilia.isChecked():
            self.columnList.append("spp_reptilia_richness_distribution")
            self.columnList.append("spp_reptilia_richness_distribution_names")
        if self.checkbox_distribucion_total_reptilia_amenazadas.isChecked():
            self.columnList.append("spp_reptilia_threatened_richness_distribution")
            self.columnList.append("spp_reptilia_threatened_richness_distribution_names")
        if self.checkbox_distribucion_total_reptilia_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_reptilia_lcvs_richness_distribution")
            self.columnList.append("spp_reptilia_lcvs_richness_distribution_names")


        if self.checkbox_distribucion_total_amphibia.isChecked():
            self.columnList.append("spp_amphibia_richness_distribution")
            self.columnList.append("spp_amphibia_richness_distribution_names")
        if self.checkbox_distribucion_total_amphibia_amenazadas.isChecked():
            self.columnList.append("spp_amphibia_threatened_richness_distribution")
            self.columnList.append("spp_amphibia_threatened_richness_distribution_names")
        if self.checkbox_distribucion_total_amphibia_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_amphibia_lcvs_richness_distribution")
            self.columnList.append("spp_amphibia_lcvs_richness_distribution_names")


        if self.checkbox_distribucion_total_trees.isChecked():
            self.columnList.append("spp_trees_richness_distribution")
            self.columnList.append("spp_trees_richness_distribution_names")
        if self.checkbox_distribucion_total_trees_amenazadas.isChecked():
            self.columnList.append("spp_trees_threatened_richness_distribution")
            self.columnList.append("spp_trees_threatened_richness_distribution_names")
        if self.checkbox_distribucion_total_trees_amenazadas_lcvs.isChecked():
            self.columnList.append("spp_trees_lcvs_richness_distribution")
            self.columnList.append("spp_trees_lcvs_richness_distribution_names")

        self.dlgIdentificarPoligono = IdentifyToolDialog()
        self.dlgIdentificarPoligono.showDialog(self.layer, self.columnList, self.progress, self.progressInfo, self.fonafifoUrl)
Пример #59
0
class ListEdit(QWidget):
    """A widget to edit a list of items (e.g. a list of directories)."""
    
    # emitted when anything changed in the listbox.
    changed = pyqtSignal()
    
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        layout = QGridLayout(self)
        self.setLayout(layout)
        
        self.addButton = QPushButton(icons.get('list-add'), '')
        self.editButton = QPushButton(icons.get('document-edit'), '')
        self.removeButton = QPushButton(icons.get('list-remove'), '')
        self.listBox = QListWidget()
        
        layout.setContentsMargins(1, 1, 1, 1)
        layout.setSpacing(0)
        layout.addWidget(self.listBox, 0, 0, 8, 1)
        layout.addWidget(self.addButton, 0, 1)
        layout.addWidget(self.editButton, 1, 1)
        layout.addWidget(self.removeButton, 2, 1)
        
        @self.addButton.clicked.connect
        def addClicked():
            item = self.createItem()
            if self.openEditor(item):
                self.addItem(item)
                
        @self.editButton.clicked.connect
        def editClicked():
            item = self.listBox.currentItem()
            item and self.editItem(item)
        
        @self.removeButton.clicked.connect
        def removeClicked():
            item = self.listBox.currentItem()
            if item:
                self.removeItem(item)
        
        @self.listBox.itemDoubleClicked.connect
        def itemDoubleClicked(item):
            item and self.editItem(item)
            
        self.listBox.model().layoutChanged.connect(self.changed)
    
        def updateSelection():
            selected = bool(self.listBox.currentItem())
            self.editButton.setEnabled(selected)
            self.removeButton.setEnabled(selected)
        
        self.changed.connect(updateSelection)
        self.listBox.itemSelectionChanged.connect(updateSelection)
        updateSelection()
        app.translateUI(self)
    
    def translateUI(self):
        self.addButton.setText(_("&Add..."))
        self.editButton.setText(_("&Edit..."))
        self.removeButton.setText(_("&Remove"))
    
    def createItem(self):
        return QListWidgetItem()
        
    def addItem(self, item):
        self.listBox.addItem(item)
        self.itemChanged(item)
        self.changed.emit()
        
    def removeItem(self, item):
        self.listBox.takeItem(self.listBox.row(item))
        self.changed.emit()
        
    def editItem(self, item):
        if self.openEditor(item):
            self.itemChanged(item)
            self.changed.emit()
            
    def setCurrentItem(self, item):
        self.listBox.setCurrentItem(item)
        
    def setCurrentRow(self, row):
        self.listBox.setCurrentRow(row)
        
    def openEditor(self, item):
        """Opens an editor (dialog) for the item.
        
        Returns True if the dialog was accepted and the item edited.
        Returns False if the dialog was cancelled (the item must be left
        unedited).
        """
        pass
    
    def itemChanged(self, item):
        """Called after an item has been added or edited.
        
        Re-implement to do something at this moment if needed, e.g. alter the
        text or display of other items.
        """
        pass
    
    def setValue(self, strings):
        """Sets the listbox to a list of strings."""
        self.listBox.clear()
        self.listBox.addItems(strings)
        self.changed.emit()
        
    def value(self):
        """Returns the list of paths in the listbox."""
        return [self.listBox.item(i).text()
            for i in range(self.listBox.count())]
    
    def setItems(self, items):
        """Sets the listbox to a list of items."""
        self.listBox.clear()
        for item in items:
            self.listBox.addItem(item)
            self.itemChanged(item)
        self.changed.emit()
    
    def items(self):
        """Returns the list of items in the listbox."""
        return [self.listBox.item(i)
            for i in range(self.listBox.count())]
        
    def clear(self):
        """Clears the listbox."""
        self.listBox.clear()
        self.changed.emit()
Пример #60
0
class UsersGUI(QWidget):

    logginn = pyqtSignal(str, str, LogLevel)

    def __init__(self):
        super(UsersGUI, self).__init__()
        self.loggin = Logger('UsersGUI', self.logginn)
        self.nautaw = NautaWrap()
        self.nautaw.set_f_load_u_ugui(self.load_users)
        self.nauta = self.nautaw.nauta

        self.cl = QVBoxLayout()

        self.li = QListWidget()
        self.load_users()
        self.cl.addWidget(self.li)

        tt = QHBoxLayout()
        addu = qta.icon('mdi.account-plus',
                        color='green',
                        color_active='yellow')
        self.addu = QPushButton(addu, "")
        editu = qta.icon('mdi.account-edit',
                         color='blue',
                         color_active='yellow')
        self.editu = QPushButton(editu, "")
        remu = qta.icon('mdi.account-minus',
                        color='red',
                        color_active='yellow')
        self.remu = QPushButton(remu, "")
        tt.addWidget(self.addu)
        tt.addWidget(self.editu)
        tt.addWidget(self.remu)
        tt.addStretch()
        self.verif = QCheckBox("Verificar cuenta")
        tt.addWidget(self.verif)
        self.cl.addLayout(tt)

        self.setLayout(self.cl)

        self.addu.clicked.connect(self.adduser)
        self.editu.clicked.connect(self.edituser)
        self.remu.clicked.connect(self.deluser)

    def adduser(self):
        self.loggin.emit("Agregando cuenta.", LogLevel.INFORMATION)
        txt, ok = QInputDialog.getText(self, tr("Agregar Cuenta"),
                                       tr("Usuario"), 0, "")
        if not ok:
            self.loggin.emit("Operacion cancelada por el usuario.",
                             LogLevel.INFORMATION)
            return
        user = txt
        txt, ok = QInputDialog.getText(self, tr("Agregar Cuenta"),
                                       tr("Contraseña"), 2, "")
        if not ok:
            self.loggin.emit("Operacion cancelada por el usuario.",
                             LogLevel.INFORMATION)
            return
        passw = txt
        if self.verif.isChecked():
            try:
                self.loggin.emit("Verificando cuenta {0}.".format(user),
                                 LogLevel.INFORMATION)
                self.nauta.card_add(user,
                                    passw,
                                    verify=True,
                                    raise_exception=True)
            except ConectionError:
                self.loggin.emit(
                    "Parece que no hay connexion en este momento. No se puede verificar la cuenta. Desmarque verificar para poder agregarla.",
                    LogLevel.WARNING)
                self.loggin.emit(
                    "No se pudo agregar la cuenta por que no se pudo verificar.",
                    LogLevel.INFORMATION)
                return
            except BadCredentials:
                self.loggin.emit("Cuenta incorrecta.", LogLevel.WARNING)
                self.loggin.emit(
                    "No se pudo agregar la cuenta por que es incorrecta.",
                    LogLevel.INFORMATION)
                return
            self.loggin.emit("Cuenta {0} agergada correctamente.".format(user),
                             LogLevel.INFORMATION)
            self.nautaw.update_u()
            return
        self.nauta.card_add(user, passw, verify=False, raise_exception=False)
        self.loggin.emit("Cuenta {0} agergada correctamente.".format(user),
                         LogLevel.INFORMATION)
        self.nautaw.update_u()

    def edituser(self):
        cc = self.li.currentItem()
        if not cc:
            return
        txt = cc.text()
        card = self.nauta.get_card(txt, try_update=False)
        userc = card.username
        passwc = card.password
        self.loggin.emit("Editando cuenta.", LogLevel.INFORMATION)
        txt, ok = QInputDialog.getText(self, tr("Editar Cuenta"),
                                       tr("Usuario"), 0, userc)
        if not ok:
            self.loggin.emit("Operacion cancelada por el usuario.",
                             LogLevel.INFORMATION)
            return
        user = txt
        txt, ok = QInputDialog.getText(self, tr("Editar Cuenta"),
                                       tr("Contraseña"), 2, passwc)
        if not ok:
            self.loggin.emit("Operacion cancelada por el usuario.",
                             LogLevel.INFORMATION)
            return
        passw = txt
        if self.verif.isChecked():
            self.loggin.emit("Verificando cuenta {0}.".format(user),
                             LogLevel.INFORMATION)
            try:
                vv = self.nauta.verify(user, passw)
            except (requests.exceptions.ConnectionError,
                    requests.exceptions.ConnectTimeout):
                self.loggin.emit(
                    "Parece que no hay connexion en este momento. No se puede verificar la cuenta. Desmarque verificar para poder editarla.",
                    LogLevel.WARNING)
                self.loggin.emit(
                    "No se pudo editar la cuenta por que no se pudo verificar.",
                    LogLevel.INFORMATION)
                return
            if not vv:
                self.loggin.emit("Cuenta incorrecta.", LogLevel.WARNING)
                self.loggin.emit(
                    "No se pudo editar la cuenta por que es incorrecta.",
                    LogLevel.INFORMATION)
                return
            card = self.nauta.get_card(txt, try_update=True)
            self.nauta.card_update(userc, card.to_json())
            self.loggin.emit("Cuenta {0} editada correctamente.".format(user),
                             LogLevel.INFORMATION)
            self.nautaw.update_u()
            return
        self.nauta.card_update(userc, card.to_json())
        self.loggin.emit("Cuenta {0} editada correctamente.".format(user),
                         LogLevel.INFORMATION)
        self.nautaw.update_u()

    def deluser(self):
        cc = self.li.currentItem()
        if not cc:
            return
        txt = cc.text()
        card = self.nauta.get_card(txt, try_update=False)
        userc = card.username
        self.loggin.emit("Eliminando cuenta.", LogLevel.INFORMATION)
        if self.nautaw.active and self.nautaw.account == userc:
            self.loggin.emit(
                "Cuenta en uso. Es necesario desconnectarse primero.",
                LogLevel.INFORMATION)
            return
        ok = QMessageBox.question(
            self, "Eliminar cuenta",
            "Seguro que quiere eliminar la cuenta {0}?".format(userc))
        if ok == QMessageBox.No:
            self.loggin.emit("Operacion cancelada por el usuario.",
                             LogLevel.INFORMATION)
            return
        self.nauta.card_delete(userc)
        self.nautaw.update_u()

    def load_users(self):
        self.li.clear()
        for i in sorted(self.nauta.get_cards(as_dict=True),
                        key=lambda x: x['username']):
            self.li.addItem(i['username'])