def _make_expression_completer(owner, data_type):
    model = QStringListModel()
    comp = QCompleter(owner)
    comp.setCaseSensitivity(Qt.CaseSensitive)

    if isinstance(data_type, str):
        data_type = uavcan.TYPENAMES[data_type]

    # TODO: implement proper completion, requires Python lexer
    # TODO: IPython/Jupyter solves the same task splendidly, might make sense to take a closer look at their code
    def make_suggestions(t):
        """Builds a flat list of fields in a given data type"""
        if t.category == t.CATEGORY_COMPOUND:
            out = []
            for a in t.fields + t.constants:
                if (a.type.category != a.type.CATEGORY_COMPOUND) and \
                   (a.type.category != a.type.CATEGORY_VOID) and \
                   (a.type.category != a.type.CATEGORY_ARRAY or
                            a.type.value_type.category == a.type.value_type.CATEGORY_PRIMITIVE):
                    out.append(a.name)
                out += [(a.name + x) for x in make_suggestions(a.type)]
            return [('.' + x) for x in out]
        elif t.category == t.CATEGORY_ARRAY:
            base = '[0]'
            if t.value_type.category == t.CATEGORY_COMPOUND:
                return [(base + x) for x in make_suggestions(t.value_type)]
            else:
                return [base]
        return []

    suggestions = [(EXPRESSION_VARIABLE_FOR_MESSAGE + x) for x in make_suggestions(data_type)]

    model.setStringList(suggestions)
    comp.setModel(model)
    return comp
Beispiel #2
0
 def set_auto_completion(self, string_list):
     completer = QCompleter()
     model = QStringListModel()
     model.setStringList(string_list)
     completer.setModel(model)
     completer.activated.connect(self.search, type=Qt.QueuedConnection)
     self.combobox_search.setCompleter(completer)
Beispiel #3
0
class FileSystemOpener(QWidget):
    requestHide = pyqtSignal()
    def __init__(self):
        super(FileSystemOpener, self).__init__()
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        self.btnClose = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.completer = QCompleter(self)
        self.pathLine = ui_tools.LineEditTabCompleter(self.completer)
        fileModel = QFileSystemModel(self.completer)
        fileModel.setRootPath("")
        self.completer.setModel(fileModel)
        self.pathLine.setCompleter(self.completer)
        self.btnOpen = QPushButton(
            self.style().standardIcon(QStyle.SP_ArrowRight), 'Open!')
        hbox.addWidget(self.btnClose)
        hbox.addWidget(QLabel(_translate("FileSystemOpener", "Path:")))
        hbox.addWidget(self.pathLine)
        hbox.addWidget(self.btnOpen)

        self.pathLine.returnPressed.connect(self._open_file)
        self.btnOpen.clicked['bool'].connect(self._open_file)

    def _open_file(self):
        path = self.pathLine.text()
        main_container.MainContainer().open_file(path)
        self.requestHide.emit()

    def showEvent(self, event):
        super(FileSystemOpener, self).showEvent(event)
        self.pathLine.selectAll()
class ManualInstallWidget(QWidget):
    """Manually Installed plugins widget"""

    def __init__(self, parent):
        super(ManualInstallWidget, self).__init__()
        self._parent = parent
        vbox = QVBoxLayout(self)
        form = QFormLayout()
        self._txtName = QLineEdit()
        self._txtName.setPlaceholderText('my_plugin')
        self._txtVersion = QLineEdit()
        self._txtVersion.setPlaceholderText('0.1')
        form.addRow(translations.TR_PROJECT_NAME, self._txtName)
        form.addRow(translations.TR_VERSION, self._txtVersion)
        vbox.addLayout(form)
        hPath = QHBoxLayout()
        self._txtFilePath = QLineEdit()
        self._txtFilePath.setPlaceholderText(os.path.join(
            os.path.expanduser('~'), 'full', 'path', 'to', 'plugin.zip'))
        self._btnFilePath = QPushButton(QIcon(":img/open"), '')
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self._txtFilePath.setCompleter(self.completer)
        hPath.addWidget(QLabel(translations.TR_FILENAME))
        hPath.addWidget(self._txtFilePath)
        hPath.addWidget(self._btnFilePath)
        vbox.addLayout(hPath)
        vbox.addSpacerItem(QSpacerItem(0, 1, QSizePolicy.Expanding,
            QSizePolicy.Expanding))

        hbox = QHBoxLayout()
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        self._btnInstall = QPushButton(translations.TR_INSTALL)
        hbox.addWidget(self._btnInstall)
        vbox.addLayout(hbox)

        #Signals
        self._btnFilePath.clicked['bool'].connect(self._load_plugin_path)
        self._btnInstall.clicked['bool'].connect(self.install_plugin)
        
    def _load_plugin_path(self):
        """Ask the user a plugin filename"""
        path = QFileDialog.getOpenFileName(self,
                                           translations.TR_SELECT_PLUGIN_PATH)
        if path:
            self._txtFilePath.setText(path)

    def install_plugin(self):
        """Install a plugin manually"""
        if self._txtFilePath.text() and self._txtName.text():
            plug = []
            plug.append(self._txtName.text())
            plug.append(self._txtVersion.text())
            plug.append('')
            plug.append('')
            plug.append('')
            plug.append(self._txtFilePath.text())
            self._parent.install_plugins_manually([plug])
Beispiel #5
0
class Completer(QGraphicsProxyWidget, object):
    ''' Class for handling text autocompletion in the SDL scene '''
    def __init__(self, parent):
        ''' Create an autocompletion list popup '''
        widget = QListWidget()
        super(Completer, self).__init__(parent)
        self.setWidget(widget)
        self.string_list = QStringListModel()
        self._completer = QCompleter()
        self.parent = parent
        self._completer.setCaseSensitivity(Qt.CaseInsensitive)
        # For some reason the default minimum size is (61,61)
        # Set it to 0 so that the size of the box is not taken
        # into account when it is hidden.
        self.setMinimumSize(0, 0)
        self.prepareGeometryChange()
        self.resize(0, 0)
        self.hide()

    def set_completer_list(self):
        ''' Set list of items for the autocompleter popup '''
        compl = [item.replace('-', '_') for item in
                 self.parent.parentItem().completion_list]
        self.string_list.setStringList(compl)
        self._completer.setModel(self.string_list)

    def set_completion_prefix(self, completion_prefix):
        '''
            Set the current completion prefix (user-entered text)
            and set the corresponding list of words in the popup widget
        '''
        self._completer.setCompletionPrefix(completion_prefix)
        self.widget().clear()
        count = self._completer.completionCount()
        for i in xrange(count):
            self._completer.setCurrentRow(i)
            self.widget().addItem(self._completer.currentCompletion())
        self.prepareGeometryChange()
        if count:
            self.resize(self.widget().sizeHintForColumn(0) + 40, 70)
        else:
            self.resize(0, 0)
        return count

    # pylint: disable=C0103
    def keyPressEvent(self, e):
        super(Completer, self).keyPressEvent(e)
        if e.key() == Qt.Key_Escape:
            self.parentItem().setFocus()
        # Consume the event so that it is not repeated at EditableText level
        e.accept()

    # pylint: disable=C0103
    def focusOutEvent(self, event):
        ''' When the user leaves the popup, return focus to parent '''
        super(Completer, self).focusOutEvent(event)
        self.hide()
        self.resize(0, 0)
        self.parentItem().setFocus()
Beispiel #6
0
def return_tag_completer_TextEdit(parent=None):
	ns = gallerydb.TagDB.get_all_ns()
	for t in gallerydb.TagDB.get_all_tags():
		ns.append(t)
	TextEditCompleter = CompleterTextEdit()
	comp = QCompleter(ns, parent)
	comp.setCaseSensitivity(Qt.CaseInsensitive)
	TextEditCompleter.setCompleter(comp)
	return TextEditCompleter
 def complete(self, cr, results):
     proposals = []
     proposals += results.get('modules', [])
     proposals += results.get('classes', [])
     proposals += results.get('attributes', [])
     proposals += results.get('functions', [])
     self.model().setStringList(proposals)
     self.popup().setCurrentIndex(self.model().index(0, 0))
     cr.setWidth(self.popup().sizeHintForColumn(0)
                 + self.popup().verticalScrollBar().sizeHint().width() + 10)
     QCompleter.complete(self, cr)
    def __init__(self, winPrincipal):
        self.winPrincipal = winPrincipal
        self.producto = Producto()
        self.proveedor = Proveedor()
        self.marca = Marca()
        self.rubro = Rubro()
        self.estado = ""
        self.conexionProducto = conexionProducto()

        self.completerRubro = QCompleter()
        self.completerMarca = QCompleter()
        self.completerProveedor = QCompleter()
        self.configInit()
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.createMenu()

        self.completingTextEdit = TextEdit()
        self.completer = QCompleter(self)
        self.completer.setModel(self.modelFromFile(':/resources/wordlist.txt'))
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setWrapAround(False)
        self.completingTextEdit.setCompleter(self.completer)

        self.setCentralWidget(self.completingTextEdit)
        self.resize(500, 300)
        self.setWindowTitle("Completer")

    def createMenu(self):
        exitAction = QAction("Exit", self)
        aboutAct = QAction("About", self)
        aboutQtAct = QAction("About Qt", self)

        exitAction.triggered.connect(QApplication.instance().quit)
        aboutAct.triggered.connect(self.about)
        aboutQtAct.triggered.connect(QApplication.instance().aboutQt)

        fileMenu = self.menuBar().addMenu("File")
        fileMenu.addAction(exitAction)

        helpMenu = self.menuBar().addMenu("About")
        helpMenu.addAction(aboutAct)
        helpMenu.addAction(aboutQtAct)

    def modelFromFile(self, fileName):
        f = QFile(fileName)
        if not f.open(QFile.ReadOnly):
            return QStringListModel(self.completer)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        words = []
        while not f.atEnd():
            line = f.readLine().trimmed()
            if line.length() != 0:
                try:
                    line = str(line, encoding='ascii')
                except TypeError:
                    line = str(line)

                words.append(line)

        QApplication.restoreOverrideCursor()

        return QStringListModel(words, self.completer)

    def about(self):
        QMessageBox.about(self, "About",
                "This example demonstrates the different features of the "
                "QCompleter class.")
Beispiel #10
0
    def setupUi(self):
        self.log.debug("Initializing UI.")
        self.load_ui("dta.ui")

        # set up source/target autocompletion
        type_completion_list = [str(t) for t in self.policy.types()]
        type_completer_model = QStringListModel(self)
        type_completer_model.setStringList(sorted(type_completion_list))
        self.type_completion = QCompleter()
        self.type_completion.setModel(type_completer_model)
        self.source.setCompleter(self.type_completion)
        self.target.setCompleter(self.type_completion)

        # setup indications of errors on source/target/default
        self.orig_palette = self.source.palette()
        self.error_palette = self.source.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)
        self.clear_source_error()
        self.clear_target_error()

        # set up processing thread
        self.thread = QThread()
        self.worker = ResultsUpdater(self.query)
        self.worker.moveToThread(self.thread)
        self.worker.raw_line.connect(self.raw_results.appendPlainText)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.update)
        self.thread.finished.connect(self.update_complete)

        # create a "busy, please wait" dialog
        self.busy = QProgressDialog(self)
        self.busy.setModal(True)
        self.busy.setRange(0, 0)
        self.busy.setMinimumDuration(0)
        self.busy.canceled.connect(self.thread.requestInterruption)
        self.busy.reset()

        # update busy dialog from DTA INFO logs
        self.handler = LogHandlerToSignal()
        self.handler.message.connect(self.busy.setLabelText)
        logging.getLogger("setools.dta").addHandler(self.handler)

        # Ensure settings are consistent with the initial .ui state
        self.max_path_length.setEnabled(self.all_paths.isChecked())
        self.source.setEnabled(not self.flows_in.isChecked())
        self.target.setEnabled(not self.flows_out.isChecked())
        self.criteria_frame.setHidden(not self.criteria_expander.isChecked())
        self.notes.setHidden(not self.notes_expander.isChecked())

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.source.textEdited.connect(self.clear_source_error)
        self.source.editingFinished.connect(self.set_source)
        self.target.textEdited.connect(self.clear_target_error)
        self.target.editingFinished.connect(self.set_target)
        self.all_paths.toggled.connect(self.all_paths_toggled)
        self.flows_in.toggled.connect(self.flows_in_toggled)
        self.flows_out.toggled.connect(self.flows_out_toggled)
        self.reverse.stateChanged.connect(self.reverse_toggled)
        self.exclude_types.clicked.connect(self.choose_excluded_types)
    def setCompleterRubro(self):
        listRubros = self.conexionProducto.listRubro()

        self.completerRubro = QCompleter(listRubros)

        self.completerRubro.setCaseSensitivity(QtCore.Qt.CaseInsensitive)

        self.winPrincipal.txtRubro_p.setCompleter(self.completerRubro)
Beispiel #12
0
class CompletingComboBox(QComboBox):
    """An editable combo box that filters and autocompletes."""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setEditable(True)
        self.filter = QSortFilterProxyModel(self)
        self.filter.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.filter.setSourceModel(self.model())
        self.completer = QCompleter(self.filter, self)
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)
        self.lineEdit().textEdited.connect(
            self.filter.setFilterFixedString)
        self.currentIndexChanged.connect(self._index_changed)

    def _index_changed(self, index):
        self.lineEdit().selectAll()
Beispiel #13
0
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(HelpWebSearchWidget, self).__init__(parent)
        
        from E5Gui.E5LineEdit import E5LineEdit
        from E5Gui.E5LineEditButton import E5LineEditButton
        from .OpenSearch.OpenSearchManager import OpenSearchManager

        self.__mw = parent
        
        self.__openSearchManager = OpenSearchManager(self)
        self.__openSearchManager.currentEngineChanged.connect(
            self.__currentEngineChanged)
        self.__currentEngine = ""
        
        self.__enginesMenu = QMenu(self)
        
        self.__engineButton = E5LineEditButton(self)
        self.__engineButton.setMenu(self.__enginesMenu)
        self.addWidget(self.__engineButton, E5LineEdit.LeftSide)
        
        self.__searchButton = E5LineEditButton(self)
        self.__searchButton.setIcon(UI.PixmapCache.getIcon("webSearch.png"))
        self.addWidget(self.__searchButton, E5LineEdit.LeftSide)
        
        self.__model = QStandardItemModel(self)
        self.__completer = QCompleter()
        self.__completer.setModel(self.__model)
        self.__completer.setCompletionMode(
            QCompleter.UnfilteredPopupCompletion)
        self.__completer.setWidget(self)
        
        self.__searchButton.clicked.connect(self.__searchButtonClicked)
        self.textEdited.connect(self.__textEdited)
        self.returnPressed.connect(self.__searchNow)
        self.__completer.activated[QModelIndex].connect(
            self.__completerActivated)
        self.__completer.highlighted[QModelIndex].connect(
            self.__completerHighlighted)
        self.__enginesMenu.aboutToShow.connect(self.__showEnginesMenu)
        
        self.__suggestionsItem = None
        self.__suggestions = []
        self.__suggestTimer = None
        self.__suggestionsEnabled = Preferences.getHelp("WebSearchSuggestions")
        
        self.__recentSearchesItem = None
        self.__recentSearches = []
        self.__maxSavedSearches = 10
        
        self.__engine = None
        self.__loadSearches()
        self.__setupCompleterMenu()
        self.__currentEngineChanged()
    def __init__(self, parent, node, node_monitor):
        super(DynamicNodeIDAllocatorWidget, self).__init__(parent)
        self.setTitle('Dynamic node ID allocation server (uavcan.protocol.dynamic_node_id.*)')

        self._node = node
        self._node_monitor = node_monitor
        self._allocator = None

        self._allocation_table = BasicTable(self, self.COLUMNS, font=get_monospace_font())

        self._allocation_table_update_timer = QTimer(self)
        self._allocation_table_update_timer.setSingleShot(False)
        self._allocation_table_update_timer.start(500)
        self._allocation_table_update_timer.timeout.connect(self._update_table)

        self._start_stop_button = make_icon_button('rocket', 'Launch/stop the dynamic node ID allocation server', self,
                                                   checkable=True)
        self._start_stop_button.clicked.connect(self._on_start_stop_button)

        self._database_file = CommitableComboBoxWithHistory(self)
        self._database_file.setAcceptDrops(True)
        self._database_file.setToolTip('Path to the allocation table file')
        self._database_file.setCurrentText(self.DEFAULT_DATABASE_FILE)
        self._database_file.addItem(self._database_file.currentText())
        self._database_file.on_commit = self._on_start_stop_button

        self._select_database_file = make_icon_button('folder-open-o', 'Open allocation table file', self,
                                                      on_clicked=self._on_select_database_file)

        db_file_completer = QCompleter()
        db_file_completer.setModel(QDirModel(db_file_completer))
        self._database_file.setCompleter(db_file_completer)

        self._sync_gui()

        layout = QVBoxLayout(self)

        controls_layout = QHBoxLayout(self)
        controls_layout.addWidget(self._start_stop_button)
        controls_layout.addWidget(self._database_file, 1)
        controls_layout.addWidget(self._select_database_file)

        layout.addLayout(controls_layout)
        layout.addWidget(self._allocation_table, 1)
        self.setLayout(layout)
Beispiel #15
0
    def __init__(self, device_name: str, project_manager: ProjectManager, signal=None, backend_handler=None,
                 network_raw_mode=False, signals=None, parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

        signals = signals if signals is not None else []
        self.project_manager = project_manager

        for encoding in self.project_manager.decodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.bootstrap(project_manager.device_conf, signal, enforce_default=True)

        self.sniffer = ProtocolSniffer(bit_len=self.ui.spinbox_sniff_BitLen.value(),
                                       center=self.ui.spinbox_sniff_Center.value(),
                                       noise=self.ui.spinbox_sniff_Noise.value(),
                                       tolerance=self.ui.spinbox_sniff_ErrorTolerance.value(),
                                       modulation_type=self.ui.combox_sniff_Modulation.currentIndex(),
                                       device=device_name,
                                       backend_handler=BackendHandler() if backend_handler is None else backend_handler,
                                       network_raw_mode=network_raw_mode)

        self.sniffer.adaptive_noise = self.ui.checkBoxAdaptiveNoise.isChecked()
        self.sniffer.automatic_center = self.ui.checkBoxAutoCenter.isChecked()

        self.create_connects()
        self.ui.comboBox_sniff_encoding.currentIndexChanged.emit(self.ui.comboBox_sniff_encoding.currentIndex())
        self.ui.comboBox_sniff_viewtype.setCurrentIndex(constants.SETTINGS.value('default_view', 0, int))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.signals = signals

        if len(signals) == 0:
            self.ui.label_sniff_Signal.hide()
            self.ui.btn_sniff_use_signal.hide()
            self.ui.comboBox_sniff_signal.hide()
        else:
            for signal in signals:
                self.ui.comboBox_sniff_signal.addItem(signal.name)
Beispiel #16
0
    def __init__(self, filename="", parent=None):
        super().__init__(parent)
        self.ui = Ui_DialogCSVImport()
        self.ui.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.ui.btnAutoDefault.hide()

        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEditFilename.setCompleter(completer)

        self.filename = None  # type: str
        self.ui.lineEditFilename.setText(filename)
        self.update_file()

        self.ui.tableWidgetPreview.setColumnHidden(self.COLUMNS["T"], True)
        self.update_preview()

        self.create_connects()
    def initializePackageList(self):
        self.packageList.model().reset()
        self.packageList.setPackages(self.state.packages())

        if self.completer:
            self.completer.deleteLater()
            del self.completer

        self.completer = QCompleter(self.state.allPackages(), self)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.searchLine.setCompleter(self.completer)
Beispiel #18
0
 def __init__(self, parent=None):
     super().__init__(parent)
     self.setEditable(True)
     self.filter = QSortFilterProxyModel(self)
     self.filter.setFilterCaseSensitivity(Qt.CaseInsensitive)
     self.filter.setSourceModel(self.model())
     self.completer = QCompleter(self.filter, self)
     self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
     self.setCompleter(self.completer)
     self.lineEdit().textEdited.connect(
         self.filter.setFilterFixedString)
     self.currentIndexChanged.connect(self._index_changed)
Beispiel #19
0
    def update_lineEdit_completer(self):
        self.files_in_current_folder = [
            QString(item) for item in os.listdir(str(self.last_folder)) if 
            os.path.isfile(os.path.join(str(self.last_folder), item))
        ]
        self.file_lineEdit_completer = QCompleter(self.files_in_current_folder)
        self.file_lineEdit_completer.setCompletionMode(QCompleter.InlineCompletion)

        self.select_prim_cell_file_lineEdit.setCompleter(self.file_lineEdit_completer)
        self.select_pckpts_file_lineEdit.setCompleter(self.file_lineEdit_completer)
        self.select_energy_file_lineEdit.setCompleter(self.file_lineEdit_completer)
        self.select_EBS_file_lineEdit.setCompleter(self.file_lineEdit_completer)
class FileSystemOpener(QWidget):

    """Widget to handle opening files through path write with completion."""
    requestHide = pyqtSignal()
    def __init__(self):
        super(FileSystemOpener, self).__init__()
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        self.btnClose = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.btnClose
        self.completer = QCompleter(self)
        self.pathLine = ui_tools.LineEditTabCompleter(self.completer)
        fileModel = QFileSystemModel(self.completer)
        fileModel.setRootPath("")
        self.completer.setModel(fileModel)
        self.pathLine.setCompleter(self.completer)
        self.btnOpen = QPushButton(
            self.style().standardIcon(QStyle.SP_ArrowRight), 'Open!')
        hbox.addWidget(self.btnClose)
        hbox.addWidget(QLabel(self.tr("Path:")))
        hbox.addWidget(self.pathLine)
        hbox.addWidget(self.btnOpen)

        self.pathLine.returnPressed.connect(self._open_file)
        self.btnOpen.clicked['bool'].connect(self._open_file)

    def _open_file(self):
        """Open the file selected."""
        path = self.pathLine.text()
        main_container = IDE.get_service("main_container")
        if main_container:
            main_container.open_file(path)
            self.requestHide.emit()

    def showEvent(self, event):
        """Show the FileSystemOpener widget and select all the text."""
        super(FileSystemOpener, self).showEvent(event)
        self.pathLine.selectAll()
Beispiel #21
0
    def __init__(self, parent, completion_model=None):
        super(SearchBarComboBox, self).__init__(parent)

        self.setFont(get_monospace_font())
        self.setToolTip('Enter the search pattern here')
        completer = QCompleter(self)
        completer.setCaseSensitivity(Qt.CaseSensitive)
        if completion_model is not None:
            completer.setModel(completion_model)
        else:
            completer.setModel(self.model())
        self.setCompleter(completer)
    def createEditor(self, manager, property, parent):
        type = manager.propertyType(property)
        if (type == VariantPropertyManager.filePathTypeId()):
            editor = FileEdit(parent)
            editor.setFilePath(manager.value(property))
            editor.setFilter(manager.attributeValue(property, "filter"))
            self.mCreatedEditors[property].append(editor)
            self.mEditorToProperty[editor] = property
            editor.filePathChanged.connect(self.slotSetValue)
            editor.destroyed.connect(self.slotEditorDestroyed)
            return editor

        editor = super().createEditor(manager, property, parent)
        if (type == QVariant.String):
            # Add support for "suggestions" attribute that adds a QCompleter to the QLineEdit
            suggestions = manager.attributeValue(property, "suggestions")
            if suggestions and len(suggestions)>0:
                lineEdit = editor
                if lineEdit:
                    completer = QCompleter(suggestions, lineEdit)
                    completer.setCaseSensitivity(Qt.CaseInsensitive)
                    lineEdit.setCompleter(completer)
        return editor
Beispiel #23
0
    def __init__(self, parent, default=None):
        super(PathItem, self).__init__(parent)

        self.on_remove = lambda _: None
        self.on_path_changed = lambda *_: None

        self._remove_button = make_icon_button('remove', 'Remove this path', self,
                                               on_clicked=lambda: self.on_remove(self))

        completer = QCompleter(self)
        completer.setModel(QDirModel(completer))

        self._path_bar = CommitableComboBoxWithHistory(self)
        if default:
            self._path_bar.setCurrentText(default)
        self._path_bar.setCompleter(completer)
        self._path_bar.setAcceptDrops(True)
        self._path_bar.setToolTip('Lookup path for file services; should point either to a file or to a directory')
        self._path_bar.currentTextChanged.connect(self._on_path_changed)

        self._select_file_button = make_icon_button('file-o', 'Specify file path', self,
                                                    on_clicked=self._on_select_path_file)

        self._select_dir_button = make_icon_button('folder-open-o', 'Specify directory path', self,
                                                   on_clicked=self._on_select_path_directory)

        self._hit_count_label = LabelWithIcon(get_icon('upload'), '0', self)
        self._hit_count_label.setToolTip('Hit count')

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._remove_button)
        layout.addWidget(self._path_bar, 1)
        layout.addWidget(self._select_file_button)
        layout.addWidget(self._select_dir_button)
        layout.addWidget(self._hit_count_label)
        self.setLayout(layout)
Beispiel #24
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.createMenu()

        self.completingTextEdit = TextEdit()
        self.completer = QCompleter(self)
        self.completer.setModel(self.modelFromFile(':/resources/wordlist.txt'))
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setWrapAround(False)
        self.completingTextEdit.setCompleter(self.completer)

        self.setCentralWidget(self.completingTextEdit)
        self.resize(500, 300)
        self.setWindowTitle("Completer")
Beispiel #25
0
 def __init__(self, parent):
     ''' Create an autocompletion list popup '''
     widget = QListWidget()
     super(Completer, self).__init__(parent)
     self.setWidget(widget)
     self.string_list = QStringListModel()
     self._completer = QCompleter()
     self.parent = parent
     self._completer.setCaseSensitivity(Qt.CaseInsensitive)
     # For some reason the default minimum size is (61,61)
     # Set it to 0 so that the size of the box is not taken
     # into account when it is hidden.
     self.setMinimumSize(0, 0)
     self.prepareGeometryChange()
     self.resize(0, 0)
     self.hide()
Beispiel #26
0
	def __init__(self,expdat):
		super(DBAnnotateSave, self).__init__()
		print("DBAnnotateSave")
		uic.loadUi(os.path.join(hs.heatsequerdir,'ui/manualdata.py'), self)
		self.bplus.clicked.connect(self.plus)
		self.bminus.clicked.connect(self.minus)
		self.bontoinput.returnPressed.connect(self.plus)
		self.bstudyinfo.clicked.connect(self.studyinfo)
		self.bisa.toggled.connect(self.radiotoggle)
		self.bdiffpres.toggled.connect(self.radiotoggle)
		self.bisatype.currentIndexChanged.connect(self.isatypechanged)
		self.bhistory.clicked.connect(self.history)
		self.cexp=expdat
		self.lnumbact.setText(str(len(expdat.selectedseqs)))
		completer = QCompleter()
		self.bontoinput.setCompleter(completer)
		scdb=hs.scdb
		self.scdb=scdb
		self.dataid=hs.supercooldb.finddataid(scdb,datamd5=self.cexp.datamd5,mapmd5=self.cexp.mapmd5)

		model = QStringListModel()
		completer.setModel(model)
#		completer.setCompletionMode(QCompleter.InlineCompletion)
		completer.maxVisibleItems=10
		completer.setCaseSensitivity(Qt.CaseInsensitive)

		# make the completer selection also erase the text edit
		completer.activated.connect(self.cleartext,type=Qt.QueuedConnection)

		# in qt5 should work with middle complete as well...
#		completer.setFilterMode(Qt.MatchContains)
		if not hs.scdb.ontologyfromid:
			hs.scdb=hs.supercooldb.loaddbonto(hs.scdb)

		self.ontology=hs.scdb.ontology
		self.ontologyfromid=hs.scdb.ontologyfromid

		nlist=list(self.ontology.keys())
#		nlist=sorted(nlist)
		nlist=sorted(nlist, key=lambda s: s.lower())
		print("sorted ontology")

		model.setStringList(nlist)
		self.setWindowTitle(self.cexp.studyname)
		try:
			tt=hs.lastdatamd5
		except:
			hs.lastdatamd5=''
		if self.cexp.datamd5==hs.lastdatamd5:
			self.fillfromcuration(hs.lastcurations[-1],onlyall=True)

		self.prefillinfo()
		self.bontoinput.setFocus()
Beispiel #27
0
    def __init__(self):
        super(FileSystemOpener, self).__init__()
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        self.btnClose = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.completer = QCompleter(self)
        self.pathLine = ui_tools.LineEditTabCompleter(self.completer)
        fileModel = QFileSystemModel(self.completer)
        fileModel.setRootPath("")
        self.completer.setModel(fileModel)
        self.pathLine.setCompleter(self.completer)
        self.btnOpen = QPushButton(
            self.style().standardIcon(QStyle.SP_ArrowRight), 'Open!')
        hbox.addWidget(self.btnClose)
        hbox.addWidget(QLabel(_translate("FileSystemOpener", "Path:")))
        hbox.addWidget(self.pathLine)
        hbox.addWidget(self.btnOpen)

        self.pathLine.returnPressed.connect(self._open_file)
        self.btnOpen.clicked['bool'].connect(self._open_file)
Beispiel #28
0
    def __init__(self, parent, cli_iface):
        super(CLIWidget, self).__init__(parent)

        self._cli_iface = cli_iface

        self._command_line = CommitableComboBoxWithHistory(self)
        self._command_line.setToolTip('Enter the command here')
        self._command_line.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self._command_line.setFont(get_monospace_font())
        self._command_line.on_commit = self._do_execute

        self._command_line_completer = QCompleter()
        self._command_line_completer.setCaseSensitivity(Qt.CaseSensitive)
        self._command_line_completer.setModel(self._command_line.model())

        self._command_line.setCompleter(self._command_line_completer)

        self._execute_button = make_icon_button('flash', 'Execute command', self, on_clicked=self._do_execute)

        self._response_box = QPlainTextEdit(self)
        self._response_box.setToolTip('Command output will be printed here')
        self._response_box.setReadOnly(True)
        self._response_box.setLineWrapMode(QPlainTextEdit.NoWrap)
        self._response_box.setFont(get_monospace_font())
        self._response_box.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        try:
            self._log_viewer.setPlaceholderText('Command output will be printed here')
        except AttributeError:      # Old PyQt
            pass

        layout = QVBoxLayout(self)

        controls_layout = QHBoxLayout(self)
        controls_layout.addWidget(self._command_line, 1)
        controls_layout.addWidget(self._execute_button)

        layout.addLayout(controls_layout)
        layout.addWidget(self._response_box, 1)
        self.setLayout(layout)
    def __init__(self, parent):
        super(ManualInstallWidget, self).__init__()
        self._parent = parent
        vbox = QVBoxLayout(self)
        form = QFormLayout()
        self._txtName = QLineEdit()
        self._txtName.setPlaceholderText('my_plugin')
        self._txtVersion = QLineEdit()
        self._txtVersion.setPlaceholderText('0.1')
        form.addRow(translations.TR_PROJECT_NAME, self._txtName)
        form.addRow(translations.TR_VERSION, self._txtVersion)
        vbox.addLayout(form)
        hPath = QHBoxLayout()
        self._txtFilePath = QLineEdit()
        self._txtFilePath.setPlaceholderText(os.path.join(
            os.path.expanduser('~'), 'full', 'path', 'to', 'plugin.zip'))
        self._btnFilePath = QPushButton(QIcon(":img/open"), '')
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self._txtFilePath.setCompleter(self.completer)
        hPath.addWidget(QLabel(translations.TR_FILENAME))
        hPath.addWidget(self._txtFilePath)
        hPath.addWidget(self._btnFilePath)
        vbox.addLayout(hPath)
        vbox.addSpacerItem(QSpacerItem(0, 1, QSizePolicy.Expanding,
            QSizePolicy.Expanding))

        hbox = QHBoxLayout()
        hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        self._btnInstall = QPushButton(translations.TR_INSTALL)
        hbox.addWidget(self._btnInstall)
        vbox.addLayout(hbox)

        #Signals
        self._btnFilePath.clicked['bool'].connect(self._load_plugin_path)
        self._btnInstall.clicked['bool'].connect(self.install_plugin)
Beispiel #30
0
    def __init__(self, namespace, parent):
        """Constructor.

        Args:
            namespace: The local namespace of the interpreter.
        """
        super().__init__(parent)
        self.update_font()
        objreg.get('config').changed.connect(self.update_font)
        self.textChanged.connect(self.on_text_changed)

        self._rlcompleter = rlcompleter.Completer(namespace)
        qcompleter = QCompleter(self)
        self._model = QStringListModel(qcompleter)
        qcompleter.setModel(self._model)
        qcompleter.setCompletionMode(
            QCompleter.UnfilteredPopupCompletion)
        qcompleter.setModelSorting(
            QCompleter.CaseSensitivelySortedModel)
        self.setCompleter(qcompleter)

        self._history = cmdhistory.History()
        self.returnPressed.connect(self.on_return_pressed)
    def createTabs(self):
        """Create tabs in main window."""
        try:
            # Initialize tab screen
            self.tabs = QTabWidget()
            self.tab2 = QWidget()
            # self.tabs.resize(300,200)

            # Add tabs
            self.tabs.addTab(self.tab2, _("Custom Match"))

            # Create second tab

            self.tab2.layout = QVBoxLayout()

            container = QHBoxLayout()

            label = QLabel()
            label.setMinimumWidth(self.labelWidth)
            container.addWidget(label, 0)

            label = QLabel(_("Match Format:"))
            label.setMinimumWidth(80)
            container.addWidget(label, 0)

            container.addWidget(QLabel(_("Best of")), 0)

            self.cb_bestof = QComboBox()
            for idx in range(0, hwctool.settings.max_no_sets):
                self.cb_bestof.addItem(str(idx + 1))
            self.cb_bestof.setCurrentIndex(3)
            string = _('"Best of 6/4": First, a Bo5/3 is played and the'
                       ' ace map gets extended to a Bo3 if needed;'
                       ' Best of 2: Bo3 with only two maps played.')
            self.cb_bestof.setToolTip(string)
            self.cb_bestof.setMaximumWidth(40)
            self.cb_bestof.currentIndexChanged.connect(self.changeBestOf)
            container.addWidget(self.cb_bestof, 0)

            container.addWidget(QLabel(_(" but at least")), 0)

            self.cb_minSets = QComboBox()

            self.cb_minSets.setToolTip(
                _('Minimum number of maps played (even if the match'
                  ' is decided already)'))
            self.cb_minSets.setMaximumWidth(40)
            container.addWidget(self.cb_minSets, 0)
            container.addWidget(QLabel(" " + _("maps") + "  "), 0)
            self.cb_minSets.currentIndexChanged.connect(
                lambda idx: self.highlightApplyCustom())

            label = QLabel("")
            container.addWidget(label, 1)

            self.applycustom_is_highlighted = False

            self.pb_applycustom = QToolButton()
            action = QAction(_("Apply Format"))
            action.triggered.connect(self.applycustom_click)
            self.pb_applycustom.setDefaultAction(action)

            self.pb_applycustom.setFixedWidth(150)
            container.addWidget(self.pb_applycustom, 0)

            self.defaultButtonPalette = self.pb_applycustom.palette()

            self.tab2.layout.addLayout(container)

            container = QHBoxLayout()

            label = QLabel()
            label.setMinimumWidth(self.labelWidth)
            container.addWidget(label, 0)

            label = QLabel(_("Match-URL:"))
            label.setMinimumWidth(80)
            container.addWidget(label, 0)

            self.le_url_custom = MonitoredLineEdit()
            self.le_url_custom.setAlignment(Qt.AlignCenter)
            self.le_url_custom.setToolTip(
                _('Optionally specify the Match-URL,'
                  ' e.g., for Nightbot commands'))
            self.le_url_custom.setPlaceholderText(
                _("Specify the Match-URL of your Custom Match"))

            completer = QCompleter(["http://"], self.le_url_custom)
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
            completer.setWrapAround(True)
            self.le_url_custom.setCompleter(completer)
            self.le_url_custom.setMinimumWidth(360)
            self.le_url_custom.textModified.connect(self.highlightApplyCustom)

            container.addWidget(self.le_url_custom, 11)

            label = QLabel("")
            container.addWidget(label, 1)

            self.pb_resetdata = QPushButton(_("Reset Match Data"))
            self.pb_resetdata.setFixedWidth(150)
            self.pb_resetdata.clicked.connect(self.resetdata_click)
            container.addWidget(self.pb_resetdata, 0)

            self.tab2.layout.addLayout(container)

            self.tab2.setLayout(self.tab2.layout)

        except Exception as e:
            module_logger.exception("message")
class SeedLayout(QVBoxLayout):
    def seed_options(self):
        dialog = QDialog()
        vbox = QVBoxLayout(dialog)
        if 'ext' in self.options:
            cb_ext = QCheckBox(_('Extend this seed with custom words'))
            cb_ext.setChecked(self.is_ext)
            vbox.addWidget(cb_ext)
        if 'bip39' in self.options:

            def f(b):
                self.is_seed = (lambda x: bool(x)) if b else self.saved_is_seed
                self.is_bip39 = b
                self.on_edit()
                if b:
                    msg = ' '.join([
                        '<b>' + _('Warning') + ':</b>  ',
                        _('BIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'
                          ),
                        _('However, we do not generate BIP39 seeds, because they do not meet our safety standard.'
                          ),
                        _('BIP39 seeds do not include a version number, which compromises compatibility with future software.'
                          ),
                        _('We do not guarantee that BIP39 imports will always be supported in Electrum.'
                          ),
                    ])
                else:
                    msg = ''
                self.seed_warning.setText(msg)

            cb_bip39 = QCheckBox(_('BIP39 seed'))
            cb_bip39.toggled.connect(f)
            cb_bip39.setChecked(self.is_bip39)
            vbox.addWidget(cb_bip39)
        vbox.addLayout(Buttons(OkButton(dialog)))
        if not dialog.exec_():
            return None
        self.is_ext = cb_ext.isChecked() if 'ext' in self.options else False
        self.is_bip39 = cb_bip39.isChecked(
        ) if 'bip39' in self.options else False

    def __init__(
        self,
        seed=None,
        title=None,
        icon=True,
        msg=None,
        options=None,
        is_seed=None,
        passphrase=None,
        parent=None,
        for_seed_words=True,
        *,
        config: 'SimpleConfig',
    ):
        QVBoxLayout.__init__(self)
        self.parent = parent
        self.options = options
        self.config = config
        if title:
            self.addWidget(WWLabel(title))
        if seed:  # "read only", we already have the text
            if for_seed_words:
                self.seed_e = ButtonsTextEdit()
            else:  # e.g. xpub
                self.seed_e = ShowQRTextEdit(config=self.config)
            self.seed_e.setReadOnly(True)
            self.seed_e.setText(seed)
        else:  # we expect user to enter text
            assert for_seed_words
            self.seed_e = CompletionTextEdit()
            self.seed_e.setTabChangesFocus(False)  # so that tab auto-completes
            self.is_seed = is_seed
            self.saved_is_seed = self.is_seed
            self.seed_e.textChanged.connect(self.on_edit)
            self.initialize_completer()

        self.seed_e.setMaximumHeight(75)
        hbox = QHBoxLayout()
        if icon:
            logo = QLabel()
            logo.setPixmap(
                QPixmap(icon_path("seed.png")).scaledToWidth(
                    64, mode=Qt.SmoothTransformation))
            logo.setMaximumWidth(60)
            hbox.addWidget(logo)
        hbox.addWidget(self.seed_e)
        self.addLayout(hbox)
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        self.seed_type_label = QLabel('')
        hbox.addWidget(self.seed_type_label)

        # options
        self.is_bip39 = False
        self.is_ext = False
        if options:
            opt_button = EnterButton(_('Options'), self.seed_options)
            hbox.addWidget(opt_button)
            self.addLayout(hbox)
        if passphrase:
            hbox = QHBoxLayout()
            passphrase_e = QLineEdit()
            passphrase_e.setText(passphrase)
            passphrase_e.setReadOnly(True)
            hbox.addWidget(QLabel(_("Your seed extension is") + ':'))
            hbox.addWidget(passphrase_e)
            self.addLayout(hbox)
        self.addStretch(1)
        self.seed_warning = WWLabel('')
        if msg:
            self.seed_warning.setText(seed_warning_msg(seed))
        self.addWidget(self.seed_warning)

    def initialize_completer(self):
        bip39_english_list = Mnemonic('en').wordlist
        old_list = old_mnemonic.wordlist
        only_old_list = set(old_list) - set(bip39_english_list)
        self.wordlist = list(bip39_english_list) + list(
            only_old_list)  # concat both lists
        self.wordlist.sort()

        class CompleterDelegate(QStyledItemDelegate):
            def initStyleOption(self, option, index):
                super().initStyleOption(option, index)
                # Some people complained that due to merging the two word lists,
                # it is difficult to restore from a metal backup, as they planned
                # to rely on the "4 letter prefixes are unique in bip39 word list" property.
                # So we color words that are only in old list.
                if option.text in only_old_list:
                    # yellow bg looks ~ok on both light/dark theme, regardless if (un)selected
                    option.backgroundBrush = ColorScheme.YELLOW.as_color(
                        background=True)

        self.completer = QCompleter(self.wordlist)
        delegate = CompleterDelegate(self.seed_e)
        self.completer.popup().setItemDelegate(delegate)
        self.seed_e.set_completer(self.completer)

    def get_seed(self):
        text = self.seed_e.text()
        return ' '.join(text.split())

    def on_edit(self):
        s = self.get_seed()
        b = self.is_seed(s)
        if not self.is_bip39:
            t = seed_type(s)
            label = _('Seed Type') + ': ' + t if t else ''
        else:
            from electrum_mona.keystore import bip39_is_checksum_valid
            is_checksum, is_wordlist = bip39_is_checksum_valid(s)
            status = ('checksum: ' + ('ok' if is_checksum else 'failed')
                      ) if is_wordlist else 'unknown wordlist'
            label = 'BIP39' + ' (%s)' % status
        self.seed_type_label.setText(label)
        self.parent.next_button.setEnabled(b)

        # disable suggestions if user already typed an unknown word
        for word in self.get_seed().split(" ")[:-1]:
            if word not in self.wordlist:
                self.seed_e.disable_suggestions()
                return
        self.seed_e.enable_suggestions()
Beispiel #33
0
 def pathFromIndex(self, index):
     path = QCompleter.pathFromIndex(self, index)
     words = self.widget().text().split("-")
     if len(words) > 1:
         path = "{}-{}".format("-".join(words[:-1]), path)
     return path
Beispiel #34
0
    def __init__(self, core_args=None, core_env=None, api_port=None, api_key=None):
        QMainWindow.__init__(self)
        self._logger = logging.getLogger(self.__class__.__name__)

        QCoreApplication.setOrganizationDomain("nl")
        QCoreApplication.setOrganizationName("TUDelft")
        QCoreApplication.setApplicationName("Tribler")

        self.setWindowIcon(QIcon(QPixmap(get_image_path('tribler.png'))))

        self.gui_settings = QSettings('nl.tudelft.tribler')
        api_port = api_port or int(get_gui_setting(self.gui_settings, "api_port", DEFAULT_API_PORT))
        api_key = api_key or get_gui_setting(self.gui_settings, "api_key", hexlify(os.urandom(16)).encode('utf-8'))
        self.gui_settings.setValue("api_key", api_key)

        api_port = get_first_free_port(start=api_port, limit=100)
        request_manager.port, request_manager.key = api_port, api_key

        self.tribler_started = False
        self.tribler_settings = None
        # TODO: move version_id to tribler_common and get core version in the core crash message
        self.tribler_version = version_id
        self.debug_window = None

        self.error_handler = ErrorHandler(self)
        self.core_manager = CoreManager(api_port, api_key, self.error_handler)
        self.pending_requests = {}
        self.pending_uri_requests = []
        self.download_uri = None
        self.dialog = None
        self.create_dialog = None
        self.chosen_dir = None
        self.new_version_dialog = None
        self.start_download_dialog_active = False
        self.selected_torrent_files = []
        self.has_search_results = False
        self.last_search_query = None
        self.last_search_time = None
        self.start_time = time.time()
        self.token_refresh_timer = None
        self.shutdown_timer = None
        self.add_torrent_url_dialog_active = False

        sys.excepthook = self.error_handler.gui_error

        uic.loadUi(get_ui_file_path('mainwindow.ui'), self)
        TriblerRequestManager.window = self
        self.tribler_status_bar.hide()

        self.token_balance_widget.mouseReleaseEvent = self.on_token_balance_click

        def on_state_update(new_state):
            self.loading_text_label.setText(new_state)

        connect(self.core_manager.core_state_update, on_state_update)

        self.magnet_handler = MagnetHandler(self.window)
        QDesktopServices.setUrlHandler("magnet", self.magnet_handler, "on_open_magnet_link")

        self.debug_pane_shortcut = QShortcut(QKeySequence("Ctrl+d"), self)
        connect(self.debug_pane_shortcut.activated, self.clicked_menu_button_debug)
        self.import_torrent_shortcut = QShortcut(QKeySequence("Ctrl+o"), self)
        connect(self.import_torrent_shortcut.activated, self.on_add_torrent_browse_file)
        self.add_torrent_url_shortcut = QShortcut(QKeySequence("Ctrl+i"), self)
        connect(self.add_torrent_url_shortcut.activated, self.on_add_torrent_from_url)

        connect(self.top_search_bar.clicked, self.clicked_search_bar)

        # Remove the focus rect on OS X
        for widget in self.findChildren(QLineEdit) + self.findChildren(QListWidget) + self.findChildren(QTreeWidget):
            widget.setAttribute(Qt.WA_MacShowFocusRect, 0)

        self.menu_buttons = [
            self.left_menu_button_downloads,
            self.left_menu_button_discovered,
            self.left_menu_button_trust_graph,
            self.left_menu_button_popular,
        ]
        hide_xxx = get_gui_setting(self.gui_settings, "family_filter", True, is_bool=True)
        self.search_results_page.initialize_content_page(hide_xxx=hide_xxx)
        self.search_results_page.channel_torrents_filter_input.setHidden(True)

        self.settings_page.initialize_settings_page()
        self.downloads_page.initialize_downloads_page()
        self.loading_page.initialize_loading_page()
        self.discovering_page.initialize_discovering_page()

        self.discovered_page.initialize_content_page(hide_xxx=hide_xxx)

        self.popular_page.initialize_content_page(hide_xxx=hide_xxx)

        self.trust_page.initialize_trust_page()
        self.trust_graph_page.initialize_trust_graph()

        self.stackedWidget.setCurrentIndex(PAGE_LOADING)

        # Create the system tray icon
        if QSystemTrayIcon.isSystemTrayAvailable():
            self.tray_icon = QSystemTrayIcon()
            use_monochrome_icon = get_gui_setting(self.gui_settings, "use_monochrome_icon", False, is_bool=True)
            self.update_tray_icon(use_monochrome_icon)

            # Create the tray icon menu
            menu = self.create_add_torrent_menu()
            show_downloads_action = QAction('Show downloads', self)
            connect(show_downloads_action.triggered, self.clicked_menu_button_downloads)
            token_balance_action = QAction('Show token balance', self)
            connect(token_balance_action.triggered, lambda _: self.on_token_balance_click(None))
            quit_action = QAction('Quit Tribler', self)
            connect(quit_action.triggered, self.close_tribler)
            menu.addSeparator()
            menu.addAction(show_downloads_action)
            menu.addAction(token_balance_action)
            menu.addSeparator()
            menu.addAction(quit_action)
            self.tray_icon.setContextMenu(menu)
        else:
            self.tray_icon = None

        self.left_menu_button_debug.setHidden(True)
        self.top_menu_button.setHidden(True)
        self.left_menu.setHidden(True)
        self.token_balance_widget.setHidden(True)
        self.settings_button.setHidden(True)
        self.add_torrent_button.setHidden(True)
        self.top_search_bar.setHidden(True)

        # Set various icons
        self.top_menu_button.setIcon(QIcon(get_image_path('menu.png')))

        self.search_completion_model = QStringListModel()
        completer = QCompleter()
        completer.setModel(self.search_completion_model)
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.item_delegate = QStyledItemDelegate()
        completer.popup().setItemDelegate(self.item_delegate)
        completer.popup().setStyleSheet(
            """
        QListView {
            background-color: #404040;
        }

        QListView::item {
            color: #D0D0D0;
            padding-top: 5px;
            padding-bottom: 5px;
        }

        QListView::item:hover {
            background-color: #707070;
        }
        """
        )
        self.top_search_bar.setCompleter(completer)

        # Toggle debug if developer mode is enabled
        self.window().left_menu_button_debug.setHidden(
            not get_gui_setting(self.gui_settings, "debug", False, is_bool=True)
        )

        # Start Tribler
        self.core_manager.start(core_args=core_args, core_env=core_env)

        connect(self.core_manager.events_manager.torrent_finished, self.on_torrent_finished)
        connect(self.core_manager.events_manager.new_version_available, self.on_new_version_available)
        connect(self.core_manager.events_manager.tribler_started, self.on_tribler_started)
        connect(self.core_manager.events_manager.low_storage_signal, self.on_low_storage)
        connect(self.core_manager.events_manager.tribler_shutdown_signal, self.on_tribler_shutdown_state_update)
        connect(self.core_manager.events_manager.config_error_signal, self.on_config_error_signal)

        # Install signal handler for ctrl+c events
        def sigint_handler(*_):
            self.close_tribler()

        signal.signal(signal.SIGINT, sigint_handler)

        # Resize the window according to the settings
        center = QApplication.desktop().availableGeometry(self).center()
        pos = self.gui_settings.value("pos", QPoint(center.x() - self.width() * 0.5, center.y() - self.height() * 0.5))
        size = self.gui_settings.value("size", self.size())

        self.move(pos)
        self.resize(size)

        self.show()

        self.add_to_channel_dialog = AddToChannelDialog(self.window())

        self.add_torrent_menu = self.create_add_torrent_menu()
        self.add_torrent_button.setMenu(self.add_torrent_menu)

        self.channels_menu_list = self.findChild(ChannelsMenuListWidget, "channels_menu_list")

        connect(self.channels_menu_list.itemClicked, self.open_channel_contents_page)

        # The channels content page is only used to show subscribed channels, so we always show xxx
        # contents in it.
        connect(
            self.core_manager.events_manager.node_info_updated,
            lambda data: self.channels_menu_list.reload_if_necessary([data]),
        )
        connect(self.left_menu_button_new_channel.clicked, self.create_new_channel)
Beispiel #35
0
class SeedLayout(QVBoxLayout):

    def seed_options(self):
        dialog = QDialog()
        vbox = QVBoxLayout(dialog)

        seed_types = [
            (value, title) for value, title in (
                ('electrum', _('Electrum')),
                ('bip39', _('BIP39 seed')),
                ('slip39', _('SLIP39 seed')),
            )
            if value in self.options or value == 'electrum'
        ]
        seed_type_values = [t[0] for t in seed_types]

        if 'ext' in self.options:
            cb_ext = QCheckBox(_('Extend this seed with custom words'))
            cb_ext.setChecked(self.is_ext)
            vbox.addWidget(cb_ext)
        if len(seed_types) >= 2:
            def f(choices_layout):
                self.seed_type = seed_type_values[choices_layout.selected_index()]
                self.is_seed = (lambda x: bool(x)) if self.seed_type != 'electrum' else self.saved_is_seed
                self.slip39_current_mnemonic_invalid = None
                self.seed_status.setText('')
                self.on_edit()
                if self.seed_type == 'bip39':
                    msg = ' '.join([
                        '<b>' + _('Warning') + ':</b>  ',
                        _('BIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'),
                        _('However, we do not generate BIP39 seeds, because they do not meet our safety standard.'),
                        _('BIP39 seeds do not include a version number, which compromises compatibility with future software.'),
                        _('We do not guarantee that BIP39 imports will always be supported in Electrum.'),
                    ])
                elif self.seed_type == 'slip39':
                    msg = ' '.join([
                        '<b>' + _('Warning') + ':</b>  ',
                        _('SLIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'),
                        _('However, we do not generate SLIP39 seeds.'),
                    ])
                else:
                    msg = ''
                self.update_share_buttons()
                self.initialize_completer()
                self.seed_warning.setText(msg)

            checked_index = seed_type_values.index(self.seed_type)
            titles = [t[1] for t in seed_types]
            clayout = ChoicesLayout(_('Seed type'), titles, on_clicked=f, checked_index=checked_index)
            vbox.addLayout(clayout.layout())

        vbox.addLayout(Buttons(OkButton(dialog)))
        if not dialog.exec_():
            return None
        self.is_ext = cb_ext.isChecked() if 'ext' in self.options else False
        self.seed_type = seed_type_values[clayout.selected_index()] if len(seed_types) >= 2 else 'electrum'

    def __init__(
            self,
            seed=None,
            title=None,
            icon=True,
            msg=None,
            options=None,
            is_seed=None,
            passphrase=None,
            parent=None,
            for_seed_words=True,
            *,
            config: 'SimpleConfig',
    ):
        QVBoxLayout.__init__(self)
        self.parent = parent
        self.options = options
        self.config = config
        self.seed_type = 'electrum'
        if title:
            self.addWidget(WWLabel(title))
        if seed:  # "read only", we already have the text
            if for_seed_words:
                self.seed_e = ButtonsTextEdit()
            else:  # e.g. xpub
                self.seed_e = ShowQRTextEdit(config=self.config)
            self.seed_e.setReadOnly(True)
            self.seed_e.setText(seed)
        else:  # we expect user to enter text
            assert for_seed_words
            self.seed_e = CompletionTextEdit()
            self.seed_e.setTabChangesFocus(False)  # so that tab auto-completes
            self.is_seed = is_seed
            self.saved_is_seed = self.is_seed
            self.seed_e.textChanged.connect(self.on_edit)
            self.initialize_completer()

        self.seed_e.setMaximumHeight(75)
        hbox = QHBoxLayout()
        if icon:
            logo = QLabel()
            logo.setPixmap(QPixmap(icon_path("seed.png"))
                           .scaledToWidth(64, mode=Qt.SmoothTransformation))
            logo.setMaximumWidth(60)
            hbox.addWidget(logo)
        hbox.addWidget(self.seed_e)
        self.addLayout(hbox)
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        self.seed_type_label = QLabel('')
        hbox.addWidget(self.seed_type_label)

        # options
        self.is_ext = False
        if options:
            opt_button = EnterButton(_('Options'), self.seed_options)
            hbox.addWidget(opt_button)
            self.addLayout(hbox)
        if passphrase:
            hbox = QHBoxLayout()
            passphrase_e = QLineEdit()
            passphrase_e.setText(passphrase)
            passphrase_e.setReadOnly(True)
            hbox.addWidget(QLabel(_("Your seed extension is") + ':'))
            hbox.addWidget(passphrase_e)
            self.addLayout(hbox)

        # slip39 shares
        self.slip39_mnemonic_index = 0
        self.slip39_mnemonics = [""]
        self.slip39_seed = None
        self.slip39_current_mnemonic_invalid = None
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        self.prev_share_btn = QPushButton(_("Previous share"))
        self.prev_share_btn.clicked.connect(self.on_prev_share)
        hbox.addWidget(self.prev_share_btn)
        self.next_share_btn = QPushButton(_("Next share"))
        self.next_share_btn.clicked.connect(self.on_next_share)
        hbox.addWidget(self.next_share_btn)
        self.update_share_buttons()
        self.addLayout(hbox)

        self.addStretch(1)
        self.seed_status = WWLabel('')
        self.addWidget(self.seed_status)
        self.seed_warning = WWLabel('')
        if msg:
            self.seed_warning.setText(seed_warning_msg(seed))
        self.addWidget(self.seed_warning)

    def initialize_completer(self):
        if self.seed_type != 'slip39':
            bip39_english_list = Mnemonic('en').wordlist
            old_list = old_mnemonic.wordlist
            only_old_list = set(old_list) - set(bip39_english_list)
            self.wordlist = list(bip39_english_list) + list(only_old_list)  # concat both lists
            self.wordlist.sort()

            class CompleterDelegate(QStyledItemDelegate):
                def initStyleOption(self, option, index):
                    super().initStyleOption(option, index)
                    # Some people complained that due to merging the two word lists,
                    # it is difficult to restore from a metal backup, as they planned
                    # to rely on the "4 letter prefixes are unique in bip39 word list" property.
                    # So we color words that are only in old list.
                    if option.text in only_old_list:
                        # yellow bg looks ~ok on both light/dark theme, regardless if (un)selected
                        option.backgroundBrush = ColorScheme.YELLOW.as_color(background=True)

            delegate = CompleterDelegate(self.seed_e)
        else:
            self.wordlist = list(slip39.get_wordlist())
            delegate = None

        self.completer = QCompleter(self.wordlist)
        if delegate:
            self.completer.popup().setItemDelegate(delegate)
        self.seed_e.set_completer(self.completer)

    def get_seed_words(self):
        return self.seed_e.text().split()

    def get_seed(self):
        if self.seed_type != 'slip39':
            return ' '.join(self.get_seed_words())
        else:
            return self.slip39_seed

    def on_edit(self):
        s = ' '.join(self.get_seed_words())
        b = self.is_seed(s)
        if self.seed_type == 'bip39':
            from electrum.keystore import bip39_is_checksum_valid
            is_checksum, is_wordlist = bip39_is_checksum_valid(s)
            status = ('checksum: ' + ('ok' if is_checksum else 'failed')) if is_wordlist else 'unknown wordlist'
            label = 'BIP39' + ' (%s)'%status
        elif self.seed_type == 'slip39':
            self.slip39_mnemonics[self.slip39_mnemonic_index] = s
            try:
                slip39.decode_mnemonic(s)
            except slip39.Slip39Error as e:
                share_status = str(e)
                current_mnemonic_invalid = True
            else:
                share_status = _('Valid.')
                current_mnemonic_invalid = False

            label = _('SLIP39 share') + ' #%d: %s' % (self.slip39_mnemonic_index + 1, share_status)

            # No need to process mnemonics if the current mnemonic remains invalid after editing.
            if not (self.slip39_current_mnemonic_invalid and current_mnemonic_invalid):
                self.slip39_seed, seed_status = slip39.process_mnemonics(self.slip39_mnemonics)
                self.seed_status.setText(seed_status)
            self.slip39_current_mnemonic_invalid = current_mnemonic_invalid

            b = self.slip39_seed is not None
            self.update_share_buttons()
        else:
            t = seed_type(s)
            label = _('Seed Type') + ': ' + t if t else ''

        self.seed_type_label.setText(label)
        self.parent.next_button.setEnabled(b)

        # disable suggestions if user already typed an unknown word
        for word in self.get_seed_words()[:-1]:
            if word not in self.wordlist:
                self.seed_e.disable_suggestions()
                return
        self.seed_e.enable_suggestions()

    def update_share_buttons(self):
        if self.seed_type != 'slip39':
            self.prev_share_btn.hide()
            self.next_share_btn.hide()
            return

        finished = self.slip39_seed is not None
        self.prev_share_btn.show()
        self.next_share_btn.show()
        self.prev_share_btn.setEnabled(self.slip39_mnemonic_index != 0)
        self.next_share_btn.setEnabled(
            # already pressed "prev" and undoing that:
            self.slip39_mnemonic_index < len(self.slip39_mnemonics) - 1
            # finished entering latest share and starting new one:
            or (bool(self.seed_e.text().strip()) and not self.slip39_current_mnemonic_invalid and not finished)
        )

    def on_prev_share(self):
        if not self.slip39_mnemonics[self.slip39_mnemonic_index]:
            del self.slip39_mnemonics[self.slip39_mnemonic_index]

        self.slip39_mnemonic_index -= 1
        self.seed_e.setText(self.slip39_mnemonics[self.slip39_mnemonic_index])
        self.slip39_current_mnemonic_invalid = None

    def on_next_share(self):
        if not self.slip39_mnemonics[self.slip39_mnemonic_index]:
            del self.slip39_mnemonics[self.slip39_mnemonic_index]
        else:
            self.slip39_mnemonic_index += 1

        if len(self.slip39_mnemonics) <= self.slip39_mnemonic_index:
            self.slip39_mnemonics.append("")
            self.seed_e.setFocus()
        self.seed_e.setText(self.slip39_mnemonics[self.slip39_mnemonic_index])
        self.slip39_current_mnemonic_invalid = None
Beispiel #36
0
    def __init__(self,
                 installed_plugins,
                 highlighted_plugins=None,
                 parent=None):
        super().__init__(parent)

        self.backend_handler = BackendHandler()
        self.backend_handler.set_gnuradio_installed_status()

        self.ui = Ui_DialogOptions()
        self.ui.setupUi(self)
        self.setWindowFlags(Qt.Window)

        self.device_options_model = DeviceOptionsTableModel(
            self.backend_handler, self)
        self.device_options_model.update()
        self.ui.tblDevices.setModel(self.device_options_model)
        self.ui.tblDevices.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)

        self.ui.tblDevices.setItemDelegateForColumn(
            1, ComboBoxDelegate(["native", "GNU Radio"]))

        self.setAttribute(Qt.WA_DeleteOnClose)
        layout = QHBoxLayout(self.ui.tab_plugins)
        self.plugin_controller = PluginFrame(installed_plugins,
                                             highlighted_plugins,
                                             parent=self)
        layout.addWidget(self.plugin_controller)
        self.ui.tab_plugins.setLayout(layout)

        self.ui.btnViewBuildLog.hide()
        self.build_log = ""

        # We use bundled native device backends on windows, so no need to reconfigure them
        self.ui.groupBoxNativeOptions.setVisible(sys.platform != "win32")
        self.ui.labelIconTheme.setVisible(sys.platform == "linux")
        self.ui.comboBoxIconTheme.setVisible(sys.platform == "linux")

        self.ui.comboBoxTheme.setCurrentIndex(
            constants.SETTINGS.value("theme_index", 0, int))
        self.ui.comboBoxIconTheme.setCurrentIndex(
            constants.SETTINGS.value("icon_theme_index", 0, int))
        self.ui.checkBoxShowConfirmCloseDialog.setChecked(
            not constants.SETTINGS.value('not_show_close_dialog', False, bool))
        self.ui.checkBoxHoldShiftToDrag.setChecked(
            constants.SETTINGS.value('hold_shift_to_drag', True, bool))
        self.ui.checkBoxDefaultFuzzingPause.setChecked(
            constants.SETTINGS.value('use_default_fuzzing_pause', True, bool))

        self.ui.checkBoxAlignLabels.setChecked(
            constants.SETTINGS.value('align_labels', True, bool))

        self.ui.doubleSpinBoxRAMThreshold.setValue(
            100 * constants.SETTINGS.value('ram_threshold', 0.6, float))

        self.ui.radioButtonGnuradioDirectory.setChecked(
            self.backend_handler.use_gnuradio_install_dir)
        self.ui.radioButtonPython2Interpreter.setChecked(
            not self.backend_handler.use_gnuradio_install_dir)
        if self.backend_handler.gnuradio_install_dir:
            self.ui.lineEditGnuradioDirectory.setText(
                self.backend_handler.gnuradio_install_dir)
        if self.backend_handler.python2_exe:
            self.ui.lineEditPython2Interpreter.setText(
                self.backend_handler.python2_exe)

        self.ui.doubleSpinBoxFuzzingPause.setValue(
            constants.SETTINGS.value("default_fuzzing_pause", 10**6, int))
        self.ui.doubleSpinBoxFuzzingPause.setEnabled(
            constants.SETTINGS.value('use_default_fuzzing_pause', True, bool))

        self.ui.checkBoxMultipleModulations.setChecked(
            constants.SETTINGS.value("multiple_modulations", False, bool))

        self.ui.radioButtonLowModulationAccuracy.setChecked(
            Modulator.get_dtype() == np.int8)
        self.ui.radioButtonMediumModulationAccuracy.setChecked(
            Modulator.get_dtype() == np.int16)
        self.ui.radioButtonHighModulationAccuracy.setChecked(
            Modulator.get_dtype() == np.float32)

        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEditPython2Interpreter.setCompleter(completer)
        self.ui.lineEditGnuradioDirectory.setCompleter(completer)

        self.ui.spinBoxFontSize.setValue(qApp.font().pointSize())

        self.refresh_device_tab()

        self.create_connects()
        self.old_show_pause_as_time = False

        self.field_type_table_model = FieldTypeTableModel([], parent=self)
        self.ui.tblLabeltypes.setModel(self.field_type_table_model)
        self.ui.tblLabeltypes.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)

        self.ui.tblLabeltypes.setItemDelegateForColumn(
            1,
            ComboBoxDelegate([f.name for f in FieldType.Function],
                             return_index=False,
                             parent=self))
        self.ui.tblLabeltypes.setItemDelegateForColumn(
            2, ComboBoxDelegate(ProtocolLabel.DISPLAY_FORMATS, parent=self))

        self.read_options()

        self.old_default_view = self.ui.comboBoxDefaultView.currentIndex()
        self.old_num_sending_repeats = self.ui.spinBoxNumSendingRepeats.value()
        self.ui.labelRebuildNativeStatus.setText("")

        self.show_available_colormaps()

        try:
            self.restoreGeometry(
                constants.SETTINGS.value("{}/geometry".format(
                    self.__class__.__name__)))
        except TypeError:
            pass
Beispiel #37
0
    def insertFromPath(self):
        dialogue = QDialog(self)
        layout = QHBoxLayout()
        dialogue.setLayout(layout)

        editor = QLineEdit()
        layout.addWidget(editor)

        completer = QCompleter()
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setFilterMode(Qt.MatchContains)
        completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)

        editor.setCompleter(completer)

        model = QStringListModel()
        completion_paths = self.hive_finder.all_hives
        model.setStringList(completion_paths)

        completer.setModel(model)

        def on_return():
            widget = self.tab_widget.currentWidget()

            if not isinstance(widget, NodeEditorSpace):
                return

            reference_path = editor.text()
            widget.addNodeAtMouse(reference_path, NodeTypes.HIVE)
            dialogue.close()

        editor.returnPressed.connect(on_return)

        dialogue.setWindowTitle("Add Hive From Path")
        dialogue.setAttribute(Qt.WA_DeleteOnClose)
        dialogue.exec_()
Beispiel #38
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__()
        QNetworkProxyFactory.setUseSystemConfiguration(True)
        self.statusBar().showMessage(__doc__ + get_nuitka_version())
        self.setWindowTitle(__doc__.strip().capitalize())
        self.setMinimumSize(480, 400)
        self.setMaximumSize(1024, 800)
        self.resize(self.minimumSize())
        self.setWindowIcon(QIcon.fromTheme("python"))
        self.center()
        QShortcut("Ctrl+q", self, activated=lambda: self.close())
        self.menuBar().addMenu("&File").addAction("Exit", lambda: self.close())
        windowMenu = self.menuBar().addMenu("&Window")
        windowMenu.addAction("Minimize", lambda: self.showMinimized())
        windowMenu.addAction("Maximize", lambda: self.showMaximized())
        windowMenu.addAction("Restore", lambda: self.showNormal())
        windowMenu.addAction("FullScreen", lambda: self.showFullScreen())
        windowMenu.addAction("Center", lambda: self.center())
        windowMenu.addAction("Top-Left", lambda: self.move(0, 0))
        windowMenu.addAction("To Mouse", lambda: self.move_to_mouse_position())
        windowMenu.addSeparator()
        windowMenu.addAction(
            "Increase size", lambda:
            self.resize(self.size().width() * 1.4, self.size().height() * 1.4))
        windowMenu.addAction("Decrease size", lambda: self.resize(
            self.size().width() // 1.4, self.size().height() // 1.4))
        windowMenu.addAction("Minimum size", lambda:
                             self.resize(self.minimumSize()))
        windowMenu.addAction("Maximum size", lambda:
                             self.resize(self.maximumSize()))
        windowMenu.addAction("Horizontal Wide", lambda: self.resize(
            self.maximumSize().width(), self.minimumSize().height()))
        windowMenu.addAction("Vertical Tall", lambda: self.resize(
            self.minimumSize().width(), self.maximumSize().height()))
        windowMenu.addSeparator()
        windowMenu.addAction("Disable Resize", lambda:
                             self.setFixedSize(self.size()))
        windowMenu.addAction("Set Interface Font...", lambda:
                             self.setFont(QFontDialog.getFont()[0]))
        windowMenu.addAction(
            "Load .qss Skin", lambda: self.setStyleSheet(self.skin()))
        helpMenu = self.menuBar().addMenu("&Help")
        helpMenu.addAction("About Qt 5", lambda: QMessageBox.aboutQt(self))
        helpMenu.addAction("About Python 3",
                           lambda: open_new_tab('https://www.python.org'))
        helpMenu.addAction("About " + __doc__,
                           lambda: QMessageBox.about(self, __doc__, HELP))
        helpMenu.addSeparator()
        helpMenu.addAction(
            "Keyboard Shortcut",
            lambda: QMessageBox.information(self, __doc__, "<b>Quit = CTRL+Q"))
        if sys.platform.startswith('linux'):
            helpMenu.addAction("View Source Code", lambda:
                               call('xdg-open ' + __file__, shell=True))
        helpMenu.addAction("View GitHub Repo", lambda: open_new_tab(__url__))
        helpMenu.addAction("Check Updates", lambda: Downloader(self))
        # process
        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self._read_output)
        self.process.readyReadStandardError.connect(self._read_errors)
        self.process.finished.connect(self._process_finished)
        self.process.error.connect(self._process_failed)
        # widgets
        self.group0, self.group1 = QGroupBox("Options"), QGroupBox("Paths")
        self.group4, self.group5 = QGroupBox("Details"), QGroupBox("Miscs")
        g0grid, g1vlay = QGridLayout(self.group0), QGridLayout(self.group1)
        g5vlay, g4vlay = QVBoxLayout(self.group5), QVBoxLayout(self.group4)
        # group 0 the options
        self.module = QCheckBox("Create compiled extension module")
        self.standalone = QCheckBox("Standalone executable binary output")
        self.nofreeze = QCheckBox("No freeze all modules of standard library")
        self.python_debug = QCheckBox("Use Python Debug")
        self.warning = QCheckBox("Warnings for implicit exceptions at compile")
        self.recurse_std = QCheckBox("Recursive compile the standard library")
        self.recurse_not = QCheckBox("Force No recursive compiling")
        self.execute = QCheckBox("Execute the created binary after compiling")
        self.pythonpath = QCheckBox("Keep pythonpath when executing")
        self.enhaced = QCheckBox("Enhaced compile, Not CPython compatible")
        self.nolineno = QCheckBox("No Statements line numbers on compile")
        self.rmbuilddir = QCheckBox("Remove build directory after compile.")
        self.nuitka_debug = QCheckBox("Use Nuitka Debug")
        self.keep_debug = QCheckBox("Keep debug info on compile for GDB")
        self.traced = QCheckBox("Traced execution output")
        self.plusplus = QCheckBox("Compile C++ Only on generated source files")
        self.experimental = QCheckBox("Experimental features")
        self.force_clang = QCheckBox("Force use of CLang")
        self.force_mingw = QCheckBox("Force use of MinGW on MS Windows")
        self.force_lto = QCheckBox("Use link time optimizations LTO")
        self.show_scons = QCheckBox("Show Scons executed commands")
        self.show_progress = QCheckBox("Show progress info and statistics")
        self.show_summary = QCheckBox("Show final summary of included modules")
        self.disable_console = QCheckBox("Disable the Console on MS Windows")
        for i, widget in enumerate((
            self.module, self.standalone, self.nofreeze, self.python_debug,
            self.warning, self.recurse_std, self.recurse_not, self.execute,
            self.pythonpath, self.enhaced, self.nolineno, self.rmbuilddir,
            self.nuitka_debug, self.keep_debug, self.traced, self.plusplus,
            self.experimental, self.force_clang, self.force_mingw,
            self.force_lto, self.show_scons, self.show_progress,
                self.show_summary, self.disable_console)):
            widget.setToolTip(widget.text())
            g0grid.addWidget(widget, i if i < i + 1 else i - (i - 1), i % 2)
        # group 1 paths
        self.target = QLineEdit()
        self.outdir = QLineEdit(os.path.expanduser("~"))
        self.t_icon = QLineEdit()
        self.target.setToolTip("Python App file you want to Compile to Binary")
        self.outdir.setToolTip("Folder to write Compiled Output Binary files")
        self.t_icon.setToolTip("Icon image file to embed for your Python App")
        self.target.setPlaceholderText("/full/path/to/target/python_app.py")
        self.outdir.setPlaceholderText("/full/path/to/output/folder/")
        self.t_icon.setPlaceholderText("/full/path/to/python_app/icon.png")
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.completer.popup().setStyleSheet("border: 1px solid gray")
        self.completer.popup().setVerticalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        self.outdir.setCompleter(self.completer)
        self.t_icon.setCompleter(self.completer)
        self.target.setCompleter(self.completer)
        self.clear_1 = QPushButton(QIcon.fromTheme("edit-clear"), "", self,
                                   clicked=lambda: self.target.clear())
        self.clear_2 = QPushButton(QIcon.fromTheme("edit-clear"), "", self,
                                   clicked=lambda: self.t_icon.clear())
        self.clear_3 = QPushButton(QIcon.fromTheme("edit-clear"), "", self,
                                   clicked=lambda: self.outdir.clear())
        self.open_1 = QPushButton(
            QIcon.fromTheme("folder-open"), "", self, clicked=lambda:
                self.target.setText(str(QFileDialog.getOpenFileName(
                    self, __doc__, os.path.expanduser("~"), """Python (*.py);;
                    Python for Windows (*.pyw);;All (*.*)""")[0])))
        self.open_2 = QPushButton(
            QIcon.fromTheme("folder-open"), "", self, clicked=lambda:
                self.t_icon.setText(str(QFileDialog.getOpenFileName(
                    self, __doc__, os.path.expanduser("~"),
                    "PNG (*.png);;JPG (*.jpg);;ICO (*.ico);;All (*.*)")[0])))
        self.open_3 = QPushButton(
            QIcon.fromTheme("folder-open"), "", self, clicked=lambda:
                self.outdir.setText(str(QFileDialog.getExistingDirectory(
                    self, __doc__, os.path.expanduser("~")))))
        self.l_icon = QLabel("Target Icon")
        g1vlay.addWidget(QLabel("<b>Target Python"), 0, 0)
        g1vlay.addWidget(self.target, 0, 1)
        g1vlay.addWidget(self.clear_1, 0, 2)
        g1vlay.addWidget(self.open_1, 0, 3)
        g1vlay.addWidget(self.l_icon, 1, 0)
        g1vlay.addWidget(self.t_icon, 1, 1)
        g1vlay.addWidget(self.clear_2, 1, 2)
        g1vlay.addWidget(self.open_2, 1, 3)
        g1vlay.addWidget(QLabel("<b>Output Folder"), 2, 0)
        g1vlay.addWidget(self.outdir, 2, 1)
        g1vlay.addWidget(self.clear_3, 2, 2)
        g1vlay.addWidget(self.open_3, 2, 3)

        # group 4 the dome view mode
        self.jobs = QSpinBox()
        self.jobs.setRange(1, cpu_count())
        self.jobs.setValue(cpu_count())
        self.jobs.setToolTip("Backend Worker Jobs Processes")
        self.python_version = QComboBox()
        self.python_version.addItems(["2.7", "3.2", "3.3", "3.4"])
        self.python_version.setToolTip("Python version to use with Nuitka")
        self.display_tree = QPushButton("Display Tree")
        self.display_tree.clicked.connect(
            lambda: call(NUITKA + " --display-tree {}".format(
                self.target.text()), shell=True))
        self.dump_tree = QPushButton(
            "View Docs", clicked=lambda:
                open_new_tab("http://nuitka.net/doc/user-manual.html"))
        self.open_log = QPushButton("View Logs")
        _log = os.path.join(gettempdir(), "nuitka-gui.log")
        _open = "xdg-open " if sys.platform.startswith("lin") else "open "
        self.open_log.clicked.connect(lambda: call(_open + _log, shell=True))
        self.open_folder = QPushButton("Open Build Folder")
        self.open_folder.clicked.connect(lambda: call(
            _open + str(self.outdir.text()).strip(), shell=True))

        # self.display_tree.clicked.connect(self._display_tree)
        g4vlay.addWidget(QLabel("<b>Worker Jobs"))
        g4vlay.addWidget(self.jobs)
        g4vlay.addWidget(QLabel("<b>Python Version"))
        g4vlay.addWidget(self.python_version)
        g4vlay.addWidget(QLabel("<b>Actions"))
        g4vlay.addWidget(self.display_tree)
        g4vlay.addWidget(self.dump_tree)
        g4vlay.addWidget(self.open_log)
        g4vlay.addWidget(self.open_folder)
        self.debug, self.scr = QCheckBox("Use Debug"), QCheckBox("Make Script")
        self.chrt, self.ionice = QCheckBox("Slow CPU"), QCheckBox("Slow HDD")
        self.minimi = QCheckBox("Auto Minimize")
        self.chrt.setToolTip("Use Low CPU speed priority (Linux only)")
        self.ionice.setToolTip("Use Low HDD speed priority (Linux only)")
        self.scr.setToolTip("Generate a Bash Script to Compile with Nuitka")
        self.debug.setToolTip("Use Debug Verbose mode")
        self.minimi.setToolTip("Automatically Minimize when compiling starts")
        self.scr.setChecked(True)
        self.chrt.setChecked(True)
        self.ionice.setChecked(True)
        self.minimi.setChecked(True)
        g5vlay.addWidget(self.debug)
        g5vlay.addWidget(self.scr)
        g5vlay.addWidget(self.chrt)
        g5vlay.addWidget(self.ionice)
        g5vlay.addWidget(self.minimi)
        self.guimode = QComboBox()
        self.guimode.addItems(('Full UX / UI', 'Simple UX / UI'))
        self.guimode.setCurrentIndex(1)
        self._set_guimode()
        self.guimode.setStyleSheet("""QComboBox{background:transparent;
            margin-left:25px;color:gray;text-decoration:underline;border:0}""")
        self.guimode.currentIndexChanged.connect(self._set_guimode)
        self.bt = QDialogButtonBox(self)
        self.bt.setStandardButtons(
            QDialogButtonBox.Ok | QDialogButtonBox.Close)
        self.bt.rejected.connect(self.close)
        self.bt.accepted.connect(self.run)

        if not sys.platform.startswith('lin'):
            self.scr.setChecked(False)
            self.chrt.setChecked(False)
            self.ionice.setChecked(False)
            self.scr.hide()
            self.chrt.hide()
            self.ionice.hide()
        if not sys.platform.startswith('win'):
            self.l_icon.hide()
            self.t_icon.hide()
            self.clear_2.hide()
            self.open_2.hide()
        if sys.platform.startswith('win'):
            self.display_tree.hide()
        container = QWidget()
        container_layout = QGridLayout(container)  # Y, X
        container_layout.addWidget(self.guimode, 0, 1)
        container_layout.addWidget(self.group0, 1, 1)
        container_layout.addWidget(self.group1, 2, 1)
        container_layout.addWidget(self.group4, 1, 2)
        container_layout.addWidget(self.group5, 2, 2)
        container_layout.addWidget(self.bt, 3, 1)
        self.setCentralWidget(container)
Beispiel #39
0
class Frame(QWidget, Ui_Form):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setupUi(self)
        self.file = 1

        self.new.clicked.connect(self.newfile)
        self.tabWidget.tabCloseRequested.connect(self.closeCode)
        self.pushButton.clicked.connect(self.close)
        self.open_2.clicked.connect(self.openfile)
        self.open.clicked.connect(self.savefile)
        self.pushButton_2.clicked.connect(
            lambda: self.setWindowState(Qt.WindowMinimized))
        self.run.clicked.connect(self.Run)
        self.start.clicked.connect(self.StartT)
        self.det = [0, 1]
        self.az = 1
        self.cha = {
            '(': ')',
            '[': ']',
            '{': '}',
            '"': '"',
            "'": "'",
            '"""': '"""',
            "'''": "'''"
        }
        self.evin = False
        self.process = None
        self.Tab = []
        self.Text = []
        self.Result = []
        self.Language = []
        self.Completer = []
        self.co = ''
        self.fileType = "Python file (*.py)"
        self.punctuation = """!$%&():"*/;<>?@[\]^_`|~"""
        self.auto = False
        self.ver = True
        open('Files/choice', 'w').truncate(0)
        for i in self.btn:
            i.setMask(QRegion(i.rect(), QRegion.Ellipse))

        self.slider.valueChanged.connect(self.opacity)

    def mouseReleaseEvent(self, event):
        if event.y() < 56 and self.ver:
            self.animBar(-60, 0)
            self.ver = False
        elif event.y() > 56 and self.ver is False:
            self.animBar(0, -60)
            self.ver = True
        super(Frame, self).mouseReleaseEvent(event)

    def openfile(self):

        fname = QFileDialog.getOpenFileName(
            self, 'Open file', 'c:\\',
            "Python file (*.py) ;;Dart file (*.dart)")
        if fname[0] != "":
            file = open(fname[0], 'r').read()
            self.newfile()
            self.text.setPlainText(file)

    def savefile(self):
        if self.Language[
                self.tabWidget.currentIndex()].currentText() == "Python":
            self.fileType = "Python file (*.py)"
        else:
            self.fileType = "Dart file (*.dart)"
        fname = QFileDialog.getSaveFileName(
            self, 'Save file',
            'c:\\untitle_%i' % (self.tabWidget.currentIndex() + 1),
            self.fileType)
        ind = self.tabWidget.currentIndex()
        if fname[0] != "":
            open(fname[0], 'w').write(self.Text[ind].toPlainText())

    def opacity(self):
        sl = self.slider.value()
        if sl > 10:
            self.setWindowOpacity(sl / 100)

    def animBar(self, x, y):
        self.anim = QPropertyAnimation(self.groupBox, b'geometry')
        self.anim.setDuration(300)
        self.anim.setEasingCurve(QEasingCurve.OutSine)
        self.anim.setStartValue(QRect(0, x, 941, 41))
        self.anim.setEndValue(QRect(0, y, 941, 41))
        self.anim.start()

    def closeCode(self, i):
        self.tabWidget.removeTab(i)
        self.Tab.remove(self.Tab[i])
        self.Text.remove(self.Text[i])
        self.ind -= 1
        self.groupBox.setGraphicsEffect(self.shadow)
        if len(self.Tab) == 0:
            self.run.setEnabled(False)
            self.open.setEnabled(False)
        self.closeDebug(i)

    def closeDebug(self, i):
        self.tabWidget_2.removeTab(i)
        self.indi -= 1
        self.groupBox.setGraphicsEffect(self.shadow)

    def keyReleaseEvent(self, event):
        self.det.append(event.text())
        try:
            if event.text() == '':
                self.time.stop()
            if not self.auto:
                re = self.text.toPlainText().count(':')
                if self.det[-1] == '\r' and self.det[-2] == ':':
                    self.text.insertPlainText("    " * re)
                    self.evin = True
                elif event.text() == '\r' and self.evin is True:
                    self.text.insertPlainText("    " * re)

                if event.text() in list(self.cha.keys()):
                    ind = self.tabWidget.currentIndex()
                    self.Text[ind].insertPlainText(self.cha[event.text()])
                    self.Text[ind].moveCursor(QTextCursor.Left)
                if len(self.det) == 4:
                    self.det.remove(self.det[0])

        except Exception as f:
            pass

    def newfile(self):
        self.open.setEnabled(True)
        self.run.setEnabled(True)
        self.tab_2 = QWidget()
        self.Tab.append(self.tab_2)
        self.tab_2.setObjectName("tab_2")
        self.text = TextEdit(self.tab_2)
        self.text.setFont(QFont('Roboto Light'))
        self.language = QComboBox(self.tab_2)
        font = QFont()
        font.setPointSize(15)
        self.language.setFont(font)
        self.language.addItems(["Python", "Dart"])
        self.language.setGeometry(self.w * 0.600231, self.h * 0.500156, 100,
                                  30)
        self.Text.append(self.text)
        self.text.setGeometry(QRect(0, 0, self.w * 0.674231,
                                    self.h * 0.535156))
        self.completer = QCompleter(self)
        self.completer.setModel(self.getWord('Files/wordpy'))
        self.text.setCompleter(self.completer)
        self.Completer.append(self.completer)
        self.Language.append(self.language)

        font = QFont()
        font.setPointSize(15)
        self.text.setFont(font)
        self.text.setStyleSheet("#text{\n"
                                "color: white;\n"
                                "background-color: rgb(35, 35, 35);\n"
                                "border:0.5px rgb(35, 35, 35);\n"
                                "}")
        self.text.setObjectName("text")
        self.tabWidget.addTab(self.tab_2, "Untitle_%i" % (self.file))
        self.tabWidget.setCurrentIndex(self.ind)
        self.Language[-1].activated[str].connect(
            partial(self.changeL, index=self.tabWidget.currentIndex()))
        self.ind += 1
        self.file += 1
        self.tabWidget.setGraphicsEffect(self.shadow)
        self.text.setFocus(False)
        self.newDebug()

    def changeL(self, lang, index):
        if self.Language[index].currentText() == "Python":
            self.Completer[index].setModel(self.getWord('Files/wordpy'))
            self.Text[index].lis = open('Files/wordpy', 'r').readlines()

        else:
            self.Text[index].setText("""main(){

}""")
            self.Text[index].moveCursor(QTextCursor.Up)
            self.completer.setModel(self.getWord('Files/worddart'))
            self.Text[index].lis = open('Files/worddart', 'r').readlines()

    def getWord(self, file):
        a = open(file, 'r').readlines()
        return QStringListModel(a, self.completer)

    @pyqtSlot()
    def RunS(self):
        self.process = QProcess()
        self.process.setProcessChannelMode(QProcess.MergedChannels)
        self.process.readyReadStandardOutput.connect(self.WorkReply)
        self.process.finished.connect(self.WorkFinished)
        version = self.doubleSpinBox.value()
        ind = self.tabWidget.currentIndex()
        if self.Language[ind].currentText().lower() == "python":
            commande = f"{self.Language[ind].currentText().lower()[:2]} -{str(version)[:3]} Files/Run"
        else:
            commande = f"{self.Language[ind].currentText().lower()} Files/Run"
        self.process.start(commande, QIODevice.ReadWrite)
        self.process.waitForStarted()
        self.text.setFocus(True)

    @pyqtSlot()
    def WorkReply(self):
        data = self.process.readAllStandardOutput().data()
        ch = str(data, encoding="utf-8").rstrip()
        ind = self.tabWidget.currentIndex()
        self.Result[ind].setPlainText(ch)

    @pyqtSlot()
    def WorkFinished(self):
        if self.process != None:
            self.process.readyReadStandardOutput.disconnect()
            self.process.finished.disconnect()

    def newDebug(self):
        ind = self.tabWidget.currentIndex()
        self.tabWidget_2.setGraphicsEffect(self.shadow)
        self.tab = QWidget()
        self.tab.setObjectName("tab")
        self.result = QPlainTextEdit(self.tab)
        self.result.setReadOnly(True)
        font = QFont()
        font.setPointSize(12)
        self.result.setFont(font)
        self.Result.append(self.result)
        self.result.setGeometry(
            QRect(0, 0, self.w * 0.674231, self.h * 0.14453))
        self.result.setStyleSheet("#result{\n"
                                  "color: white;\n"
                                  "background-color: rgb(35, 35, 35);\n"
                                  "border:0.5px rgb(35, 35, 35);\n"
                                  "}")
        self.result.setObjectName("result")
        self.tabWidget_2.addTab(self.tab, "Untitle_%i" % (ind + 1))
        self.tabWidget_2.setCurrentIndex(self.ind)

    def Run(self):
        ind = self.tabWidget.currentIndex()
        open('Files/Run', 'w').write(self.Text[ind].toPlainText())
        self.RunS()
        self.tabWidget_2.setCurrentIndex(ind)

    def StartT(self):
        self.gm = {"{": "'", "}": '='}
        self.start.setText('*لنتعلم معا*')
        self.start.setStyleSheet(
            'background-color:rgb(30, 30, 30);border:5px solid rgb(30, 30, 30);'
        )
        d = StartTuto()
        self.setWindowOpacity(0.4)
        d.exec_()
        self.start.setText('لنتعلم معا')
        self.start.setStyleSheet(
            "QPushButton:hover{background-color:rgb(30, 30, 30);border:5px solid rgb(30, 30, 30);}\n"
            "QPushButton{color:white;background-color: rgb(50, 50, 50);border:0.3px solid  rgb(50, 50, 50);}QPushButton:pressed{background-color:rgb(80, 80, 80);border: rgb(80, 80, 80);}\n"
            "")
        self.setWindowOpacity(1)
        self.o = 0
        self.fil = open('Files/choice', 'r').read().rstrip()[2:]
        open('Files/choice', 'w').truncate(0)
        self.auto = True
        if self.fil == 'it':
            self.auto = False
        elif self.fil == 'me':
            self.StartT()
        else:
            self.time = QTimer()
            self.time.timeout.connect(self.tuto)
            self.time.start(300)

    def PRESS(self):
        hllDll = ctypes.WinDLL("User32.dll")
        VK_CAPITAL = 0x14
        if hllDll.GetKeyState(VK_CAPITAL) == 1:
            press('capslock')

    def tuto(self):
        if self.o == 0:
            self.newfile()
            self.text.setFocus()

        elif self.o == self.co - 1:
            self.Run()
            self.time.stop()
            self.auto = False
        self.PRESS()
        code = open('Files/%s' % (self.fil), 'r').read()
        liC = []
        for i in code:
            liC.append(i)
        liC.append(' ')
        self.co = len(liC)
        if liC[self.o] in self.punctuation:
            press('capslock')
            press(liC[self.o])
        elif liC[self.o] in ['{', '}']:
            hotkey('altright', self.gm[liC[self.o]])
        else:
            press(liC[self.o])

        self.o += 1
Beispiel #40
0
class MainWindow(QMainWindow):


    def __init__(self, parent=None):
        super(MainWindow, self).__init__()
        QNetworkProxyFactory.setUseSystemConfiguration(True)
        self.statusBar().showMessage(__doc__ + get_nuitka_version())
        self.setWindowTitle(__doc__.strip().capitalize())
        self.setMinimumSize(480, 400)
        self.setMaximumSize(1024, 800)
        self.resize(self.minimumSize())
        self.setWindowIcon(QIcon.fromTheme("python"))
        self.center()
        QShortcut("Ctrl+q", self, activated=lambda: self.close())
        self.menuBar().addMenu("&File").addAction("Exit", lambda: self.close())
        windowMenu = self.menuBar().addMenu("&Window")
        windowMenu.addAction("Minimize", lambda: self.showMinimized())
        windowMenu.addAction("Maximize", lambda: self.showMaximized())
        windowMenu.addAction("Restore", lambda: self.showNormal())
        windowMenu.addAction("FullScreen", lambda: self.showFullScreen())
        windowMenu.addAction("Center", lambda: self.center())
        windowMenu.addAction("Top-Left", lambda: self.move(0, 0))
        windowMenu.addAction("To Mouse", lambda: self.move_to_mouse_position())
        windowMenu.addSeparator()
        windowMenu.addAction(
            "Increase size", lambda:
            self.resize(self.size().width() * 1.4, self.size().height() * 1.4))
        windowMenu.addAction("Decrease size", lambda: self.resize(
            self.size().width() // 1.4, self.size().height() // 1.4))
        windowMenu.addAction("Minimum size", lambda:
                             self.resize(self.minimumSize()))
        windowMenu.addAction("Maximum size", lambda:
                             self.resize(self.maximumSize()))
        windowMenu.addAction("Horizontal Wide", lambda: self.resize(
            self.maximumSize().width(), self.minimumSize().height()))
        windowMenu.addAction("Vertical Tall", lambda: self.resize(
            self.minimumSize().width(), self.maximumSize().height()))
        windowMenu.addSeparator()
        windowMenu.addAction("Disable Resize", lambda:
                             self.setFixedSize(self.size()))
        windowMenu.addAction("Set Interface Font...", lambda:
                             self.setFont(QFontDialog.getFont()[0]))
        windowMenu.addAction(
            "Load .qss Skin", lambda: self.setStyleSheet(self.skin()))
        helpMenu = self.menuBar().addMenu("&Help")
        helpMenu.addAction("About Qt 5", lambda: QMessageBox.aboutQt(self))
        helpMenu.addAction("About Python 3",
                           lambda: open_new_tab('https://www.python.org'))
        helpMenu.addAction("About " + __doc__,
                           lambda: QMessageBox.about(self, __doc__, HELP))
        helpMenu.addSeparator()
        helpMenu.addAction(
            "Keyboard Shortcut",
            lambda: QMessageBox.information(self, __doc__, "<b>Quit = CTRL+Q"))
        if sys.platform.startswith('linux'):
            helpMenu.addAction("View Source Code", lambda:
                               call('xdg-open ' + __file__, shell=True))
        helpMenu.addAction("View GitHub Repo", lambda: open_new_tab(__url__))
        helpMenu.addAction("Check Updates", lambda: Downloader(self))
        # process
        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self._read_output)
        self.process.readyReadStandardError.connect(self._read_errors)
        self.process.finished.connect(self._process_finished)
        self.process.error.connect(self._process_failed)
        # widgets
        self.group0, self.group1 = QGroupBox("Options"), QGroupBox("Paths")
        self.group4, self.group5 = QGroupBox("Details"), QGroupBox("Miscs")
        g0grid, g1vlay = QGridLayout(self.group0), QGridLayout(self.group1)
        g5vlay, g4vlay = QVBoxLayout(self.group5), QVBoxLayout(self.group4)
        # group 0 the options
        self.module = QCheckBox("Create compiled extension module")
        self.standalone = QCheckBox("Standalone executable binary output")
        self.nofreeze = QCheckBox("No freeze all modules of standard library")
        self.python_debug = QCheckBox("Use Python Debug")
        self.warning = QCheckBox("Warnings for implicit exceptions at compile")
        self.recurse_std = QCheckBox("Recursive compile the standard library")
        self.recurse_not = QCheckBox("Force No recursive compiling")
        self.execute = QCheckBox("Execute the created binary after compiling")
        self.pythonpath = QCheckBox("Keep pythonpath when executing")
        self.enhaced = QCheckBox("Enhaced compile, Not CPython compatible")
        self.nolineno = QCheckBox("No Statements line numbers on compile")
        self.rmbuilddir = QCheckBox("Remove build directory after compile.")
        self.nuitka_debug = QCheckBox("Use Nuitka Debug")
        self.keep_debug = QCheckBox("Keep debug info on compile for GDB")
        self.traced = QCheckBox("Traced execution output")
        self.plusplus = QCheckBox("Compile C++ Only on generated source files")
        self.experimental = QCheckBox("Experimental features")
        self.force_clang = QCheckBox("Force use of CLang")
        self.force_mingw = QCheckBox("Force use of MinGW on MS Windows")
        self.force_lto = QCheckBox("Use link time optimizations LTO")
        self.show_scons = QCheckBox("Show Scons executed commands")
        self.show_progress = QCheckBox("Show progress info and statistics")
        self.show_summary = QCheckBox("Show final summary of included modules")
        self.disable_console = QCheckBox("Disable the Console on MS Windows")
        for i, widget in enumerate((
            self.module, self.standalone, self.nofreeze, self.python_debug,
            self.warning, self.recurse_std, self.recurse_not, self.execute,
            self.pythonpath, self.enhaced, self.nolineno, self.rmbuilddir,
            self.nuitka_debug, self.keep_debug, self.traced, self.plusplus,
            self.experimental, self.force_clang, self.force_mingw,
            self.force_lto, self.show_scons, self.show_progress,
                self.show_summary, self.disable_console)):
            widget.setToolTip(widget.text())
            g0grid.addWidget(widget, i if i < i + 1 else i - (i - 1), i % 2)
        # group 1 paths
        self.target = QLineEdit()
        self.outdir = QLineEdit(os.path.expanduser("~"))
        self.t_icon = QLineEdit()
        self.target.setToolTip("Python App file you want to Compile to Binary")
        self.outdir.setToolTip("Folder to write Compiled Output Binary files")
        self.t_icon.setToolTip("Icon image file to embed for your Python App")
        self.target.setPlaceholderText("/full/path/to/target/python_app.py")
        self.outdir.setPlaceholderText("/full/path/to/output/folder/")
        self.t_icon.setPlaceholderText("/full/path/to/python_app/icon.png")
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.completer.popup().setStyleSheet("border: 1px solid gray")
        self.completer.popup().setVerticalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        self.outdir.setCompleter(self.completer)
        self.t_icon.setCompleter(self.completer)
        self.target.setCompleter(self.completer)
        self.clear_1 = QPushButton(QIcon.fromTheme("edit-clear"), "", self,
                                   clicked=lambda: self.target.clear())
        self.clear_2 = QPushButton(QIcon.fromTheme("edit-clear"), "", self,
                                   clicked=lambda: self.t_icon.clear())
        self.clear_3 = QPushButton(QIcon.fromTheme("edit-clear"), "", self,
                                   clicked=lambda: self.outdir.clear())
        self.open_1 = QPushButton(
            QIcon.fromTheme("folder-open"), "", self, clicked=lambda:
                self.target.setText(str(QFileDialog.getOpenFileName(
                    self, __doc__, os.path.expanduser("~"), """Python (*.py);;
                    Python for Windows (*.pyw);;All (*.*)""")[0])))
        self.open_2 = QPushButton(
            QIcon.fromTheme("folder-open"), "", self, clicked=lambda:
                self.t_icon.setText(str(QFileDialog.getOpenFileName(
                    self, __doc__, os.path.expanduser("~"),
                    "PNG (*.png);;JPG (*.jpg);;ICO (*.ico);;All (*.*)")[0])))
        self.open_3 = QPushButton(
            QIcon.fromTheme("folder-open"), "", self, clicked=lambda:
                self.outdir.setText(str(QFileDialog.getExistingDirectory(
                    self, __doc__, os.path.expanduser("~")))))
        self.l_icon = QLabel("Target Icon")
        g1vlay.addWidget(QLabel("<b>Target Python"), 0, 0)
        g1vlay.addWidget(self.target, 0, 1)
        g1vlay.addWidget(self.clear_1, 0, 2)
        g1vlay.addWidget(self.open_1, 0, 3)
        g1vlay.addWidget(self.l_icon, 1, 0)
        g1vlay.addWidget(self.t_icon, 1, 1)
        g1vlay.addWidget(self.clear_2, 1, 2)
        g1vlay.addWidget(self.open_2, 1, 3)
        g1vlay.addWidget(QLabel("<b>Output Folder"), 2, 0)
        g1vlay.addWidget(self.outdir, 2, 1)
        g1vlay.addWidget(self.clear_3, 2, 2)
        g1vlay.addWidget(self.open_3, 2, 3)

        # group 4 the dome view mode
        self.jobs = QSpinBox()
        self.jobs.setRange(1, cpu_count())
        self.jobs.setValue(cpu_count())
        self.jobs.setToolTip("Backend Worker Jobs Processes")
        self.python_version = QComboBox()
        self.python_version.addItems(["2.7", "3.2", "3.3", "3.4"])
        self.python_version.setToolTip("Python version to use with Nuitka")
        self.display_tree = QPushButton("Display Tree")
        self.display_tree.clicked.connect(
            lambda: call(NUITKA + " --display-tree {}".format(
                self.target.text()), shell=True))
        self.dump_tree = QPushButton(
            "View Docs", clicked=lambda:
                open_new_tab("http://nuitka.net/doc/user-manual.html"))
        self.open_log = QPushButton("View Logs")
        _log = os.path.join(gettempdir(), "nuitka-gui.log")
        _open = "xdg-open " if sys.platform.startswith("lin") else "open "
        self.open_log.clicked.connect(lambda: call(_open + _log, shell=True))
        self.open_folder = QPushButton("Open Build Folder")
        self.open_folder.clicked.connect(lambda: call(
            _open + str(self.outdir.text()).strip(), shell=True))

        # self.display_tree.clicked.connect(self._display_tree)
        g4vlay.addWidget(QLabel("<b>Worker Jobs"))
        g4vlay.addWidget(self.jobs)
        g4vlay.addWidget(QLabel("<b>Python Version"))
        g4vlay.addWidget(self.python_version)
        g4vlay.addWidget(QLabel("<b>Actions"))
        g4vlay.addWidget(self.display_tree)
        g4vlay.addWidget(self.dump_tree)
        g4vlay.addWidget(self.open_log)
        g4vlay.addWidget(self.open_folder)
        self.debug, self.scr = QCheckBox("Use Debug"), QCheckBox("Make Script")
        self.chrt, self.ionice = QCheckBox("Slow CPU"), QCheckBox("Slow HDD")
        self.minimi = QCheckBox("Auto Minimize")
        self.chrt.setToolTip("Use Low CPU speed priority (Linux only)")
        self.ionice.setToolTip("Use Low HDD speed priority (Linux only)")
        self.scr.setToolTip("Generate a Bash Script to Compile with Nuitka")
        self.debug.setToolTip("Use Debug Verbose mode")
        self.minimi.setToolTip("Automatically Minimize when compiling starts")
        self.scr.setChecked(True)
        self.chrt.setChecked(True)
        self.ionice.setChecked(True)
        self.minimi.setChecked(True)
        g5vlay.addWidget(self.debug)
        g5vlay.addWidget(self.scr)
        g5vlay.addWidget(self.chrt)
        g5vlay.addWidget(self.ionice)
        g5vlay.addWidget(self.minimi)
        self.guimode = QComboBox()
        self.guimode.addItems(('Full UX / UI', 'Simple UX / UI'))
        self.guimode.setCurrentIndex(1)
        self._set_guimode()
        self.guimode.setStyleSheet("""QComboBox{background:transparent;
            margin-left:25px;color:gray;text-decoration:underline;border:0}""")
        self.guimode.currentIndexChanged.connect(self._set_guimode)
        self.bt = QDialogButtonBox(self)
        self.bt.setStandardButtons(
            QDialogButtonBox.Ok | QDialogButtonBox.Close)
        self.bt.rejected.connect(self.close)
        self.bt.accepted.connect(self.run)

        if not sys.platform.startswith('lin'):
            self.scr.setChecked(False)
            self.chrt.setChecked(False)
            self.ionice.setChecked(False)
            self.scr.hide()
            self.chrt.hide()
            self.ionice.hide()
        if not sys.platform.startswith('win'):
            self.l_icon.hide()
            self.t_icon.hide()
            self.clear_2.hide()
            self.open_2.hide()
        if sys.platform.startswith('win'):
            self.display_tree.hide()
        container = QWidget()
        container_layout = QGridLayout(container)  # Y, X
        container_layout.addWidget(self.guimode, 0, 1)
        container_layout.addWidget(self.group0, 1, 1)
        container_layout.addWidget(self.group1, 2, 1)
        container_layout.addWidget(self.group4, 1, 2)
        container_layout.addWidget(self.group5, 2, 2)
        container_layout.addWidget(self.bt, 3, 1)
        self.setCentralWidget(container)

    def check_paths(self):
        if not os.path.isfile(self.target.text()):
            log.error("Target File not found or not valid.")
            QMessageBox.warning(self, __doc__.title(),
                                "Target File not found or not valid.")
            return False
        if not str(self.target.text()).endswith((".py", ".pyw")):
            log.error("Target File not valid.")
            QMessageBox.warning(self, __doc__.title(),
                                "Target File not valid.")
            return False
        if not os.path.isdir(self.outdir.text()):
            log.error("Target Folder not found or not valid.")
            QMessageBox.warning(self, __doc__.title(),
                                "Target Folder not found or not valid.")
            return False
        if self.t_icon.text() and not os.path.isfile(self.t_icon.text()):
            log.warning("Target Icon File not found or not valid.")
            QMessageBox.warning(self, __doc__.title(),
                                "Target Icon File not found or not valid.")
            return True
        else:
            return True

    def generate_build_command(self):
        return re.sub(r"\s+", " ", " ".join((
            'chrt --verbose --idle 0' if self.chrt.isChecked() else '',
            'ionice --ignore --class 3' if self.ionice.isChecked() else '',
            NUITKA,
            '--debug --verbose' if self.debug.isChecked() else '',
            '--show-progress' if self.show_progress.isChecked() else '',
            '--show-scons --show-modules' if self.show_scons.isChecked() else '',
            '--unstriped' if self.keep_debug.isChecked() else '',
            '--trace-execution' if self.traced.isChecked() else '',
            '--remove-output' if self.rmbuilddir.isChecked() else '',
            '--code-gen-no-statement-lines' if self.nolineno.isChecked() else '',
            '--execute' if self.execute.isChecked() else '',
            '--recurse-none' if self.recurse_not.isChecked() else '--recurse-all',
            '--recurse-stdlib' if self.recurse_std.isChecked() else '',
            '--clang' if self.force_clang.isChecked() else '',
            '--lto' if self.force_lto.isChecked() else '',
            '--c++-only' if self.plusplus.isChecked() else '',
            '--windows-disable-console' if self.disable_console.isChecked() else '',
            '--experimental' if self.experimental.isChecked() else '',
            '--python-debug' if self.python_debug.isChecked() else '',
            '--module' if self.module.isChecked() else '--standalone',
            '--nofreeze-stdlib' if self.nofreeze.isChecked() else '',
            '--mingw' if self.force_mingw.isChecked() else '',
            '--warn-implicit-exceptions' if self.warning.isChecked() else '',
            '--execute-with-pythonpath' if self.pythonpath.isChecked() else '',
            '--enhanced' if self.enhaced.isChecked() else '',
            '--icon="{}"'.format(self.t_icon.text()) if self.t_icon.text() else '',
            '--python-version={}'.format(self.python_version.currentText()),
            '--jobs={}'.format(self.jobs.value()),
            '--output-dir="{}"'.format(self.outdir.text()),
            '"{}"'.format(self.target.text()))))

    def run(self):
        self.statusBar().showMessage('Working...')
        log.debug("Working...")
        if not self.check_paths():
            return
        command_to_run_nuitka = self.generate_build_command()
        log.debug(command_to_run_nuitka)
        self.process.start(command_to_run_nuitka)
        if not self.process.waitForStarted():
            log.error(self._read_errors())
            return  # ERROR
        if self.scr.isChecked() and sys.platform.startswith("lin"):
            script_file = str(self.target.text()).replace(".py",
                                                          "-nuitka-compile.sh")
            log.debug("Writing Script {}".format(script_file))
            with open(script_file, "w", encoding="utf-8") as script:
                script.write("#!/usr/bin/env bash\n" + command_to_run_nuitka)
                os.chmod(script_file, 0o755)
        self.statusBar().showMessage(__doc__.title())

    def _process_finished(self):
        log.debug("Finished.")
        self.showNormal()

    def _read_output(self):
        return str(self.process.readAllStandardOutput()).strip()

    def _read_errors(self):
        log.debug(self.process.readAllStandardError())
        return str(self.process.readAllStandardError()).strip()

    def _process_failed(self):
        self.showNormal()
        self.statusBar().showMessage(" ERROR: Failed ! ")
        log.warning(str(self.process.readAllStandardError()).strip().lower())
        return str(self.process.readAllStandardError()).strip().lower()

    def _set_guimode(self):
        for widget in (self.group0, self.group4,
                       self.group5, self.statusBar(), self.menuBar()):
            widget.hide() if self.guimode.currentIndex() else widget.show()
        self.resize(self.minimumSize()
                    if self.guimode.currentIndex() else self.maximumSize())
        self.center()

    def skin(self, filename=None):
        if not filename:
            filename = str(QFileDialog.getOpenFileName(
                self, __doc__ + "-Open QSS Skin file", os.path.expanduser("~"),
                "CSS Cascading Style Sheet for Qt 5 (*.qss);;All (*.*)")[0])
        if filename and os.path.isfile(filename):
            log.debug(filename)
            with open(filename, 'r') as file_to_read:
                text = file_to_read.read().strip()
        if text:
            log.debug(text)
            return text

    def center(self):
        window_geometry = self.frameGeometry()
        mousepointer_position = QApplication.desktop().cursor().pos()
        screen = QApplication.desktop().screenNumber(mousepointer_position)
        centerPoint = QApplication.desktop().screenGeometry(screen).center()
        window_geometry.moveCenter(centerPoint)
        return bool(not self.move(window_geometry.topLeft()))

    def move_to_mouse_position(self):
        window_geometry = self.frameGeometry()
        window_geometry.moveCenter(QApplication.desktop().cursor().pos())
        return bool(not self.move(window_geometry.topLeft()))

    def closeEvent(self, event):
        the_conditional_is_true = QMessageBox.question(
            self, __doc__.title(), 'Quit ?.', QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No) == QMessageBox.Yes
        event.accept() if the_conditional_is_true else event.ignore()
Beispiel #41
0
    def setupUi(self):
        self.load_ui("mlsrulequery.ui")

        # set up source/target autocompletion
        typeattr_completion_list = [str(t) for t in self.policy.types()]
        typeattr_completion_list.extend(
            str(a) for a in self.policy.typeattributes())
        typeattr_completer_model = QStringListModel(self)
        typeattr_completer_model.setStringList(
            sorted(typeattr_completion_list))
        self.typeattr_completion = QCompleter()
        self.typeattr_completion.setModel(typeattr_completer_model)
        self.source.setCompleter(self.typeattr_completion)
        self.target.setCompleter(self.typeattr_completion)

        # setup indications of errors on source/target/default
        self.orig_palette = self.source.palette()
        self.error_palette = self.source.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)
        self.clear_source_error()
        self.clear_target_error()
        self.clear_default_error()

        # populate class list
        self.class_model = SEToolsListModel(self)
        self.class_model.item_list = sorted(self.policy.classes())
        self.tclass.setModel(self.class_model)

        # set up results
        self.table_results_model = MLSRuleListModel(self)
        self.sort_proxy = QSortFilterProxyModel(self)
        self.sort_proxy.setSourceModel(self.table_results_model)
        self.table_results.setModel(self.sort_proxy)

        # set up processing thread
        self.thread = QThread()
        self.worker = ResultsUpdater(self.query, self.table_results_model)
        self.worker.moveToThread(self.thread)
        self.worker.raw_line.connect(self.raw_results.appendPlainText)
        self.worker.finished.connect(self.update_complete)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.update)

        # create a "busy, please wait" dialog
        self.busy = QProgressDialog(self)
        self.busy.setModal(True)
        self.busy.setRange(0, 0)
        self.busy.setMinimumDuration(0)
        self.busy.canceled.connect(self.thread.requestInterruption)

        # Ensure settings are consistent with the initial .ui state
        self.set_source_regex(self.source_regex.isChecked())
        self.set_target_regex(self.target_regex.isChecked())
        self.criteria_frame.setHidden(not self.criteria_expander.isChecked())
        self.results_frame.setHidden(not self.results_expander.isChecked())
        self.notes.setHidden(not self.notes_expander.isChecked())

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.clear_ruletypes.clicked.connect(self.clear_all_ruletypes)
        self.all_ruletypes.clicked.connect(self.set_all_ruletypes)
        self.source.textEdited.connect(self.clear_source_error)
        self.source.editingFinished.connect(self.set_source)
        self.source_regex.toggled.connect(self.set_source_regex)
        self.target.textEdited.connect(self.clear_target_error)
        self.target.editingFinished.connect(self.set_target)
        self.target_regex.toggled.connect(self.set_target_regex)
        self.tclass.selectionModel().selectionChanged.connect(self.set_tclass)
        self.invert_class.clicked.connect(self.invert_tclass_selection)
        self.default_range.textEdited.connect(self.clear_default_error)
        self.default_range.editingFinished.connect(self.set_default_range)
Beispiel #42
0
    def initGui(self):

        # Create a new toolbar
        self.tool_bar = self.iface.addToolBar('Discovery')
        self.tool_bar.setObjectName('Discovery_Plugin')

        # Create action that will start plugin configuration
        self.action_config = QAction(
            QIcon(os.path.join(self.plugin_dir, "discovery_logo.png")),
            u"Configure Discovery", self.tool_bar)
        self.action_config.triggered.connect(self.show_config_dialog)
        self.tool_bar.addAction(self.action_config)

        # Add combobox for configs
        self.config_combo = QComboBox()
        settings = QgsSettings()
        settings.beginGroup("/Discovery")
        config_list = settings.value("config_list")

        if config_list:
            for conf in config_list:
                self.config_combo.addItem(conf)
        elif settings.childGroups():
            # support for prev version
            key = "Config1"
            config_list = []
            config_list.append(key)
            settings.setValue("config_list", config_list)
            self.config_combo.addItem(key)

            settings.setValue(key + "data_type", settings.value("data_type"))
            settings.setValue(key + "file", settings.value("file"))
            settings.setValue(key + "connection", settings.value("connection"))
            settings.setValue(key + "schema", settings.value("schema"))
            settings.setValue(key + "table", settings.value("table"))
            settings.setValue(key + "search_column",
                              settings.value("search_column"))
            settings.setValue(key + "echo_search_column",
                              settings.value("echo_search_column"))
            settings.setValue(key + "display_columns",
                              settings.value("display_columns"))
            settings.setValue(key + "geom_column",
                              settings.value("geom_column"))
            settings.setValue(key + "scale_expr", settings.value("scale_expr"))
            settings.setValue(key + "bbox_expr", settings.value("bbox_expr"))

            delete_config_from_settings("", settings)
        self.tool_bar.addWidget(self.config_combo)

        # Add search edit box
        self.search_line_edit = QgsFilterLineEdit()
        self.search_line_edit.setPlaceholderText('Search for...')
        self.search_line_edit.setMaximumWidth(768)
        self.tool_bar.addWidget(self.search_line_edit)

        self.config_combo.currentIndexChanged.connect(
            self.change_configuration)

        # Set up the completer
        self.completer = QCompleter([])  # Initialise with en empty list
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setMaxVisibleItems(1000)
        self.completer.setModelSorting(
            QCompleter.UnsortedModel)  # Sorting done in PostGIS
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion
                                         )  # Show all fetched possibilities
        self.completer.activated[QModelIndex].connect(self.on_result_selected)
        self.completer.highlighted[QModelIndex].connect(
            self.on_result_highlighted)
        self.search_line_edit.setCompleter(self.completer)

        # Connect any signals
        self.search_line_edit.textEdited.connect(self.on_search_text_changed)

        # Search results
        self.search_results = []

        # Set up a timer to periodically perform db queries as required
        self.db_timer.timeout.connect(self.do_db_operations)
        self.db_timer.start(100)

        # Read config
        self.read_config(config_list[0] if config_list else "")

        self.locator_filter = locator_filter.DiscoveryLocatorFilter(self)
        self.iface.registerLocatorFilter(self.locator_filter)
Beispiel #43
0
 def creaCompleter(self, datos=[]):
     completer = QCompleter(datos)
     completer.setCaseSensitivity(Qt.CaseInsensitive)
     self.setCompleter(completer)
Beispiel #44
0
class TERuleQueryTab(AnalysisTab):
    """A Type Enforcement rule query."""
    def __init__(self, parent, policy, perm_map):
        super(TERuleQueryTab, self).__init__(parent)
        self.log = logging.getLogger(__name__)
        self.policy = policy
        self.query = TERuleQuery(policy)
        self.setupUi()

    def __del__(self):
        self.thread.quit()
        self.thread.wait(5000)
        logging.getLogger("setools.terulequery").removeHandler(self.handler)

    def setupUi(self):
        self.load_ui("apol/terulequery.ui")

        # set up source/target autocompletion
        typeattr_completion_list = [str(t) for t in self.policy.types()]
        typeattr_completion_list.extend(
            str(a) for a in self.policy.typeattributes())
        typeattr_completer_model = QStringListModel(self)
        typeattr_completer_model.setStringList(
            sorted(typeattr_completion_list))
        self.typeattr_completion = QCompleter()
        self.typeattr_completion.setModel(typeattr_completer_model)
        self.source.setCompleter(self.typeattr_completion)
        self.target.setCompleter(self.typeattr_completion)

        # set up default autocompletion
        type_completion_list = [str(t) for t in self.policy.types()]
        type_completer_model = QStringListModel(self)
        type_completer_model.setStringList(sorted(type_completion_list))
        self.type_completion = QCompleter()
        self.type_completion.setModel(type_completer_model)
        self.default_type.setCompleter(self.type_completion)

        # setup indications of errors on source/target/default
        self.errors = set()
        self.orig_palette = self.source.palette()
        self.error_palette = self.source.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)
        self.clear_source_error()
        self.clear_target_error()
        self.clear_default_error()
        self.clear_xperm_error()

        # populate class list
        self.class_model = SEToolsListModel(self)
        self.class_model.item_list = sorted(self.policy.classes())
        self.tclass.setModel(self.class_model)

        # populate perm list
        self.perms_model = PermListModel(self, self.policy)
        self.perms.setModel(self.perms_model)

        # populate bool list
        self.bool_model = SEToolsListModel(self)
        self.bool_model.item_list = sorted(self.policy.bools())
        self.bool_criteria.setModel(self.bool_model)

        # set up results
        self.table_results_model = TERuleTableModel(self)
        self.sort_proxy = QSortFilterProxyModel(self)
        self.sort_proxy.setSourceModel(self.table_results_model)
        self.table_results.setModel(self.sort_proxy)
        self.table_results.sortByColumn(0, Qt.AscendingOrder)

        # set up processing thread
        self.thread = QThread()
        self.worker = QueryResultsUpdater(self.query, self.table_results_model)
        self.worker.moveToThread(self.thread)
        self.worker.raw_line.connect(self.raw_results.appendPlainText)
        self.worker.finished.connect(self.update_complete)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.update)

        # create a "busy, please wait" dialog
        self.busy = QProgressDialog(self)
        self.busy.setModal(True)
        self.busy.setRange(0, 0)
        self.busy.setMinimumDuration(0)
        self.busy.canceled.connect(self.thread.requestInterruption)
        self.busy.reset()

        # update busy dialog from query INFO logs
        self.handler = LogHandlerToSignal()
        self.handler.message.connect(self.busy.setLabelText)
        logging.getLogger("setools.terulequery").addHandler(self.handler)

        # Ensure settings are consistent with the initial .ui state
        self.set_source_regex(self.source_regex.isChecked())
        self.set_target_regex(self.target_regex.isChecked())
        self.set_default_regex(self.default_regex.isChecked())
        self.toggle_xperm_criteria()
        self.criteria_frame.setHidden(not self.criteria_expander.isChecked())
        self.notes.setHidden(not self.notes_expander.isChecked())

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.allowxperm.toggled.connect(self.toggle_xperm_criteria)
        self.auditallowxperm.toggled.connect(self.toggle_xperm_criteria)
        self.neverallowxperm.toggled.connect(self.toggle_xperm_criteria)
        self.dontauditxperm.toggled.connect(self.toggle_xperm_criteria)
        self.clear_ruletypes.clicked.connect(self.clear_all_ruletypes)
        self.all_ruletypes.clicked.connect(self.set_all_ruletypes)
        self.source.textEdited.connect(self.clear_source_error)
        self.source.editingFinished.connect(self.set_source)
        self.source_regex.toggled.connect(self.set_source_regex)
        self.target.textEdited.connect(self.clear_target_error)
        self.target.editingFinished.connect(self.set_target)
        self.target_regex.toggled.connect(self.set_target_regex)
        self.tclass.selectionModel().selectionChanged.connect(self.set_tclass)
        self.invert_class.clicked.connect(self.invert_tclass_selection)
        self.perms.selectionModel().selectionChanged.connect(self.set_perms)
        self.invert_perms.clicked.connect(self.invert_perms_selection)
        self.xperms.textEdited.connect(self.clear_xperm_error)
        self.xperms.editingFinished.connect(self.set_xperm)
        self.default_type.textEdited.connect(self.clear_default_error)
        self.default_type.editingFinished.connect(self.set_default_type)
        self.default_regex.toggled.connect(self.set_default_regex)
        self.bool_criteria.selectionModel().selectionChanged.connect(
            self.set_bools)

    #
    # Ruletype criteria
    #

    def _set_ruletypes(self, value):
        self.allow.setChecked(value)
        self.allowxperm.setChecked(value)
        self.auditallow.setChecked(value)
        self.auditallowxperm.setChecked(value)
        self.neverallow.setChecked(value)
        self.neverallowxperm.setChecked(value)
        self.dontaudit.setChecked(value)
        self.dontauditxperm.setChecked(value)
        self.type_transition.setChecked(value)
        self.type_member.setChecked(value)
        self.type_change.setChecked(value)

    def set_all_ruletypes(self):
        self._set_ruletypes(True)

    def clear_all_ruletypes(self):
        self._set_ruletypes(False)

    #
    # Source criteria
    #

    def clear_source_error(self):
        self.clear_criteria_error(
            self.source, "Match the source type/attribute of the rule.")

    def set_source(self):
        try:
            self.query.source = self.source.text()
        except Exception as ex:
            self.log.error("Source type/attribute error: {0}".format(ex))
            self.set_criteria_error(self.source, ex)

    def set_source_regex(self, state):
        self.log.debug("Setting source_regex {0}".format(state))
        self.query.source_regex = state
        self.clear_source_error()
        self.set_source()

    #
    # Target criteria
    #

    def clear_target_error(self):
        self.clear_criteria_error(
            self.target, "Match the target type/attribute of the rule.")

    def set_target(self):
        try:
            self.query.target = self.target.text()
        except Exception as ex:
            self.log.error("Target type/attribute error: {0}".format(ex))
            self.set_criteria_error(self.target, ex)

    def set_target_regex(self, state):
        self.log.debug("Setting target_regex {0}".format(state))
        self.query.target_regex = state
        self.clear_target_error()
        self.set_target()

    #
    # Class criteria
    #

    def set_tclass(self):
        selected_classes = []
        for index in self.tclass.selectionModel().selectedIndexes():
            selected_classes.append(self.class_model.data(index, Qt.UserRole))

        self.query.tclass = selected_classes
        self.perms_model.set_classes(selected_classes)

    def invert_tclass_selection(self):
        invert_list_selection(self.tclass.selectionModel())

    #
    # Permissions criteria
    #

    def set_perms(self):
        selected_perms = []
        for index in self.perms.selectionModel().selectedIndexes():
            selected_perms.append(self.perms_model.data(index, Qt.UserRole))

        self.query.perms = selected_perms

    def invert_perms_selection(self):
        invert_list_selection(self.perms.selectionModel())

    #
    # Extended permission criteria
    #
    def toggle_xperm_criteria(self):
        mode = any(
            (self.allowxperm.isChecked(), self.auditallowxperm.isChecked(),
             self.neverallowxperm.isChecked(),
             self.dontauditxperm.isChecked()))

        self.xperms.setEnabled(mode)
        self.xperms_equal.setEnabled(mode)

    def clear_xperm_error(self):
        self.clear_criteria_error(
            self.xperms, "Match the extended permissions of the rule. "
            "Comma-separated permissions or ranges of permissions.")

    def set_xperm(self):
        xperms = []
        try:
            text = self.xperms.text()

            if text:
                for item in self.xperms.text().split(","):
                    rng = item.split("-")
                    if len(rng) == 2:
                        xperms.append((int(rng[0],
                                           base=16), int(rng[1], base=16)))
                    elif len(rng) == 1:
                        xperms.append((int(rng[0],
                                           base=16), int(rng[0], base=16)))
                    else:
                        raise ValueError(
                            "Enter an extended permission or extended permission "
                            "range, e.g. 0x5411 or 0x8800-0x88ff.")

                self.query.xperms = xperms
            else:
                self.query.xperms = None

        except Exception as ex:
            self.log.error("Extended permissions error: {0}".format(ex))
            self.set_criteria_error(self.xperms, ex)

    #
    # Default criteria
    #

    def clear_default_error(self):
        self.clear_criteria_error(self.default_type,
                                  "Match the default type the rule.")

    def set_default_type(self):
        self.query.default_regex = self.default_regex.isChecked()

        try:
            self.query.default = self.default_type.text()
        except Exception as ex:
            self.log.error("Default type error: {0}".format(ex))
            self.set_criteria_error(self.default_type, ex)

    def set_default_regex(self, state):
        self.log.debug("Setting default_regex {0}".format(state))
        self.query.default_regex = state
        self.clear_default_error()
        self.set_default_type()

    #
    # Boolean criteria
    #

    def set_bools(self):
        selected_bools = []
        for index in self.bool_criteria.selectionModel().selectedIndexes():
            selected_bools.append(self.bool_model.data(index, Qt.UserRole))

        self.query.boolean = selected_bools

    #
    # Save/Load tab
    #
    def save(self):
        """Return a dictionary of settings."""
        if self.errors:
            raise TabFieldError("Field(s) are in error: {0}".format(" ".join(
                o.objectName() for o in self.errors)))

        settings = {}
        save_checkboxes(self, settings, [
            "criteria_expander", "notes_expander", "allow", "allowxperm",
            "auditallow", "auditallowxperm", "neverallow", "neverallowxperm",
            "dontaudit", "dontauditxperm", "type_transition", "type_change",
            "type_member", "source_indirect", "source_regex",
            "target_indirect", "target_regex", "perms_subset", "xperms_equal",
            "default_regex", "bools_equal"
        ])
        save_lineedits(self, settings,
                       ["source", "target", "xperms", "default_type"])
        save_listviews(self, settings, ["tclass", "perms", "bool_criteria"])
        save_textedits(self, settings, ["notes"])
        return settings

    def load(self, settings):
        load_checkboxes(self, settings, [
            "allow", "allowxperm", "auditallow", "auditallowxperm",
            "neverallow", "neverallowxperm", "dontaudit", "dontauditxperm",
            "type_transition", "type_change", "type_member",
            "criteria_expander", "notes_expander", "source_indirect",
            "source_regex", "target_indirect", "target_regex", "perms_subset",
            "xperms_equal", "default_regex", "bools_equal"
        ])
        load_lineedits(self, settings,
                       ["source", "target", "xperms", "default_type"])
        load_listviews(self, settings, ["tclass", "perms", "bool_criteria"])
        load_textedits(self, settings, ["notes"])

    #
    # Results runner
    #

    def run(self, button):
        # right now there is only one button.
        rule_types = []
        max_results = 0

        if self.allow.isChecked():
            rule_types.append("allow")
            max_results += self.policy.allow_count
        if self.allowxperm.isChecked():
            rule_types.append("allowxperm")
            max_results += self.policy.allowxperm_count
        if self.auditallow.isChecked():
            rule_types.append("auditallow")
            max_results += self.policy.auditallow_count
        if self.auditallowxperm.isChecked():
            rule_types.append("auditallowxperm")
            max_results += self.policy.auditallowxperm_count
        if self.neverallow.isChecked():
            rule_types.append("neverallow")
            max_results += self.policy.neverallow_count
        if self.neverallowxperm.isChecked():
            rule_types.append("neverallowxperm")
            max_results += self.policy.neverallowxperm_count
        if self.dontaudit.isChecked():
            rule_types.append("dontaudit")
            max_results += self.policy.dontaudit_count
        if self.dontauditxperm.isChecked():
            rule_types.append("dontauditxperm")
            max_results += self.policy.dontauditxperm_count
        if self.type_transition.isChecked():
            rule_types.append("type_transition")
            max_results += self.policy.type_transition_count
        if self.type_member.isChecked():
            rule_types.append("type_member")
            max_results += self.policy.type_member_count
        if self.type_change.isChecked():
            rule_types.append("type_change")
            max_results += self.policy.type_change_count

        self.query.ruletype = rule_types
        self.query.source_indirect = self.source_indirect.isChecked()
        self.query.target_indirect = self.target_indirect.isChecked()
        self.query.perms_subset = self.perms_subset.isChecked()
        self.query.boolean_equal = self.bools_equal.isChecked()

        # if query is broad, show warning.
        if not any((self.query.source, self.query.target, self.query.tclass, self.query.perms,
                    self.query.xperms, self.query.default, self.query.boolean)) \
                and max_results > 1000:

            reply = QMessageBox.question(
                self, "Continue?",
                "This is a broad query, estimated to return {0} results.  Continue?"
                .format(max_results), QMessageBox.Yes | QMessageBox.No)

            if reply == QMessageBox.No:
                return

        # start processing
        self.busy.setLabelText("Processing query...")
        self.busy.show()
        self.raw_results.clear()
        self.thread.start()

    def update_complete(self, count):
        self.log.info("{0} type enforcement rule(s) found.".format(count))

        # update sizes/location of result displays
        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Resizing the result table's columns; GUI may be unresponsive")
            self.busy.repaint()
            self.table_results.resizeColumnsToContents()
            # If the permissions column width is too long, pull back
            # to a reasonable size
            header = self.table_results.horizontalHeader()
            if header.sectionSize(4) > 400:
                header.resizeSection(4, 400)

        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Resizing the result table's rows; GUI may be unresponsive")
            self.busy.repaint()
            self.table_results.resizeRowsToContents()

        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Moving the raw result to top; GUI may be unresponsive")
            self.busy.repaint()
            self.raw_results.moveCursor(QTextCursor.Start)

        self.busy.reset()
def run_setup_window(icon):
    win = QDialog()
    win.setWindowTitle('Application Setup')
    win.setWindowIcon(icon)
    win.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint
                       | Qt.WindowCloseButtonHint)
    win.setAttribute(
        Qt.WA_DeleteOnClose)  # This is required to stop background timers!

    combo = QComboBox(win)
    combo.setEditable(True)
    combo.setInsertPolicy(QComboBox.NoInsert)
    combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    combo.setFont(get_monospace_font())

    combo_completer = QCompleter()
    combo_completer.setCaseSensitivity(Qt.CaseSensitive)
    combo_completer.setModel(combo.model())
    combo.setCompleter(combo_completer)

    bitrate = QSpinBox(win)
    bitrate.setMaximum(1000000)
    bitrate.setMinimum(10000)
    bitrate.setValue(1000000)

    baudrate = QComboBox(win)
    baudrate.setEditable(True)
    baudrate.setInsertPolicy(QComboBox.NoInsert)
    baudrate.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    baudrate.setFont(get_monospace_font())

    baudrate_completer = QCompleter(win)
    baudrate_completer.setModel(baudrate.model())
    baudrate.setCompleter(baudrate_completer)

    baudrate.setValidator(
        QIntValidator(min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES)))
    baudrate.insertItems(0, map(str, STANDARD_BAUD_RATES))
    baudrate.setCurrentText(str(DEFAULT_BAUD_RATE))

    dir_selection = DirectorySelectionWidget(win)

    ok = QPushButton('OK', win)

    def update_slcan_options_visibility():
        if RUNNING_ON_LINUX:
            slcan_active = '/' in combo.currentText()
        else:
            slcan_active = True
        slcan_group.setEnabled(slcan_active)

    combo.currentTextChanged.connect(update_slcan_options_visibility)

    ifaces = None

    def update_iface_list():
        nonlocal ifaces
        ifaces = iface_lister.get_list()
        known_keys = set()
        remove_indices = []
        was_empty = combo.count() == 0
        # Marking known and scheduling for removal
        for idx in count():
            tx = combo.itemText(idx)
            if not tx:
                break
            known_keys.add(tx)
            if tx not in ifaces:
                logger.debug('Removing iface %r', tx)
                remove_indices.append(idx)
        # Removing - starting from the last item in order to retain indexes
        for idx in remove_indices[::-1]:
            combo.removeItem(idx)
        # Adding new items - starting from the last item in order to retain the final order
        for key in list(ifaces.keys())[::-1]:
            if key not in known_keys:
                logger.debug('Adding iface %r', key)
                combo.insertItem(0, key)
        # Updating selection
        if was_empty:
            combo.setCurrentIndex(0)

    result = None
    kwargs = {}

    def on_ok():
        nonlocal result, kwargs
        try:
            baud_rate_value = int(baudrate.currentText())
        except ValueError:
            show_error('Invalid parameters',
                       'Could not parse baud rate',
                       'Please specify correct baud rate',
                       parent=win)
            return
        if not (min(STANDARD_BAUD_RATES) <= baud_rate_value <=
                max(STANDARD_BAUD_RATES)):
            show_error('Invalid parameters',
                       'Baud rate is out of range',
                       'Baud rate value should be within [%s, %s]' %
                       (min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES)),
                       parent=win)
            return
        kwargs['baudrate'] = baud_rate_value
        kwargs['bitrate'] = int(bitrate.value())
        result_key = str(combo.currentText()).strip()
        if not result_key:
            show_error('Invalid parameters',
                       'Interface name cannot be empty',
                       'Please select a valid interface',
                       parent=win)
            return
        try:
            result = ifaces[result_key]
        except KeyError:
            result = result_key
        win.close()

    ok.clicked.connect(on_ok)

    can_group = QGroupBox('CAN interface setup', win)
    can_layout = QVBoxLayout()
    can_layout.addWidget(QLabel('Select CAN interface'))
    can_layout.addWidget(combo)

    slcan_group = QGroupBox('SLCAN adapter settings', win)
    slcan_layout = QGridLayout()
    slcan_layout.addWidget(QLabel('CAN bus bit rate:'), 0, 0)
    slcan_layout.addWidget(bitrate, 0, 1)
    slcan_layout.addWidget(
        QLabel('Adapter baud rate (not applicable to USB-CAN adapters):'), 1,
        0)
    slcan_layout.addWidget(baudrate, 1, 1)
    slcan_group.setLayout(slcan_layout)

    can_layout.addWidget(slcan_group)
    can_group.setLayout(can_layout)

    layout = QVBoxLayout()
    layout.addWidget(can_group)
    layout.addWidget(dir_selection)
    layout.addWidget(ok)
    layout.setSizeConstraint(layout.SetFixedSize)
    win.setLayout(layout)

    with BackgroundIfaceListUpdater() as iface_lister:
        update_slcan_options_visibility()
        update_iface_list()
        timer = QTimer(win)
        timer.setSingleShot(False)
        timer.timeout.connect(update_iface_list)
        timer.start(int(BackgroundIfaceListUpdater.UPDATE_INTERVAL / 2 * 1000))
        win.exec()

    return result, kwargs, dir_selection.get_selection()
Beispiel #46
0
    def setupUi(self):
        self.load_ui("apol/terulequery.ui")

        # set up source/target autocompletion
        typeattr_completion_list = [str(t) for t in self.policy.types()]
        typeattr_completion_list.extend(
            str(a) for a in self.policy.typeattributes())
        typeattr_completer_model = QStringListModel(self)
        typeattr_completer_model.setStringList(
            sorted(typeattr_completion_list))
        self.typeattr_completion = QCompleter()
        self.typeattr_completion.setModel(typeattr_completer_model)
        self.source.setCompleter(self.typeattr_completion)
        self.target.setCompleter(self.typeattr_completion)

        # set up default autocompletion
        type_completion_list = [str(t) for t in self.policy.types()]
        type_completer_model = QStringListModel(self)
        type_completer_model.setStringList(sorted(type_completion_list))
        self.type_completion = QCompleter()
        self.type_completion.setModel(type_completer_model)
        self.default_type.setCompleter(self.type_completion)

        # setup indications of errors on source/target/default
        self.errors = set()
        self.orig_palette = self.source.palette()
        self.error_palette = self.source.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)
        self.clear_source_error()
        self.clear_target_error()
        self.clear_default_error()
        self.clear_xperm_error()

        # populate class list
        self.class_model = SEToolsListModel(self)
        self.class_model.item_list = sorted(self.policy.classes())
        self.tclass.setModel(self.class_model)

        # populate perm list
        self.perms_model = PermListModel(self, self.policy)
        self.perms.setModel(self.perms_model)

        # populate bool list
        self.bool_model = SEToolsListModel(self)
        self.bool_model.item_list = sorted(self.policy.bools())
        self.bool_criteria.setModel(self.bool_model)

        # set up results
        self.table_results_model = TERuleTableModel(self)
        self.sort_proxy = QSortFilterProxyModel(self)
        self.sort_proxy.setSourceModel(self.table_results_model)
        self.table_results.setModel(self.sort_proxy)
        self.table_results.sortByColumn(0, Qt.AscendingOrder)

        # set up processing thread
        self.thread = QThread()
        self.worker = QueryResultsUpdater(self.query, self.table_results_model)
        self.worker.moveToThread(self.thread)
        self.worker.raw_line.connect(self.raw_results.appendPlainText)
        self.worker.finished.connect(self.update_complete)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.update)

        # create a "busy, please wait" dialog
        self.busy = QProgressDialog(self)
        self.busy.setModal(True)
        self.busy.setRange(0, 0)
        self.busy.setMinimumDuration(0)
        self.busy.canceled.connect(self.thread.requestInterruption)
        self.busy.reset()

        # update busy dialog from query INFO logs
        self.handler = LogHandlerToSignal()
        self.handler.message.connect(self.busy.setLabelText)
        logging.getLogger("setools.terulequery").addHandler(self.handler)

        # Ensure settings are consistent with the initial .ui state
        self.set_source_regex(self.source_regex.isChecked())
        self.set_target_regex(self.target_regex.isChecked())
        self.set_default_regex(self.default_regex.isChecked())
        self.toggle_xperm_criteria()
        self.criteria_frame.setHidden(not self.criteria_expander.isChecked())
        self.notes.setHidden(not self.notes_expander.isChecked())

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.allowxperm.toggled.connect(self.toggle_xperm_criteria)
        self.auditallowxperm.toggled.connect(self.toggle_xperm_criteria)
        self.neverallowxperm.toggled.connect(self.toggle_xperm_criteria)
        self.dontauditxperm.toggled.connect(self.toggle_xperm_criteria)
        self.clear_ruletypes.clicked.connect(self.clear_all_ruletypes)
        self.all_ruletypes.clicked.connect(self.set_all_ruletypes)
        self.source.textEdited.connect(self.clear_source_error)
        self.source.editingFinished.connect(self.set_source)
        self.source_regex.toggled.connect(self.set_source_regex)
        self.target.textEdited.connect(self.clear_target_error)
        self.target.editingFinished.connect(self.set_target)
        self.target_regex.toggled.connect(self.set_target_regex)
        self.tclass.selectionModel().selectionChanged.connect(self.set_tclass)
        self.invert_class.clicked.connect(self.invert_tclass_selection)
        self.perms.selectionModel().selectionChanged.connect(self.set_perms)
        self.invert_perms.clicked.connect(self.invert_perms_selection)
        self.xperms.textEdited.connect(self.clear_xperm_error)
        self.xperms.editingFinished.connect(self.set_xperm)
        self.default_type.textEdited.connect(self.clear_default_error)
        self.default_type.editingFinished.connect(self.set_default_type)
        self.default_regex.toggled.connect(self.set_default_regex)
        self.bool_criteria.selectionModel().selectionChanged.connect(
            self.set_bools)
Beispiel #47
0
    def __init__(self, keywords, parent=None):
        QCompleter.__init__(self, keywords, parent)
        self.setCompletionMode(QCompleter.PopupCompletion)
        self.highlighted.connect(self.setHighlighted)

        self.lastSelected = None
class MainWidget(QWidget, PM, Ui_MainWidget):
    # Signal Emits
    updatingStatus = pyqtSignal()
    repositoriesUpdated = pyqtSignal()
    selectionStatusChanged = pyqtSignal([str])
    finished = pyqtSignal()
    cleanUp = pyqtSignal()

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

        self.setupUi(self)
        self.parent = parent

        self._selectedGroups = []
        self._preexceptions = []
        self._postexceptions = []

        self.state = StateManager(self)
        self.currentState = None
        self.completer = None
        self._updatesCheckedOnce = False

        # Search Thread
        self._searchThread = PThread(self, self.startSearch,
                                     self.searchFinished)

        self.statusUpdater = StatusUpdater()
        self.basket = BasketDialog(self.state, self.parent)
        self._postexceptions.append(lambda: self.basket.setActionEnabled(True))
        self.searchButton.setIcon(QIcon.fromTheme('edit-find'))
        self.initializeUpdateTypeList()

        model = PackageModel(self)
        proxy = PackageProxy(self)
        proxy.setSourceModel(model)
        self.packageList.setModel(proxy)
        self.packageList.setItemDelegate(PackageDelegate(self, self.parent))
        self.packageList.setColumnWidth(0, 32)

        self.packageList.dataChanged[QModelIndex,
                                     QModelIndex].connect(self.statusChanged)

        self.packageList.updateRequested.connect(self.initialize)

        self.updateSettings()
        self.setActionButton()

        self.operation = OperationManager(self.state)

        self.progressDialog = ProgressDialog(self.state, self.parent)
        self._preexceptions.append(self.progressDialog._hide)
        self.progressDialog.registerFunction(
            FINISHED, lambda: self.parent.statusBar().setVisible(
                not self.progressDialog.isVisible()))
        self.progressDialog.registerFunction(
            OUT, lambda: self.parent.statusBar().show())
        self.summaryDialog = SummaryDialog()

        self.connectOperationSignals()
        self.pdsMessageBox = PMessageBox(self.content)

    def connectMainSignals(self):
        self.actionButton.clicked.connect(self.showBasket)
        self.checkUpdatesButton.clicked.connect(self.state.updateRepoAction)
        self.searchButton.clicked.connect(self.searchActivated)
        self.searchLine.textChanged[str].connect(self.searchLineChanged)
        self.searchLine.returnPressed.connect(self.searchActivated)

        self.searchLine.textChanged[str].connect(self.slotSearchLineClear)

        self.typeCombo.activated[int].connect(self.typeFilter)
        self.stateTab.currentChanged[int].connect(self.switchState)
        self.groupList.groupChanged.connect(self.groupFilter)
        self.groupList.groupChanged.connect(
            lambda: self.searchButton.setEnabled(False))
        self.packageList.select_all.clicked[bool].connect(self.toggleSelectAll)
        self.packageList.itemDelegate().packageSelected[bool].connect(
            self.toggleSelect)
        self.statusUpdater.selectedInfoChanged[int, str, int, str].connect(
            self.emitStatusBarInfo)
        self.statusUpdater.selectedInfoChanged[str].connect(
            lambda message: self.selectionStatusChanged[str].emit(message))
        self.statusUpdater.finished.connect(self.statusUpdated)

    def initialize(self):
        waitCursor()
        self.searchLine.clear()
        self._started = False
        self._last_packages = None
        self.state.reset()
        self.initializePackageList()
        self.initializeGroupList()
        self.initializeStatusUpdater()
        self.statusChanged()
        self._selectedGroups = []
        self.packageList.select_all.setChecked(False)
        self.initializeBasket()
        self.searchLine.setFocus(True)
        if self.currentState == self.state.UPGRADE:
            if self.groupList.count() == 0:
                QTimer.singleShot(0, \
                lambda: self.pdsMessageBox.showMessage(_translate("Package Manager","All packages are up to date"), icon = "info"))
        if self.groupList.count() > 0:
            if self.state.inUpgrade():
                self.pdsMessageBox.hideMessage(force=True)
        restoreCursor()

    def initializeStatusUpdater(self):
        self.statusUpdater.calculate_deps = not self.state.state == self.state.ALL
        self.statusUpdater.setModel(self.packageList.model().sourceModel())

    def initializeBasket(self):
        waitCursor()
        self.basket.setModel(self.packageList.model().sourceModel())
        restoreCursor()

    def initializePackageList(self):
        self.packageList.model().reset()
        self.packageList.setPackages(self.state.packages())

        if self.completer:
            self.completer.deleteLater()
            del self.completer

        self.completer = QCompleter(self.state.allPackages(), self)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.searchLine.setCompleter(self.completer)

    def selectComponent(self, component):
        if not self.state.iface.operationInProgress():
            if self.basket.isVisible():
                self.basket._hide()

            self.stateTab.setCurrentIndex(1)
            self.switchState(self.state.INSTALL)

            if component in self.groupList._list:
                self.groupList.setCurrentItem(self.groupList._list[component])
                self.groupFilter()

    def updateSettings(self):  # pmconfig ikinci kez okunmuyor
        self.packageList.showComponents = PMConfig().showComponents()
        self.packageList.showIsA = PMConfig().showIsA()
        self.packageList.setFocus()
        self.initialize()

    def searchLineChanged(self, text):
        self.searchButton.setEnabled(bool(text))
        if text == 'true':
            self.searchActivated()

    def statusUpdated(self):
        if self.statusUpdater.needsUpdate:
            self.statusUpdater.needsUpdate = False
            self.statusChanged()

    def statusChanged(self):
        self.setActionEnabled()
        if self.statusUpdater.isRunning():
            self.statusUpdater.needsUpdate = True
        else:
            self.updatingStatus.emit()
            self.statusUpdater.start()

    def initializeGroupList(self):
        self.groupList.clear()
        self.groupList._list = {}
        self.groupList.setAlternatingRowColors(True)
        self.groupList.setIconSize(QSize(32, 32))
        self.groupList.setState(self.state)
        self.groupList.addGroups(self.state.groups())
        if self.state.state == self.state.UPGRADE:
            self.typeCombo.show()
        else:
            self.typeCombo.hide()
            self.state._typeFilter = 'normal'
        self.groupFilter()

    def packageFilter(self, text):
        self.packageList.model().setFilterRole(Qt.DisplayRole)
        self.packageList.model().setFilterRegExp(
            QRegExp(unicode(text), Qt.CaseInsensitive, QRegExp.FixedString))

    def typeFilter(self, index):
        if self.state.state == self.state.UPGRADE:
            filter = self.typeCombo.itemData(index)
            if not self.state._typeFilter == filter:
                self.state._typeFilter = filter
                self.initializeGroupList()

    def slotSearchLineClear(self):
        if self.searchLine.text() != 'true':
            return

        self.groupFilter()

    def groupFilter(self):
        waitCursor()
        self.packageList.resetMoreInfoRow()
        packages = self.state.groupPackages(self.groupList.currentGroup())
        self.packageList.model().setFilterRole(GroupRole)
        self.packageList.model().setFilterPackages(packages)
        self.packageList.scrollToTop()
        self.packageList.select_all.setChecked(
            self.groupList.currentGroup() in self._selectedGroups)
        restoreCursor()

    def searchActivated(self):
        if self.currentState == self.state.UPGRADE:
            if self.groupList.count() == 0 and not self.searchUsed:
                return

        if not self.searchLine.text() == '':
            self.pdsMessageBox.showMessage(_translate("Package Manager",
                                                      "Searching..."),
                                           busy=True)
            self.groupList.lastSelected = None
            self._searchThread.start()
            self.searchUsed = True
        else:
            self.state.cached_packages = None
            self.state.packages()
            self.searchUsed = False
            self.searchFinished()

    def searchFinished(self):
        if self.state.cached_packages == []:
            self.pdsMessageBox.showMessage(
                _translate("Package Manager", "No results found."),
                "dialog-information")
        else:
            self.pdsMessageBox.hideMessage()
        self.initializeGroupList()
        self.initializePackageList()

    def startSearch(self):
        searchText = str(self.searchLine.text()).split()
        sourceModel = self.packageList.model().sourceModel()
        self.state.cached_packages = sourceModel.search(searchText)
        self.finished.emit()
        return self.state.cached_packages

    def setActionButton(self):
        self.actionButton.setEnabled(False)
        if self.state.state == self.state.ALL:
            menu = QMenu(self.actionButton)
            self.__install_action = menu.addAction(
                self.state.getActionIcon(self.state.INSTALL),
                self.state.getActionName(self.state.INSTALL), self.showBasket)
            self.__remove_action = menu.addAction(
                self.state.getActionIcon(self.state.REMOVE),
                self.state.getActionName(self.state.REMOVE), self.showBasket)
            self.actionButton.setMenu(menu)
        elif self.state.state == self.state.REMOVE:
            menu = QMenu(self.actionButton)
            self.__remove_action = menu.addAction(
                self.state.getActionIcon(self.state.REMOVE),
                self.state.getActionName(self.state.REMOVE), self.showBasket)
            self.__install_action = menu.addAction(
                self.state.getActionIcon(self.state.INSTALL),
                self.state.getActionName(self.state.INSTALL), self.showBasket)
            self.actionButton.setMenu(menu)
        else:
            self.actionButton.setMenu(None)
        self.actionButton.setIcon(self.state.getActionIcon())
        self.actionButton.setText(self.state.getActionName())

    def actionStarted(self, operation):
        self.pdsMessageBox.hideMessage()
        self.progressDialog.reset()
        if not operation in [
                "System.Manager.updateRepository",
                "System.Manager.updateAllRepositories"
        ]:
            totalPackages = self.packageList.packageCount()
            self.operation.setTotalPackages(totalPackages)
            self.progressDialog.updateStatus(0, totalPackages,
                                             self.state.toBe())
        if self.isVisible():
            if operation in [
                    "System.Manager.updateRepository",
                    "System.Manager.updateAllRepositories"
            ]:
                self.progressDialog.repoOperationView()
            if self.basket.isVisible():
                self.basket._hide()
                QTimer.singleShot(0, self.progressDialog._show)
            else:
                self.progressDialog._show()

        if not self._started:
            self.progressDialog.disableCancel()
        else:
            self.progressDialog.enableCancel()

    def actionFinished(self, operation):
        if operation in ("System.Manager.installPackage",
                         "System.Manager.removePackage",
                         "System.Manager.updatePackage"):
            self.notifyFinished()

        if operation == "System.Manager.installPackage" and self._started:
            KIconLoader.updateAvailableIcons()
            self.summaryDialog.setDesktopFiles(self.operation.desktopFiles)
            self.summaryDialog.showSummary()

        if operation in ("System.Manager.updateRepository",
                         "System.Manager.updateAllRepositories"):
            self.repositoriesUpdated.emit()
        self.searchLine.clear()
        self.state.reset()
        self.progressDialog._hide()
        if not self.currentState == self.state.UPGRADE:
            self.switchState(self.currentState)
        self.initialize()

    def actionCancelled(self):
        self.progressDialog._hide()
        self.progressDialog.reset()
        self.switchState(self.currentState)
        self.groupFilter()

    def setActionEnabled(self):
        enabled = self.packageList.isSelected()
        self.actionButton.setEnabled(enabled)
        self.basket.setActionEnabled(enabled)

    def switchState(self, state):
        self.pdsMessageBox.hideMessage()
        self._states[state][1].setChecked(True)
        self.state.setState(state)
        self.currentState = state
        self._selectedGroups = []
        if not state == self.state.HISTORY:
            self.setActionButton()
            self.state.cached_packages = None
            if state == self.state.UPGRADE or (state == self.state.INSTALL and
                                               self.groupList.count() == 1):
                if not self._updatesCheckedOnce:
                    self._updatesCheckedOnce = self.state.updateRepoAction(
                        silence=True)
            self.checkUpdatesButton.setHidden(not state == self.state.UPGRADE)
            self.initialize()

    def emitStatusBarInfo(self, packages, packagesSize, extraPackages,
                          extraPackagesSize):
        self.selectionStatusChanged[str].emit(
            self.state.statusText(packages, packagesSize, extraPackages,
                                  extraPackagesSize))

        # paket seçimine geçici çözüm
        if packages > 0:
            self.actionButton.setEnabled(True)
        else:
            self.actionButton.setEnabled(False)

    def setSelectAll(self, packages=None):
        if packages:
            self.packageList.reverseSelection(packages)

    def setReverseAll(self, packages=None):
        if packages:
            self.packageList.selectAll(packages)

    def toggleSelectAll(self, toggled):
        self._last_packages = self.packageList.model().getFilteredPackages()

        if toggled:
            if self.groupList.currentGroup() not in self._selectedGroups:
                self._selectedGroups.append(self.groupList.currentGroup())
            self.setReverseAll(self._last_packages)
        else:
            if self.groupList.currentGroup() in self._selectedGroups:
                self._selectedGroups.remove(self.groupList.currentGroup())
            self.setSelectAll(self._last_packages)

        self.packageList.setFocus()
        self.statusChanged()

    def toggleSelect(self, toggled):
        #self._last_packages = self.packageList.model().getFilteredPackages()
        if toggled:
            if self.groupList.currentGroup() not in self._selectedGroups:
                self._selectedGroups.append(self.groupList.currentGroup())

        #else:
        #if self.groupList.currentGroup() in self._selectedGroups:
        #    self._selectedGroups.remove(self.groupList.currentGroup())
        #self.setSelectAll(self._last_packages)

        self.packageList.setFocus()
        self.statusChanged()

    def showBasket(self):

        if self.basket.isVisible():
            return

        waitCursor()
        self.statusUpdater.wait()

        if self.currentState == self.state.ALL or self.state.REMOVE:
            action = {
                self.__remove_action: self.state.REMOVE,
                self.__install_action: self.state.INSTALL
            }.get(self.sender(), self.state.INSTALL)
            if action:
                if action == self.state.REMOVE:
                    installed_packages = self.state.iface.getInstalledPackages(
                    )
                    filtered_packages = filter(
                        lambda x: x not in installed_packages,
                        self.basket.model.selectedPackages())
                    if filtered_packages == self.basket.model.selectedPackages(
                    ):
                        restoreCursor()
                        QMessageBox(
                            _translate("Package Manager", "Select packages"),
                            _translate(
                                "Package Manager",
                                "You must select at least one installed package"
                            ), QMessageBox.Information, QMessageBox.Ok, 0,
                            0).exec_()
                        return
                    self.packageList.model().sourceModel().selectPackages(
                        filtered_packages, state=False)

                self.state.state = action

        self.basket._show()
        restoreCursor()

    def initializeUpdateTypeList(self):
        self.typeCombo.clear()
        self.typeCombo.addItem(QIcon.fromTheme('system-software-update'),
                               _translate("Package Manager", 'All Updates'),
                               'normal')
        self.typeCombo.addItem(
            QIcon.fromTheme('security-medium'),
            _translate("Package Manager", 'Security Updates'), 'security')
        self.typeCombo.addItem(
            QIcon.fromTheme('security-low'),
            _translate("Package Manager", 'Critical Updates'), 'critical')
Beispiel #49
0
class Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(700, 500)

        self.pilt = QtWidgets.QLabel(Dialog)
        self.pilt.setGeometry(QtCore.QRect(14, 5, 671, 431))
        self.pilt.setText("")
        self.pilt.setObjectName("pilt")

        self.daysaverage = QtWidgets.QLineEdit(Dialog)
        self.daysaverage.setGeometry(QtCore.QRect(370, 440, 51, 31))
        self.daysaverage.setObjectName("daysaverage")
        self.daysaverage.setText("20")

        self.uuesti = QtWidgets.QPushButton(Dialog)
        self.uuesti.setGeometry(QtCore.QRect(270, 440, 93, 31))
        self.uuesti.setObjectName("uuesti")

        self.daysbegin = QtWidgets.QDateEdit(Dialog)
        self.daysbegin.setCalendarPopup(True)
        self.daysbegin.setGeometry(QtCore.QRect(10, 440, 121, 31))
        self.daysbegin.setObjectName("daysbegin")
        self.daysbegin.setDate(get_last_year_same_date())
        self.daysbegin.setMaximumDate(get_yesterday_date())

        self.daysend = QtWidgets.QDateEdit(Dialog)
        self.daysend.setCalendarPopup(True)
        self.daysend.setGeometry(QtCore.QRect(140, 440, 121, 31))
        self.daysend.setObjectName("daysend")
        today = get_today_date()
        self.daysend.setMaximumDate(today)
        self.daysend.setDate(today)

        self.comboBox = QtWidgets.QComboBox(Dialog)
        self.comboBox.setGeometry(QtCore.QRect(440, 440, 161, 31))
        self.comboBox.setObjectName("comboBox")
        self.completer = QCompleter(self.fill_combobox())
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setFilterMode(Qt.MatchContains)
        self.comboBox.setEditable(True)
        self.comboBox.setCompleter(self.completer)

        self.display = QtWidgets.QPushButton(Dialog)
        self.display.setGeometry(QtCore.QRect(620, 440, 71, 31))
        self.display.setObjectName("display")

        self.retranslate_ui(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslate_ui(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "n Days Average"))
        self.uuesti.setText(_translate("Dialog", "Taasarvuta"))
        self.display.setText(_translate("Dialog", "KUVA"))

    def fill_combobox(self):
        with open(DEFAULT_STOCKS_FILENAME, 'r') as file:
            stocks = file.read().split('\n')

        if stocks is not None and len(stocks) > 0:
            completer_list = []
            self.comboBox.blockSignals(True)
            self.comboBox.addItem("")
            for stock in stocks:
                data = stock.split(",")
                if len(data) == 2:
                    name = data[0]
                    symbol = data[1]
                    self.comboBox.addItem(name, symbol)
                    completer_list.append(name)
            self.comboBox.blockSignals(False)
            return completer_list

    def update_start_time(self, start_date):
        strftime = datetime.strptime(start_date, "%d-%m-%Y")
        q_date = QtCore.QDate(strftime.year, strftime.month, strftime.day)
        self.daysbegin.setDate(q_date)
Beispiel #50
0
    def __init__(self, parent, state):
        QDialog.__init__(self, parent)

        self._state = state

        self.ui = Ui_PreferencesDialog()
        self.ui.setupUi(self)

        # 0. Dialog

        self.ui.buttonApplyChanges.clicked.connect(self.onApplyChanges)
        self.ui.buttonCancel.clicked.connect(self.onCancel)
        self.ui.tabsPreferences.setCurrentIndex(0)

        # 1. Search tab

        # - Filter languages

        self._filterLanguageComboBoxes = {}

        self._search_languages = {lang: False for lang in all_languages()}
        nb_columns_languages = 4
        for lang_i, lang in enumerate(all_languages()):
            row = lang_i // nb_columns_languages
            column = lang_i % nb_columns_languages

            checkBox = QCheckBox(_(lang.generic_name()),
                                 self.ui.scrollAreaWidgetSearch)

            def createSearchLangSlot(lang):
                @pyqtSlot(bool)
                def onSearchLangCheckBoxToggled(toggled):
                    self.searchLanguageChanged.emit(lang, toggled)

                return onSearchLangCheckBoxToggled

            checkBox.toggled.connect(createSearchLangSlot(lang))
            checkBox.setChecked(self._search_languages[lang])

            self._filterLanguageComboBoxes[lang] = checkBox
            self.ui.scrollAreaWidgetLayoutSearch.addWidget(
                checkBox, row, column)

        self.searchLanguageChanged.connect(self.onSearchLanguageChanged)
        fontSearchItem = self._filterLanguageComboBoxes[
            UnknownLanguage.create_generic()].font()
        fontSearchItem.setItalic(True)
        self._filterLanguageComboBoxes[
            UnknownLanguage.create_generic()].setFont(fontSearchItem)

        # 2. Download tab

        # - Download Destination

        self._dlDestinationType = self.DEFAULT_DLDESTINATIONTYPE

        def create_dlDestinationTypeChangedSlot(dlDestinationType):
            @pyqtSlot(bool)
            def dlDestinationTypeChanged(toggled):
                if toggled:
                    self.dlDestinationTypeChanged.emit(dlDestinationType)

            return dlDestinationTypeChanged

        self.ui.optionDlDestinationAsk.toggled.connect(
            create_dlDestinationTypeChangedSlot(
                self.DLDESTINATIONTYPE_ASKUSER))
        self.ui.optionDlDestinationSame.toggled.connect(
            create_dlDestinationTypeChangedSlot(
                self.DLDESTINATIONTYPE_SAMEFOLDER))
        self.ui.optionDlDestinationUser.toggled.connect(
            create_dlDestinationTypeChangedSlot(
                self.DLDESTINATIONTYPE_PREDEFINEDFOLDER))

        self.dlDestinationTypeChanged.connect(self.onDlDestinationTypeChange)

        self.ui.optionDlDestinationUser.toggled.connect(
            self.ui.inputDlDestinationUser.setEnabled)
        self.ui.optionDlDestinationUser.toggled.connect(
            self.ui.buttonDlDestinationUser.setEnabled)
        self.ui.optionDlDestinationUser.toggled.emit(False)

        # Always contains a valid download destination folder
        self._dlDestinationPredefined = ''  # FIXME: good default (USER HOME? USER DOWNLOADS?)

        dlDestinationCompleter = QCompleter()
        dlDestinationCompleter.setModel(
            QDirModel([], QDir.Dirs | QDir.NoDotAndDotDot, QDir.Name,
                      dlDestinationCompleter))
        self.ui.inputDlDestinationUser.setCompleter(dlDestinationCompleter)
        self.ui.inputDlDestinationUser.editingFinished.connect(
            self.onInputDlDestinationEditingFinished)

        self.ui.buttonDlDestinationUser.clicked.connect(
            self.onButtonDlDestinationClicked)

        # - Subtitle Filename

        self._subtitleFilename = self.DEFAULT_DLSUBFN

        def create_dlSubtitleFileNameChangedSlot(subtitleFilename):
            @pyqtSlot(bool)
            def subtitleFileNameChanged(toggled):
                if toggled:
                    self.subtitleFilenameChanged.emit(subtitleFilename)

            return subtitleFileNameChanged

        self.ui.optionSubFnSame.toggled.connect(
            create_dlSubtitleFileNameChangedSlot(self.DLSUBFN_SAME))
        self.ui.optionSubFnSameLang.toggled.connect(
            create_dlSubtitleFileNameChangedSlot(self.DLSUBFN_SAMELANG))
        self.ui.optionSubFnSameLangUploader.toggled.connect(
            create_dlSubtitleFileNameChangedSlot(
                self.DLSUBFN_SAMELANGUPLOADER))
        self.ui.optionSubFnOnline.toggled.connect(
            create_dlSubtitleFileNameChangedSlot(self.DLSUBFN_ONLINE))

        self.subtitleFilenameChanged.connect(self.onSubtitleFilenameChange)

        # 3. Upload tab

        # - Default Subtitle Language

        self._uploadLanguage = self.DEFAULT_UL_LANG

        self.ui.optionUlDefaultLanguage.set_unknown_text(_('Auto Detect'))
        self.ui.optionUlDefaultLanguage.set_selected_language(
            self._uploadLanguage)

        self.ui.optionUlDefaultLanguage.selected_language_changed.connect(
            self.onOptionUlDefaultLanguageChange)

        # 4. Network tab

        self.ui.inputProxyPort.setRange(0, 65535)

        # 5. Others tab

        # - Interface Language

        self._original_interface_language = UnknownLanguage.create_generic()
        self.ui.optionInterfaceLanguage.set_unknown_text(_('System Language'))
        self.ui.optionUlDefaultLanguage.set_selected_language(
            self.DEFAULT_INTERFACE_LANG)

        # - Video Application Location

        self.ui.buttonVideoAppLocationChoose.clicked.connect(
            self.onButtonVideoAppLocationChoose)
        self.ui.buttonHelpTranslation.clicked.connect(self.onHelpTranslate)

        self.settings = QSettings()  # FIXME: use config path

        self.readSettings()
class HelpWebSearchWidget(E5ClearableLineEdit):
    """
    Class implementing a web search widget for the web browser.
    
    @signal search(QUrl) emitted when the search should be done
    """
    search = pyqtSignal(QUrl)

    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(HelpWebSearchWidget, self).__init__(parent)

        from E5Gui.E5LineEdit import E5LineEdit
        from E5Gui.E5LineEditButton import E5LineEditButton
        from .OpenSearch.OpenSearchManager import OpenSearchManager

        self.__mw = parent

        self.__openSearchManager = OpenSearchManager(self)
        self.__openSearchManager.currentEngineChanged.connect(
            self.__currentEngineChanged)
        self.__currentEngine = ""

        self.__enginesMenu = QMenu(self)

        self.__engineButton = E5LineEditButton(self)
        self.__engineButton.setMenu(self.__enginesMenu)
        self.addWidget(self.__engineButton, E5LineEdit.LeftSide)

        self.__searchButton = E5LineEditButton(self)
        self.__searchButton.setIcon(UI.PixmapCache.getIcon("webSearch.png"))
        self.addWidget(self.__searchButton, E5LineEdit.LeftSide)

        self.__model = QStandardItemModel(self)
        self.__completer = QCompleter()
        self.__completer.setModel(self.__model)
        self.__completer.setCompletionMode(
            QCompleter.UnfilteredPopupCompletion)
        self.__completer.setWidget(self)

        self.__searchButton.clicked.connect(self.__searchButtonClicked)
        self.textEdited.connect(self.__textEdited)
        self.returnPressed.connect(self.__searchNow)
        self.__completer.activated[QModelIndex].connect(
            self.__completerActivated)
        self.__completer.highlighted[QModelIndex].connect(
            self.__completerHighlighted)
        self.__enginesMenu.aboutToShow.connect(self.__showEnginesMenu)

        self.__suggestionsItem = None
        self.__suggestions = []
        self.__suggestTimer = None
        self.__suggestionsEnabled = Preferences.getHelp("WebSearchSuggestions")

        self.__recentSearchesItem = None
        self.__recentSearches = []
        self.__maxSavedSearches = 10

        self.__engine = None
        self.__loadSearches()
        self.__setupCompleterMenu()
        self.__currentEngineChanged()

    def __searchNow(self):
        """
        Private slot to perform the web search.
        """
        searchText = self.text()
        if not searchText:
            return

        globalSettings = QWebSettings.globalSettings()
        if not globalSettings.testAttribute(
                QWebSettings.PrivateBrowsingEnabled):
            if searchText in self.__recentSearches:
                self.__recentSearches.remove(searchText)
            self.__recentSearches.insert(0, searchText)
            if len(self.__recentSearches) > self.__maxSavedSearches:
                self.__recentSearches = \
                    self.__recentSearches[:self.__maxSavedSearches]
            self.__setupCompleterMenu()

        url = self.__openSearchManager.currentEngine().searchUrl(searchText)
        self.search.emit(url)

    def __setupCompleterMenu(self):
        """
        Private method to create the completer menu.
        """
        if not self.__suggestions or \
           (self.__model.rowCount() > 0 and
                self.__model.item(0) != self.__suggestionsItem):
            self.__model.clear()
            self.__suggestionsItem = None
        else:
            self.__model.removeRows(1, self.__model.rowCount() - 1)

        boldFont = QFont()
        boldFont.setBold(True)

        if self.__suggestions:
            if self.__model.rowCount() == 0:
                if not self.__suggestionsItem:
                    self.__suggestionsItem = QStandardItem(
                        self.tr("Suggestions"))
                    self.__suggestionsItem.setFont(boldFont)
                self.__model.appendRow(self.__suggestionsItem)

            for suggestion in self.__suggestions:
                self.__model.appendRow(QStandardItem(suggestion))

        if not self.__recentSearches:
            self.__recentSearchesItem = QStandardItem(
                self.tr("No Recent Searches"))
            self.__recentSearchesItem.setFont(boldFont)
            self.__model.appendRow(self.__recentSearchesItem)
        else:
            self.__recentSearchesItem = QStandardItem(
                self.tr("Recent Searches"))
            self.__recentSearchesItem.setFont(boldFont)
            self.__model.appendRow(self.__recentSearchesItem)
            for recentSearch in self.__recentSearches:
                self.__model.appendRow(QStandardItem(recentSearch))

        view = self.__completer.popup()
        view.setFixedHeight(
            view.sizeHintForRow(0) * self.__model.rowCount() +
            view.frameWidth() * 2)

        self.__searchButton.setEnabled(
            bool(self.__recentSearches or self.__suggestions))

    def __completerActivated(self, index):
        """
        Private slot handling the selection of an entry from the completer.
        
        @param index index of the item (QModelIndex)
        """
        if self.__suggestionsItem and \
           self.__suggestionsItem.index().row() == index.row():
            return

        if self.__recentSearchesItem and \
           self.__recentSearchesItem.index().row() == index.row():
            return

        self.__searchNow()

    def __completerHighlighted(self, index):
        """
        Private slot handling the highlighting of an entry of the completer.
        
        @param index index of the item (QModelIndex)
        @return flah indicating a successful highlighting (boolean)
        """
        if self.__suggestionsItem and \
           self.__suggestionsItem.index().row() == index.row():
            return False

        if self.__recentSearchesItem and \
           self.__recentSearchesItem.index().row() == index.row():
            return False

        self.setText(index.data())
        return True

    def __textEdited(self, txt):
        """
        Private slot to handle changes of the search text.
        
        @param txt search text (string)
        """
        if self.__suggestionsEnabled:
            if self.__suggestTimer is None:
                self.__suggestTimer = QTimer(self)
                self.__suggestTimer.setSingleShot(True)
                self.__suggestTimer.setInterval(200)
                self.__suggestTimer.timeout.connect(self.__getSuggestions)
            self.__suggestTimer.start()
        else:
            self.__completer.setCompletionPrefix(txt)
            self.__completer.complete()

    def __getSuggestions(self):
        """
        Private slot to get search suggestions from the configured search
        engine.
        """
        searchText = self.text()
        if searchText:
            self.__openSearchManager.currentEngine()\
                .requestSuggestions(searchText)

    def __newSuggestions(self, suggestions):
        """
        Private slot to receive a new list of suggestions.
        
        @param suggestions list of suggestions (list of strings)
        """
        self.__suggestions = suggestions
        self.__setupCompleterMenu()
        self.__completer.complete()

    def __showEnginesMenu(self):
        """
        Private slot to handle the display of the engines menu.
        """
        self.__enginesMenu.clear()

        from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction
        engineNames = self.__openSearchManager.allEnginesNames()
        for engineName in engineNames:
            engine = self.__openSearchManager.engine(engineName)
            action = OpenSearchEngineAction(engine, self.__enginesMenu)
            action.setData(engineName)
            action.triggered.connect(self.__changeCurrentEngine)
            self.__enginesMenu.addAction(action)

            if self.__openSearchManager.currentEngineName() == engineName:
                action.setCheckable(True)
                action.setChecked(True)

        ct = self.__mw.currentBrowser()
        linkedResources = ct.linkedResources("search")

        if len(linkedResources) > 0:
            self.__enginesMenu.addSeparator()

        for linkedResource in linkedResources:
            url = QUrl(linkedResource.href)
            title = linkedResource.title
            mimetype = linkedResource.type_

            if mimetype != "application/opensearchdescription+xml":
                continue
            if url.isEmpty():
                continue

            if url.isRelative():
                url = ct.url().resolved(url)

            if not title:
                if not ct.title():
                    title = url.host()
                else:
                    title = ct.title()

            action = self.__enginesMenu.addAction(
                self.tr("Add '{0}'").format(title), self.__addEngineFromUrl)
            action.setData(url)
            action.setIcon(ct.icon())

        self.__enginesMenu.addSeparator()
        self.__enginesMenu.addAction(self.__mw.searchEnginesAction())

        if self.__recentSearches:
            self.__enginesMenu.addAction(self.tr("Clear Recent Searches"),
                                         self.clear)

    def __changeCurrentEngine(self):
        """
        Private slot to handle the selection of a search engine.
        """
        action = self.sender()
        if action is not None:
            name = action.data()
            self.__openSearchManager.setCurrentEngineName(name)

    def __addEngineFromUrl(self):
        """
        Private slot to add a search engine given its URL.
        """
        action = self.sender()
        if action is not None:
            url = action.data()
            if not isinstance(url, QUrl):
                return

            self.__openSearchManager.addEngine(url)

    def __searchButtonClicked(self):
        """
        Private slot to show the search menu via the search button.
        """
        self.__setupCompleterMenu()
        self.__completer.complete()

    def clear(self):
        """
        Public method to clear all private data.
        """
        self.__recentSearches = []
        self.__setupCompleterMenu()
        super(HelpWebSearchWidget, self).clear()
        self.clearFocus()

    def preferencesChanged(self):
        """
        Public method to handle the change of preferences.
        """
        self.__suggestionsEnabled = Preferences.getHelp("WebSearchSuggestions")
        if not self.__suggestionsEnabled:
            self.__suggestions = []
            self.__setupCompleterMenu()

    def saveSearches(self):
        """
        Public method to save the recently performed web searches.
        """
        Preferences.Prefs.settings.setValue('Help/WebSearches',
                                            self.__recentSearches)

    def __loadSearches(self):
        """
        Private method to load the recently performed web searches.
        """
        searches = Preferences.Prefs.settings.value('Help/WebSearches')
        if searches is not None:
            self.__recentSearches = searches

    def openSearchManager(self):
        """
        Public method to get a reference to the opensearch manager object.
        
        @return reference to the opensearch manager object (OpenSearchManager)
        """
        return self.__openSearchManager

    def __currentEngineChanged(self):
        """
        Private slot to track a change of the current search engine.
        """
        if self.__openSearchManager.engineExists(self.__currentEngine):
            oldEngine = self.__openSearchManager.engine(self.__currentEngine)
            oldEngine.imageChanged.disconnect(self.__engineImageChanged)
            if self.__suggestionsEnabled:
                oldEngine.suggestions.disconnect(self.__newSuggestions)

        newEngine = self.__openSearchManager.currentEngine()
        if newEngine.networkAccessManager() is None:
            newEngine.setNetworkAccessManager(self.__mw.networkAccessManager())
        newEngine.imageChanged.connect(self.__engineImageChanged)
        if self.__suggestionsEnabled:
            newEngine.suggestions.connect(self.__newSuggestions)

        self.setInactiveText(self.__openSearchManager.currentEngineName())
        self.__currentEngine = self.__openSearchManager.currentEngineName()
        self.__engineButton.setIcon(
            QIcon(
                QPixmap.fromImage(
                    self.__openSearchManager.currentEngine().image())))
        self.__suggestions = []
        self.__setupCompleterMenu()

    def __engineImageChanged(self):
        """
        Private slot to handle a change of the current search engine icon.
        """
        self.__engineButton.setIcon(
            QIcon(
                QPixmap.fromImage(
                    self.__openSearchManager.currentEngine().image())))

    def mousePressEvent(self, evt):
        """
        Protected method called by a mouse press event.
        
        @param evt reference to the mouse event (QMouseEvent)
        """
        if evt.button() == Qt.XButton1:
            self.__mw.currentBrowser().pageAction(QWebPage.Back).trigger()
        elif evt.button() == Qt.XButton2:
            self.__mw.currentBrowser().pageAction(QWebPage.Forward).trigger()
        else:
            super(HelpWebSearchWidget, self).mousePressEvent(evt)
    def __init__(self, installed_plugins, highlighted_plugins=None, parent=None):
        super().__init__(parent)

        self.backend_handler = BackendHandler()

        self.ui = Ui_DialogOptions()
        self.ui.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose)
        layout = QHBoxLayout(self.ui.tab_plugins)
        self.plugin_controller = PluginController(installed_plugins, highlighted_plugins, parent=self)
        layout.addWidget(self.plugin_controller)
        self.ui.tab_plugins.setLayout(layout)

        self.ui.labelWindowsError.setVisible(sys.platform == "win32" and platform.architecture()[0] != "64bit")

        self.ui.checkBoxAlignLabels.setChecked(constants.SETTINGS.value("align_labels", True, bool))
        self.ui.checkBoxFallBackTheme.setChecked(constants.SETTINGS.value('use_fallback_theme', False, bool))
        self.ui.checkBoxShowConfirmCloseDialog.setChecked(not constants.SETTINGS.value('not_show_close_dialog', False, bool))
        self.ui.checkBoxHoldShiftToDrag.setChecked(constants.SETTINGS.value('hold_shift_to_drag', False, bool))
        self.ui.checkBoxDefaultFuzzingPause.setChecked(constants.SETTINGS.value('use_default_fuzzing_pause', True, bool))

        self.ui.doubleSpinBoxRAMThreshold.setValue(100*constants.SETTINGS.value('ram_threshold', 0.6, float))

        self.ui.radioButtonGnuradioDirectory.setChecked(self.backend_handler.use_gnuradio_install_dir)
        self.ui.radioButtonPython2Interpreter.setChecked(not self.backend_handler.use_gnuradio_install_dir)
        if self.backend_handler.gnuradio_install_dir:
            self.ui.lineEditGnuradioDirectory.setText(self.backend_handler.gnuradio_install_dir)
        if self.backend_handler.python2_exe:
            self.ui.lineEditPython2Interpreter.setText(self.backend_handler.python2_exe)

        self.ui.doubleSpinBoxFuzzingPause.setValue(constants.SETTINGS.value("default_fuzzing_pause", 10**6, int))
        self.ui.doubleSpinBoxFuzzingPause.setEnabled(constants.SETTINGS.value('use_default_fuzzing_pause', True, bool))

        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEditPython2Interpreter.setCompleter(completer)
        self.ui.lineEditGnuradioDirectory.setCompleter(completer)

        for dev_name in self.backend_handler.DEVICE_NAMES:
            self.ui.listWidgetDevices.addItem(dev_name)

        self.set_device_enabled_suffix()

        self.ui.listWidgetDevices.setCurrentRow(0)
        self.set_gnuradio_status()
        self.refresh_device_tab()

        self.create_connects()
        self.old_symbol_tresh = 10
        self.old_show_pause_as_time = False

        self.field_type_table_model = FieldTypeTableModel([], parent=self)
        self.ui.tblLabeltypes.setModel(self.field_type_table_model)
        self.ui.tblLabeltypes.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        self.ui.tblLabeltypes.setItemDelegateForColumn(1, ComboBoxDelegate([f.name for f in FieldType.Function], return_index=False, parent=self))
        self.ui.tblLabeltypes.setItemDelegateForColumn(2, ComboBoxDelegate(ProtocolLabel.DISPLAY_FORMATS, parent=self))

        self.read_options()

        self.old_default_view = self.ui.comboBoxDefaultView.currentIndex()
Beispiel #53
0
    def setupUi(self):
        self.load_ui("apol/portconquery.ui")

        # set up user autocompletion
        user_completion_list = [str(u) for u in self.policy.users()]
        user_completer_model = QStringListModel(self)
        user_completer_model.setStringList(sorted(user_completion_list))
        self.user_completion = QCompleter()
        self.user_completion.setModel(user_completer_model)
        self.user.setCompleter(self.user_completion)

        # set up role autocompletion
        role_completion_list = [str(r) for r in self.policy.roles()]
        role_completer_model = QStringListModel(self)
        role_completer_model.setStringList(sorted(role_completion_list))
        self.role_completion = QCompleter()
        self.role_completion.setModel(role_completer_model)
        self.role.setCompleter(self.role_completion)

        # set up type autocompletion
        type_completion_list = [str(t) for t in self.policy.types()]
        type_completer_model = QStringListModel(self)
        type_completer_model.setStringList(sorted(type_completion_list))
        self.type_completion = QCompleter()
        self.type_completion.setModel(type_completer_model)
        self.type_.setCompleter(self.type_completion)

        # setup indications of errors on source/target/default
        self.errors = set()
        self.orig_palette = self.type_.palette()
        self.error_palette = self.type_.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)
        self.clear_ports_error()
        self.clear_user_error()
        self.clear_type_error()
        self.clear_role_error()
        self.clear_range_error()

        # populate protocol list. This has empty string as
        # the first item in the .ui file:
        for i, e in enumerate(PortconProtocol, start=1):
            self.protocol.insertItem(i, e.name.upper(), e)

        # set up results
        self.table_results_model = PortconTableModel(self)
        self.sort_proxy = QSortFilterProxyModel(self)
        self.sort_proxy.setSourceModel(self.table_results_model)
        self.table_results.setModel(self.sort_proxy)
        self.table_results.sortByColumn(0, Qt.AscendingOrder)

        # set up processing thread
        self.thread = QThread()
        self.worker = QueryResultsUpdater(self.query, self.table_results_model)
        self.worker.moveToThread(self.thread)
        self.worker.raw_line.connect(self.raw_results.appendPlainText)
        self.worker.finished.connect(self.update_complete)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.update)

        # create a "busy, please wait" dialog
        self.busy = QProgressDialog(self)
        self.busy.setModal(True)
        self.busy.setRange(0, 0)
        self.busy.setMinimumDuration(0)
        self.busy.canceled.connect(self.thread.requestInterruption)
        self.busy.reset()

        # update busy dialog from query INFO logs
        self.handler = LogHandlerToSignal()
        self.handler.message.connect(self.busy.setLabelText)
        logging.getLogger("setools.portconquery").addHandler(self.handler)

        # Ensure settings are consistent with the initial .ui state
        self.criteria_frame.setHidden(not self.criteria_expander.isChecked())
        self.notes.setHidden(not self.notes_expander.isChecked())

        # Range criteria is available only if policy is MLS
        if not self.policy.mls:
            self.range_criteria.setEnabled(False)
            self.range_criteria.setToolTip("MLS is disabled in this policy.")
            self.range_.setToolTip("MLS is disabled in this policy.")
            self.range_exact.setToolTip("MLS is disabled in this policy.")
            self.range_overlap.setToolTip("MLS is disabled in this policy.")
            self.range_subset.setToolTip("MLS is disabled in this policy.")
            self.range_superset.setToolTip("MLS is disabled in this policy.")

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.ports.textEdited.connect(self.clear_ports_error)
        self.ports.editingFinished.connect(self.set_ports)
        self.user.textEdited.connect(self.clear_user_error)
        self.user.editingFinished.connect(self.set_user)
        self.user_regex.toggled.connect(self.set_user_regex)
        self.role.textEdited.connect(self.clear_role_error)
        self.role.editingFinished.connect(self.set_role)
        self.role_regex.toggled.connect(self.set_role_regex)
        self.type_.textEdited.connect(self.clear_type_error)
        self.type_.editingFinished.connect(self.set_type)
        self.type_regex.toggled.connect(self.set_type_regex)
        self.range_.textEdited.connect(self.clear_range_error)
        self.range_.editingFinished.connect(self.set_range)
Beispiel #54
0
    def setupUI(MW, self):

    # Настроки окна
        MW.setGeometry(0, 0, 1080, 720)
        MW.setWindowTitle("Deck Editor")  
        MW.setWindowIcon(QIcon("icons/icon.jpg"))
        MW.center()  # Центрирование окна
        self.statusBar().showMessage("Ready")

        self.centralwidget = QWidget(MW)

    

        # Добавление Виджетов

        # Выпадающий список для выбора героя
        self.hero_list = QComboBox()
        self.hero_list.addItems(['Маг', 'Чернокнижник', 'Друид',
                                    'Палдин', 'Воин', 'Разбойник',
                                    'Жрец', 'Шаман', 'Охотник', 'Охотник на демонов'])
        self.hero_list.currentIndexChanged.connect(self.hero_)

        # Список карт
        self.list_cards = QTableWidget()
        self.list_cards.setColumnCount(5)
        self.list_cards.setSortingEnabled(True)
        self.list_cards.setHorizontalHeaderLabels(["Имя", "Тип", "Класс", "Редкость", "Стоимость"])
        # self.list_cards.setShowGrid(1)
        self.list_cards.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.list_cards.setSelectionMode(QAbstractItemView.NoSelection)
        self.list_cards.setGridStyle(Qt.SolidLine)



        # Картинка для текущей карты
        self.image = QPixmap("icons/start_card.png")

        # Виджет с изображением карты
        self.card = QLabel()
        self.card.setPixmap(self.image)

        # Фильтры

        self.name = QLineEdit()  # Имя
        self.name.setFixedWidth(200)
        self.name.setPlaceholderText('Имя карты')
        self.cards = []
        self.completer = QCompleter(self.cards)
        self.name.setCompleter(self.completer)

        self.class_ = QComboBox()   # Класс
        self.class_.setFixedWidth(130)
        self.class_.addItems(['Жабы', 'Змеи', "Учиха", "Узумаки", "Джинчурики"]) # Здесь нужно парсить все доступные типы из xml

        self.type = QComboBox()  # Тип
        self.type.setFixedWidth(130)
        self.type.addItems(['Существо', 'Заклинание', 'Оружие', 'Герой', 'Земля'])

        self.set = QComboBox()  # Cет
        self.set.setFixedWidth(115)
        self.set.addItems(['HT', 'TK', 'Standart'])
        self.set.currentIndexChanged.connect(self.relist)

        # Progressbar
        self.progress = QProgressBar()
        self.progress.setMaximum(40)
        self.progress.setProperty("value", 0)
        self.progress.setFormat("%v/40")
        self.progress.setFixedWidth(300)

        # Колода
        self.deckList = QTableWidget()
        self.deckList.setFixedWidth(300)

        # Создание layout и размещение виджетов
        self.lo1 = QGridLayout()
        self.lo1.addWidget(self.set, 0, 0, Qt.AlignLeft)
        self.lo1.addWidget(self.hero_list, 0, 1, Qt.AlignLeft)
        self.lo1.addWidget(self.name, 0, 2, Qt.AlignLeft)
        self.lo1.addWidget(self.class_, 0, 3, Qt.AlignLeft)
        self.lo1.addWidget(self.type, 0, 4, Qt.AlignLeft)


        self.grid2 = QGridLayout()

        self.grid2.addWidget(self.list_cards, 0, 0)
        self.grid2.addWidget(self.card, 0, 1, Qt.AlignTop)

        self.deckListlayout = QVBoxLayout()
        self.deckListlayout.addWidget(self.deckList)
        self.deckListlayout.addWidget(self.progress, Qt.AlignBottom)


        self.right = QHBoxLayout()
        self.right.addLayout(self.grid2)
        self.right.addLayout(self.deckListlayout)

        self.gen_layout = QVBoxLayout()

        self.gen_layout.addLayout(self.lo1)
        self.gen_layout.addLayout(self.right)


        self.centralwidget.setLayout(self.gen_layout)

        self.setCentralWidget(self.centralwidget)
Beispiel #55
0
class IbpkeyconQueryTab(AnalysisTab):
    """An ibpkeycon query."""

    section = AnalysisSection.Labeling
    tab_title = "Infiniband Partition Key Contexts"
    mlsonly = False

    def __init__(self, parent, policy, perm_map):
        super().__init__(parent)
        self.log = logging.getLogger(__name__)
        self.policy = policy
        self.query = IbpkeyconQuery(policy)
        self.setupUi()

    def __del__(self):
        with suppress(RuntimeError):
            self.thread.quit()
            self.thread.wait(5000)

        logging.getLogger("setools.ibpkeyconquery").removeHandler(self.handler)

    def setupUi(self):
        self.load_ui("apol/ibpkeyconquery.ui")

        # set up user autocompletion
        user_completion_list = [str(u) for u in self.policy.users()]
        user_completer_model = QStringListModel(self)
        user_completer_model.setStringList(sorted(user_completion_list))
        self.user_completion = QCompleter()
        self.user_completion.setModel(user_completer_model)
        self.user.setCompleter(self.user_completion)

        # set up role autocompletion
        role_completion_list = [str(r) for r in self.policy.roles()]
        role_completer_model = QStringListModel(self)
        role_completer_model.setStringList(sorted(role_completion_list))
        self.role_completion = QCompleter()
        self.role_completion.setModel(role_completer_model)
        self.role.setCompleter(self.role_completion)

        # set up type autocompletion
        type_completion_list = [str(t) for t in self.policy.types()]
        type_completer_model = QStringListModel(self)
        type_completer_model.setStringList(sorted(type_completion_list))
        self.type_completion = QCompleter()
        self.type_completion.setModel(type_completer_model)
        self.type_.setCompleter(self.type_completion)

        # setup indications of errors on source/target/default
        self.errors = set()
        self.orig_palette = self.type_.palette()
        self.error_palette = self.type_.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)
        self.clear_subnet_prefix_error()
        self.clear_pkeys_error()
        self.clear_user_error()
        self.clear_type_error()
        self.clear_role_error()
        self.clear_range_error()

        # set up results
        self.table_results_model = IbpkeyconTableModel(self)
        self.sort_proxy = QSortFilterProxyModel(self)
        self.sort_proxy.setSourceModel(self.table_results_model)
        self.table_results.setModel(self.sort_proxy)
        self.table_results.sortByColumn(0, Qt.AscendingOrder)

        # set up processing thread
        self.thread = QThread()
        self.worker = QueryResultsUpdater(self.query, self.table_results_model)
        self.worker.moveToThread(self.thread)
        self.worker.raw_line.connect(self.raw_results.appendPlainText)
        self.worker.finished.connect(self.update_complete)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.update)

        # create a "busy, please wait" dialog
        self.busy = QProgressDialog(self)
        self.busy.setModal(True)
        self.busy.setRange(0, 0)
        self.busy.setMinimumDuration(0)
        self.busy.canceled.connect(self.thread.requestInterruption)
        self.busy.reset()

        # update busy dialog from query INFO logs
        self.handler = LogHandlerToSignal()
        self.handler.message.connect(self.busy.setLabelText)
        logging.getLogger("setools.ibpkeyconquery").addHandler(self.handler)

        # Ensure settings are consistent with the initial .ui state
        self.criteria_frame.setHidden(not self.criteria_expander.isChecked())
        self.notes.setHidden(not self.notes_expander.isChecked())

        # Range criteria is available only if policy is MLS
        if not self.policy.mls:
            self.range_criteria.setEnabled(False)
            self.range_criteria.setToolTip("MLS is disabled in this policy.")
            self.range_.setToolTip("MLS is disabled in this policy.")
            self.range_exact.setToolTip("MLS is disabled in this policy.")
            self.range_overlap.setToolTip("MLS is disabled in this policy.")
            self.range_subset.setToolTip("MLS is disabled in this policy.")
            self.range_superset.setToolTip("MLS is disabled in this policy.")

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.subnet_prefix.textEdited.connect(self.clear_subnet_prefix_error)
        self.subnet_prefix.editingFinished.connect(self.set_subnet_prefix)
        self.pkeys.textEdited.connect(self.clear_pkeys_error)
        self.pkeys.editingFinished.connect(self.set_pkeys)
        self.user.textEdited.connect(self.clear_user_error)
        self.user.editingFinished.connect(self.set_user)
        self.user_regex.toggled.connect(self.set_user_regex)
        self.role.textEdited.connect(self.clear_role_error)
        self.role.editingFinished.connect(self.set_role)
        self.role_regex.toggled.connect(self.set_role_regex)
        self.type_.textEdited.connect(self.clear_type_error)
        self.type_.editingFinished.connect(self.set_type)
        self.type_regex.toggled.connect(self.set_type_regex)
        self.range_.textEdited.connect(self.clear_range_error)
        self.range_.editingFinished.connect(self.set_range)

    #
    # Subnet prefix criteria
    #
    def clear_subnet_prefix_error(self):
        self.clear_criteria_error(self.subnet_prefix,
                                  "Match the subnet prefix.")

    def set_subnet_prefix(self):
        try:
            self.query.subnet_prefix = self.subnet_prefix.text()
        except Exception as ex:
            self.log.error("Subnet prefix error: {0}".format(ex))
            self.set_criteria_error(self.subnet_prefix, ex)

    #
    # Pkey criteria
    #
    def clear_pkeys_error(self):
        self.clear_criteria_error(self.pkeys, "Match the partition keys.")

    def set_pkeys(self):
        try:
            pending_pkeys = self.pkeys.text()
            if pending_pkeys:
                try:
                    pkeys = [int(i) for i in pending_pkeys.split("-")]
                except ValueError as ex:
                    raise ValueError(
                        "Enter a pkey number or range, e.g. 22 or 6000-6020"
                    ) from ex

                if len(pkeys) == 2:
                    self.query.pkeys = pkeys
                elif len(pkeys) == 1:
                    self.query.pkeys = (pkeys[0], pkeys[0])
                else:
                    raise ValueError(
                        "Enter a pkey number or range, e.g. 22 or 6000-6020")
            else:
                self.query.pkeys = None

        except Exception as ex:
            self.log.error("Partition key error: {0}".format(ex))
            self.set_criteria_error(self.pkeys, ex)

    #
    # User criteria
    #
    def clear_user_error(self):
        self.clear_criteria_error(self.user, "Match the user of the context.")

    def set_user(self):
        try:
            self.query.user = self.user.text()
        except Exception as ex:
            self.log.error("Context user error: {0}".format(ex))
            self.set_criteria_error(self.user, ex)

    def set_user_regex(self, state):
        self.log.debug("Setting user_regex {0}".format(state))
        self.query.user_regex = state
        self.clear_user_error()
        self.set_user()

    #
    # Role criteria
    #
    def clear_role_error(self):
        self.clear_criteria_error(self.role, "Match the role of the context.")

    def set_role(self):
        try:
            self.query.role = self.role.text()
        except Exception as ex:
            self.log.error("Context role error: {0}".format(ex))
            self.set_criteria_error(self.role, ex)

    def set_role_regex(self, state):
        self.log.debug("Setting role_regex {0}".format(state))
        self.query.role_regex = state
        self.clear_role_error()
        self.set_role()

    #
    # Type criteria
    #
    def clear_type_error(self):
        self.clear_criteria_error(self.type_, "Match the type of the context.")

    def set_type(self):
        try:
            self.query.type_ = self.type_.text()
        except Exception as ex:
            self.log.error("Context type error: {0}".format(ex))
            self.set_criteria_error(self.type_, ex)

    def set_type_regex(self, state):
        self.log.debug("Setting type_regex {0}".format(state))
        self.query.type_regex = state
        self.clear_type_error()
        self.set_type()

    #
    # Range criteria
    #
    def clear_range_error(self):
        self.clear_criteria_error(self.range_,
                                  "Match the range of the context.")

    def set_range(self):
        try:
            self.query.range_ = self.range_.text()
        except Exception as ex:
            self.log.info("Context range error: " + str(ex))
            self.set_criteria_error(self.range_, ex)

    #
    # Save/Load tab
    #
    def save(self):
        """Return a dictionary of settings."""
        if self.errors:
            raise TabFieldError("Field(s) are in error: {0}".format(" ".join(
                o.objectName() for o in self.errors)))

        settings = {}
        save_checkboxes(self, settings, [
            "criteria_expander", "notes_expander", "pkeys_exact",
            "pkeys_overlap", "pkeys_subset", "pkeys_superset", "user_regex",
            "role_regex", "type_regex", "range_exact", "range_overlap",
            "range_subset", "range_superset"
        ])
        save_lineedits(
            self, settings,
            ["subnet_prefix", "pkeys", "user", "role", "type_", "range_"])
        save_textedits(self, settings, ["notes"])
        return settings

    def load(self, settings):
        load_checkboxes(self, settings, [
            "criteria_expander", "notes_expander", "pkeys_exact",
            "pkeys_overlap", "pkeys_subset", "pkeys_superset", "user_regex",
            "role_regex", "type_regex", "range_exact", "range_overlap",
            "range_subset", "range_superset"
        ])
        load_lineedits(
            self, settings,
            ["subnet_prefix", "pkeys", "user", "role", "type_", "range_"])
        load_textedits(self, settings, ["notes"])

    #
    # Results runner
    #
    def run(self, button):
        # right now there is only one button.
        self.query.pkeys_overlap = self.pkeys_overlap.isChecked()
        self.query.pkeys_subset = self.pkeys_subset.isChecked()
        self.query.pkeys_superset = self.pkeys_superset.isChecked()
        self.query.range_overlap = self.range_overlap.isChecked()
        self.query.range_subset = self.range_subset.isChecked()
        self.query.range_superset = self.range_superset.isChecked()

        # start processing
        self.busy.setLabelText("Processing query...")
        self.busy.show()
        self.raw_results.clear()
        self.thread.start()

    def update_complete(self, count):
        self.log.info("{0} ibpkeycon statement(s) found.".format(count))

        # update sizes/location of result displays
        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Resizing the result table's columns; GUI may be unresponsive")
            self.busy.repaint()
            self.table_results.resizeColumnsToContents()

        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Resizing the result table's rows; GUI may be unresponsive")
            self.busy.repaint()
            self.table_results.resizeRowsToContents()

        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Moving the raw result to top; GUI may be unresponsive")
            self.busy.repaint()
            self.raw_results.moveCursor(QTextCursor.Start)

        self.busy.reset()
Beispiel #56
0
    def relist(self):

        # try:
        #     print(self.library)
        #     self.library is not None
        # except:
        #     self.open()

        print(self.library)
        try:
            self.library is not None
        except:
            return

        self.list_cards.clear()
        self.list_cards.setRowCount(0)
        self.row = 0

        if self.set.currentText() == 'HT':

            self.esc = self.func_read(self.library)
            self.cards = list(
                map(lambda x: x[:x.rfind('.png')], list(self.esc.keys())))

            for i in self.cards:
                self.row += 1
                self.list_cards.setRowCount(self.row + 1)
                self.list_cards.setItem(self.row - 1, 0, QTableWidgetItem(i))
                self.list_cards.setItem(self.row - 1, 1, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 2, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 3, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 4, QTableWidgetItem('1'))
            self.list_cards.setRowCount(self.row - 1)

            self.completer = QCompleter(self.cards)
            self.name.setCompleter(self.completer)

        elif self.set.currentText() == 'TK':

            self.esc_TK = self.func_read(
                self.library[:self.library.rfind('/')] + '/TK.xml')
            self.TK = list(
                map(lambda x: x[:x.rfind('.png')], list(self.esc_TK.keys())))

            for i in self.TK:
                self.row += 1
                self.list_cards.setRowCount(self.row + 1)
                self.list_cards.setItem(self.row - 1, 0, QTableWidgetItem(i))
                self.list_cards.setItem(self.row - 1, 1, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 2, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 3, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 4, QTableWidgetItem('1'))
            self.list_cards.setRowCount(self.row - 1)

            self.completer = QCompleter(self.TK)
            self.name.setCompleter(self.completer)

        elif self.set.currentText() == 'Standart':

            self.esc_std = self.func_read(
                self.library[:self.library.rfind('/')] + '/StandardCards.xml')
            self.std = list(
                map(lambda x: x[:x.rfind('.png')], list(self.esc_std.keys())))

            for i in self.std:
                self.row += 1
                self.list_cards.setRowCount(self.row + 1)
                self.list_cards.setItem(self.row - 1, 0, QTableWidgetItem(i))
                self.list_cards.setItem(self.row - 1, 1, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 2, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 3, QTableWidgetItem('1'))
                self.list_cards.setItem(self.row - 1, 4, QTableWidgetItem('1'))
            self.list_cards.setRowCount(self.row - 1)

            self.completer = QCompleter(self.std)
            self.name.setCompleter(self.completer)

        else:
            QMessageBox.about(self, "Ошибка", "Не удалось подгрузить карты")

        self.list_cards.setHorizontalHeaderLabels(
            ["Имя", "Тип", "Класс", "Редкость", "Стоимость"])
Beispiel #57
0
class PairCreatorWindow(QDialog):
    """
    Dialog window for creating a student pair.
    """
    def __init__(self, number, parent: QWidget = None):
        super().__init__(parent)

        self._number: int = number
        self._edit_pair: StudentPair = None
        self._dates: DatePair = DatePair()

        # window settings
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)
        self.setWindowTitle(self.tr("Creator"))
        self.setMinimumSize(640, 350)
        self.resize(800, 400)

        # general settings window
        self.group_box_general = QGroupBox(self.tr("General"))
        self.layout_general = QFormLayout(self.group_box_general)

        # title
        self.label_title = QLabel(self.tr("Title"))
        self.layout_general.setWidget(0, QFormLayout.LabelRole,
                                      self.label_title)
        self.line_edit_title = QLineEdit("")
        self.layout_general.setWidget(0, QFormLayout.FieldRole,
                                      self.line_edit_title)

        # lecturer
        self.label_lecturer = QLabel(self.tr("Lecturer"))
        self.layout_general.setWidget(1, QFormLayout.LabelRole,
                                      self.label_lecturer)
        self.line_edit_lecturer = QLineEdit("")
        self.layout_general.setWidget(1, QFormLayout.FieldRole,
                                      self.line_edit_lecturer)

        self.completer = QCompleter(LecturerPair.get_lecturers())
        self.completer.setModelSorting(QCompleter.CaseSensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setFilterMode(Qt.MatchContains)
        self.line_edit_lecturer.setCompleter(self.completer)

        # type
        self.label_type = QLabel(self.tr("Type"))
        self.layout_general.setWidget(2, QFormLayout.LabelRole,
                                      self.label_type)
        self.combo_box_type = QComboBox()
        self.layout_general.setWidget(2, QFormLayout.FieldRole,
                                      self.combo_box_type)

        for name, attrib in TypePairAttrib.items():
            self.combo_box_type.addItem(name, attrib)

        # classes
        self.label_classes = QLabel(self.tr("Classes"))
        self.layout_general.setWidget(3, QFormLayout.LabelRole,
                                      self.label_classes)
        self.line_edit_classes = QLineEdit("")
        self.layout_general.setWidget(3, QFormLayout.FieldRole,
                                      self.line_edit_classes)

        # subgroup
        self.label_subgroup = QLabel(self.tr("Subgroup"))
        self.layout_general.setWidget(4, QFormLayout.LabelRole,
                                      self.label_subgroup)
        self.combo_box_subgroup = QComboBox()
        self.layout_general.setWidget(4, QFormLayout.FieldRole,
                                      self.combo_box_subgroup)

        for name, attrib in SubgroupPairAttrib.items():
            self.combo_box_subgroup.addItem(name, attrib)

        # time setting
        self.group_box_time = QGroupBox(self.tr("Time"))
        self.layout_time = QFormLayout(self.group_box_time)

        self.label_start = QLabel(self.tr("Start"))
        self.layout_time.setWidget(0, QFormLayout.LabelRole, self.label_start)
        self.combo_box_start = QComboBox()
        self.layout_time.setWidget(0, QFormLayout.FieldRole,
                                   self.combo_box_start)

        self.label_end = QLabel(self.tr("End"))
        self.layout_time.setWidget(1, QFormLayout.LabelRole, self.label_end)
        self.combo_box_end = QComboBox()
        self.layout_time.setWidget(1, QFormLayout.FieldRole,
                                   self.combo_box_end)

        self.combo_box_start.addItems(TimePair.time_starts())
        self.combo_box_start.setCurrentIndex(self._number)
        self.combo_box_end.addItems(TimePair.time_ends())
        self.combo_box_end.setCurrentIndex(self._number)

        # date setting
        self.group_box_date = QGroupBox(self.tr("Date"))
        self.layout_date_edit = QHBoxLayout(self.group_box_date)

        self.list_widget_date = QListWidget(self.group_box_date)
        self.layout_date_edit.addWidget(self.list_widget_date)

        self.layout_date_edit_navigate = QVBoxLayout()
        self.layout_date_edit.addLayout(self.layout_date_edit_navigate)

        self.push_button_add_date = QPushButton(self.tr("Add"))
        self.layout_date_edit_navigate.addWidget(self.push_button_add_date)

        self.push_button_edit_date = QPushButton(self.tr("Edit"))
        self.layout_date_edit_navigate.addWidget(self.push_button_edit_date)

        self.push_button_remove_date = QPushButton(self.tr("Remove"))
        self.layout_date_edit_navigate.addWidget(self.push_button_remove_date)

        self.layout_date_edit_navigate.addStretch(1)

        # navigate
        self.layout_navigate = QHBoxLayout()

        self.layout_navigate.addStretch(1)

        self.push_button_ok = QPushButton(self.tr("OK"))
        self.layout_navigate.addWidget(self.push_button_ok)

        self.push_button_cancel = QPushButton(self.tr("Cancel"))
        self.layout_navigate.addWidget(self.push_button_cancel)

        # layout settings
        self.layout_general_time = QVBoxLayout()
        self.layout_general_time.addWidget(self.group_box_general)
        self.layout_general_time.addWidget(self.group_box_time)

        self.layout_center = QHBoxLayout()
        self.layout_center.addLayout(self.layout_general_time)
        self.layout_center.addWidget(self.group_box_date)

        self.layout_main = QVBoxLayout()
        self.layout_main.addLayout(self.layout_center)
        self.layout_main.addLayout(self.layout_navigate)

        self.setLayout(self.layout_main)

        # connection
        self.combo_box_start.currentIndexChanged.connect(
            self.combo_box_start_changed)
        self.list_widget_date.itemDoubleClicked.connect(
            self.push_button_edit_date_clicked)
        self.push_button_add_date.clicked.connect(
            self.push_button_add_date_clicked)
        self.push_button_edit_date.clicked.connect(
            self.push_button_edit_date_clicked)
        self.push_button_remove_date.clicked.connect(
            self.push_button_remove_date_clicked)
        self.push_button_ok.clicked.connect(self.push_button_ok_clicked)
        self.push_button_cancel.clicked.connect(
            self.push_button_cancel_clicked)

    def save(self) -> bool:
        """
        Saves the created / edited a student pair.
        Returns True/False depending on whether the save was successful or not.
        """
        title = self.line_edit_title.text().strip()
        if title == "":
            QMessageBox.information(self, self.tr("Information"),
                                    self.tr("Title field is empty"))
            return False

        lecturer = self.line_edit_lecturer.text().strip()
        if lecturer == "":
            QMessageBox.information(self, self.tr("Information"),
                                    self.tr("Lecturer field is empty"))
            return False

        classes = self.line_edit_classes.text().strip()
        if classes == "":
            QMessageBox.information(self, self.tr("Information"),
                                    self.tr("Classes field is empty"))
            return False

        pair_type = self.combo_box_type.currentData(Qt.UserRole)
        subgroup = self.combo_box_subgroup.currentData(Qt.UserRole)

        start_time = self.combo_box_start.currentText()
        end_time = self.combo_box_end.currentText()

        if self.list_widget_date.count() == 0:
            QMessageBox.information(self, self.tr("Information"),
                                    self.tr("No dates"))
            return False

        new_pair = StudentPair()
        new_pair["title"].set_title(title)
        new_pair["lecturer"].set_lecturer(lecturer)
        new_pair["type"].set_type(pair_type)
        new_pair["classroom"].set_classroom(classes)
        new_pair["subgroup"].set_subgroup(subgroup)
        new_pair["time"].set_time(start_time, end_time)
        for date in self._dates:
            new_pair["dates"].add_date(date)

        self._edit_pair = new_pair

        return True

    def set_pair(self, pair: StudentPair) -> None:
        """
        Method to set the pair to edit.

        :param pair: Pair
        """
        self._edit_pair = pair
        self.line_edit_title.setText(str(self._edit_pair["title"]))
        self.line_edit_lecturer.setText(str(self._edit_pair["lecturer"]))
        self.combo_box_type.setCurrentText(str(self._edit_pair["type"]))
        self.line_edit_classes.setText(str(self._edit_pair["classroom"]))
        self.combo_box_subgroup.setCurrentText(str(
            self._edit_pair["subgroup"]))

        time: TimePair = self._edit_pair["time"]
        if time is not None:
            number = time.get_number()
            self.combo_box_start.setCurrentIndex(number)
            self.combo_box_end.clear()
            self.combo_box_end.addItems(TimePair.time_ends()[number:])
            self.combo_box_end.setCurrentIndex(time.duration() - 1)

        self._dates = self._edit_pair["dates"]
        self.update_list_widget_date()

    def get_pair(self) -> (StudentPair, None):
        """
        Returns an editable pair.
        """
        return self._edit_pair

    def push_button_add_date_clicked(self) -> None:
        """
        Slot for add date button.
        """
        date_creator = DateCreatorWindow(self)
        while True:
            date_creator.exec_()
            create_date = date_creator.get_date()
            if create_date is not None:
                try:
                    self._dates.add_date(create_date)
                    self.update_list_widget_date()
                    break
                except InvalidDatePair as ex:
                    QMessageBox.critical(self, self.tr("Invalid date pair"),
                                         str(ex))
            else:
                break

    def push_button_edit_date_clicked(self) -> None:
        """
        Slot for edit date button.
        """
        item = self.list_widget_date.currentItem()
        if item is None:
            QMessageBox.information(self, self.tr("Information"),
                                    self.tr("No date selected"))
            return

        original_date = item.data(Qt.UserRole)
        self._dates.remove_date(item.data(Qt.UserRole))

        date_editor = DateCreatorWindow(self)
        date_editor.set_date(original_date.copy())

        while True:
            date_editor.exec_()
            edit_date = date_editor.get_date()
            if edit_date is not None:
                try:
                    self._dates.add_date(edit_date)
                    self.update_list_widget_date()
                    break
                except InvalidDatePair as ex:
                    QMessageBox.critical(self, self.tr("Invalid date pair"),
                                         str(ex))
            else:
                self._dates.add_date(original_date)
                break

    def push_button_remove_date_clicked(self) -> None:
        """
        Slot for remove date button.
        """
        item = self.list_widget_date.currentItem()
        if item is None:
            QMessageBox.information(self, self.tr("Information"),
                                    self.tr("No date selected"))
            return

        self._dates.remove_date(item.data(Qt.UserRole))
        self.update_list_widget_date()

    def update_list_widget_date(self) -> None:
        """
        Updates the list of dates in the window.
        """
        self.list_widget_date.clear()
        for date in self._dates:
            item = QListWidgetItem(str(date))
            item.setData(Qt.UserRole, date)
            self.list_widget_date.addItem(item)

    def push_button_ok_clicked(self) -> None:
        """
        Slot for ok button.
        """
        if self.save():
            self.close()

    def push_button_cancel_clicked(self) -> None:
        """
        Slot for cancel button.
        """
        self._edit_pair = None
        self.close()

    def combo_box_start_changed(self, index) -> None:
        """
        Slot to change the end time of the pair.
        """
        old_index = self.combo_box_end.currentIndex()
        self.combo_box_end.clear()
        self.combo_box_end.addItems(TimePair.time_ends()[index:])
Beispiel #58
0
class DiscoveryPlugin:
    def __init__(self, _iface):
        # Save reference to the QGIS interface
        self.iface = _iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # Variables to facilitate delayed queries and database connection management
        self.db_timer = QTimer()
        self.line_edit_timer = QTimer()
        self.line_edit_timer.setSingleShot(True)
        self.line_edit_timer.timeout.connect(self.reset_line_edit_after_move)
        self.next_query_time = None
        self.last_query_time = time.time()
        self.db_conn = None
        self.search_delay = 0.5  # s
        self.query_sql = ''
        self.query_text = ''
        self.query_dict = {}
        self.db_idle_time = 60.0  # s
        self.display_time = 5000  # ms
        self.bar_info_time = 30  # s

        self.search_results = []
        self.tool_bar = None
        self.search_line_edit = None
        self.completer = None
        self.conn_info = {}

        self.marker = QgsVertexMarker(iface.mapCanvas())
        self.marker.setIconSize(15)
        self.marker.setPenWidth(2)
        self.marker.setColor(QColor(226, 27, 28))  #51,160,44))
        self.marker.setZValue(11)
        self.marker.setVisible(False)
        self.marker2 = QgsVertexMarker(iface.mapCanvas())
        self.marker2.setIconSize(16)
        self.marker2.setPenWidth(4)
        self.marker2.setColor(QColor(255, 255, 255, 200))
        self.marker2.setZValue(10)
        self.marker2.setVisible(False)
        self.is_displayed = False

        self.rubber_band = QgsRubberBand(iface.mapCanvas(), False)
        self.rubber_band.setVisible(False)
        self.rubber_band.setWidth(3)
        self.rubber_band.setStrokeColor(QColor(226, 27, 28))
        self.rubber_band.setFillColor(QColor(226, 27, 28, 63))

    def initGui(self):

        # Create a new toolbar
        self.tool_bar = self.iface.addToolBar('Discovery')
        self.tool_bar.setObjectName('Discovery_Plugin')

        # Create action that will start plugin configuration
        self.action_config = QAction(
            QIcon(os.path.join(self.plugin_dir, "discovery_logo.png")),
            u"Configure Discovery", self.tool_bar)
        self.action_config.triggered.connect(self.show_config_dialog)
        self.tool_bar.addAction(self.action_config)

        # Add combobox for configs
        self.config_combo = QComboBox()
        settings = QgsSettings()
        settings.beginGroup("/Discovery")
        config_list = settings.value("config_list")

        if config_list:
            for conf in config_list:
                self.config_combo.addItem(conf)
        elif settings.childGroups():
            # support for prev version
            key = "Config1"
            config_list = []
            config_list.append(key)
            settings.setValue("config_list", config_list)
            self.config_combo.addItem(key)

            settings.setValue(key + "data_type", settings.value("data_type"))
            settings.setValue(key + "file", settings.value("file"))
            settings.setValue(key + "connection", settings.value("connection"))
            settings.setValue(key + "schema", settings.value("schema"))
            settings.setValue(key + "table", settings.value("table"))
            settings.setValue(key + "search_column",
                              settings.value("search_column"))
            settings.setValue(key + "echo_search_column",
                              settings.value("echo_search_column"))
            settings.setValue(key + "display_columns",
                              settings.value("display_columns"))
            settings.setValue(key + "geom_column",
                              settings.value("geom_column"))
            settings.setValue(key + "scale_expr", settings.value("scale_expr"))
            settings.setValue(key + "bbox_expr", settings.value("bbox_expr"))

            delete_config_from_settings("", settings)
        self.tool_bar.addWidget(self.config_combo)

        # Add search edit box
        self.search_line_edit = QgsFilterLineEdit()
        self.search_line_edit.setPlaceholderText('Search for...')
        self.search_line_edit.setMaximumWidth(768)
        self.tool_bar.addWidget(self.search_line_edit)

        self.config_combo.currentIndexChanged.connect(
            self.change_configuration)

        # Set up the completer
        self.completer = QCompleter([])  # Initialise with en empty list
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setMaxVisibleItems(1000)
        self.completer.setModelSorting(
            QCompleter.UnsortedModel)  # Sorting done in PostGIS
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion
                                         )  # Show all fetched possibilities
        self.completer.activated[QModelIndex].connect(self.on_result_selected)
        self.completer.highlighted[QModelIndex].connect(
            self.on_result_highlighted)
        self.search_line_edit.setCompleter(self.completer)

        # Connect any signals
        self.search_line_edit.textEdited.connect(self.on_search_text_changed)

        # Search results
        self.search_results = []

        # Set up a timer to periodically perform db queries as required
        self.db_timer.timeout.connect(self.do_db_operations)
        self.db_timer.start(100)

        # Read config
        self.read_config(config_list[0] if config_list else "")

        self.locator_filter = locator_filter.DiscoveryLocatorFilter(self)
        self.iface.registerLocatorFilter(self.locator_filter)

        # Debug
        # import pydevd; pydevd.settrace('localhost', port=5678)

    def unload(self):
        # Stop timer
        self.db_timer.stop()
        # Disconnect any signals
        self.db_timer.timeout.disconnect(self.do_db_operations)
        self.completer.highlighted[QModelIndex].disconnect(
            self.on_result_highlighted)
        self.completer.activated[QModelIndex].disconnect(
            self.on_result_selected)
        self.search_line_edit.textEdited.disconnect(
            self.on_search_text_changed)
        # Remove the new toolbar
        self.tool_bar.clear()  # Clear all actions
        self.iface.mainWindow().removeToolBar(self.tool_bar)

        self.iface.deregisterLocatorFilter(self.locator_filter)
        self.locator_filter = None

    def clear_suggestions(self):
        model = self.completer.model()
        model.setStringList([])

    def on_search_text_changed(self, new_search_text):
        """
        This function is called whenever the user modified the search text

        1. Open a database connection
        2. Make the query
        3. Update the QStringListModel with these results
        4. Store the other details in self.search_results
        """

        self.query_text = new_search_text

        if len(new_search_text) < 3:
            # Clear any previous suggestions in case the user is 'backspacing'
            self.clear_suggestions()
            return

        if self.data_type == "postgres":
            query_text, query_dict = dbutils.get_search_sql(
                new_search_text, self.postgisgeomcolumn,
                self.postgissearchcolumn, self.echosearchcolumn,
                self.postgisdisplaycolumn, self.extra_expr_columns,
                self.postgisschema, self.postgistable)
            self.schedule_search(query_text, query_dict)

        elif self.data_type == "gpkg":
            query_text = (new_search_text, self.postgissearchcolumn,
                          self.echosearchcolumn,
                          self.postgisdisplaycolumn.split(","),
                          self.extra_expr_columns, self.layer)
            self.schedule_search(query_text, None)

        elif self.data_type == "mssql":
            query_text = mssql_utils.get_search_sql(
                new_search_text, self.postgisgeomcolumn,
                self.postgissearchcolumn, self.echosearchcolumn,
                self.postgisdisplaycolumn, self.extra_expr_columns,
                self.postgisschema, self.postgistable)
            self.schedule_search(query_text, None)

    def do_db_operations(self):
        if self.next_query_time is not None and self.next_query_time < time.time(
        ):
            # It's time to run a query
            self.next_query_time = None  # Prevent this query from being repeated
            self.last_query_time = time.time()
            self.perform_search()
        else:
            # We're not performing a query, close the db connection if it's been open for > 60s
            if time.time() > self.last_query_time + self.db_idle_time:
                self.db_conn = None

    def perform_search(self):
        db = self.get_db()
        self.search_results = []
        suggestions = []
        if self.data_type == "postgres":
            cur = db.cursor()
            try:
                cur.execute(self.query_sql, self.query_dict)
            except psycopg2.Error as e:
                err_info = "Failed to execute the search query. Please, check your settings. Error message:\n\n"
                err_info += f"{e.pgerror}"
                QMessageBox.critical(None, "Discovery", err_info)
                return
            result_set = cur.fetchall()
        elif self.data_type == "mssql":
            result_set = mssql_utils.execute(db, self.query_sql)
        elif self.data_type == "gpkg":
            result_set = gpkg_utils.search_gpkg(*self.query_sql)

        for row in result_set:
            geom, epsg, suggestion_text = row[0], row[1], row[2]
            extra_data = {}
            for idx, extra_col in enumerate(self.extra_expr_columns):
                extra_data[extra_col] = row[3 + idx]
            self.search_results.append(
                (geom, epsg, suggestion_text, extra_data))
            suggestions.append(suggestion_text)
        model = self.completer.model()
        model.setStringList(suggestions)
        self.completer.complete()

    def schedule_search(self, query_text, query_dict):
        # Update the search text and the time after which the query should be executed
        self.query_sql = query_text
        self.query_dict = query_dict
        self.next_query_time = time.time() + self.search_delay

    def show_bar_info(self, info_text):
        """Optional show info bar message with selected result information"""
        self.iface.messageBar().clearWidgets()
        if self.bar_info_time:
            self.iface.messageBar().pushMessage("Discovery",
                                                info_text,
                                                level=Qgis.Info,
                                                duration=self.bar_info_time)

    def on_result_selected(self, result_index):
        # What to do when the user makes a selection
        self.select_result(self.search_results[result_index.row()])

    def select_result(self, result_data):
        geometry_text, src_epsg, suggestion_text, extra_data = result_data
        location_geom = QgsGeometry.fromWkt(geometry_text)
        canvas = self.iface.mapCanvas()
        dst_srid = canvas.mapSettings().destinationCrs().authid()
        transform = QgsCoordinateTransform(
            QgsCoordinateReferenceSystem(src_epsg),
            QgsCoordinateReferenceSystem(dst_srid),
            canvas.mapSettings().transformContext())
        # Ensure the geometry from the DB is reprojected to the same SRID as the map canvas
        location_geom.transform(transform)
        location_centroid = location_geom.centroid().asPoint()

        # show temporary marker
        if location_geom.type() == QgsWkbTypes.PointGeometry:
            self.show_marker(location_centroid)
        elif location_geom.type() == QgsWkbTypes.LineGeometry or \
            location_geom.type() == QgsWkbTypes.PolygonGeometry:
            self.show_line_rubber_band(location_geom)
        else:
            #unsupported geometry type
            pass

        # Adjust map canvas extent
        zoom_method = 'Move and Zoom'
        if zoom_method == 'Move and Zoom':
            # with higher priority try to use exact bounding box to zoom to features (if provided)
            bbox_str = eval_expression(self.bbox_expr, extra_data)
            rect = bbox_str_to_rectangle(bbox_str)
            if rect is not None:
                # transform the rectangle in case of OTF projection
                rect = transform.transformBoundingBox(rect)
            else:
                # bbox is not available - so let's just use defined scale
                # compute target scale. If the result is 2000 this means the target scale is 1:2000
                rect = location_geom.boundingBox()
                if rect.isEmpty():
                    scale_denom = eval_expression(self.scale_expr,
                                                  extra_data,
                                                  default=2000.)
                    rect = canvas.mapSettings().extent()
                    rect.scale(scale_denom / canvas.scale(), location_centroid)
                else:
                    # enlarge geom bbox to have some margin
                    rect.scale(1.2)
            canvas.setExtent(rect)
        elif zoom_method == 'Move':
            current_extent = QgsGeometry.fromRect(
                self.iface.mapCanvas().extent())
            dx = location_centroid.x() - location_centroid.x()
            dy = location_centroid.y() - location_centroid.y()
            current_extent.translate(dx, dy)
            canvas.setExtent(current_extent.boundingBox())
        canvas.refresh()
        self.line_edit_timer.start(0)
        if self.info_to_clipboard:
            QApplication.clipboard().setText(suggestion_text)
            suggestion_text += ' (copied to clipboard)'
        self.show_bar_info(suggestion_text)

    def on_result_highlighted(self, result_idx):
        self.line_edit_timer.start(0)

    def reset_line_edit_after_move(self):
        self.search_line_edit.setText(self.query_text)

    def get_db(self):
        # Create a new new connection if required
        if self.db_conn is None:
            if self.data_type == "postgres":
                self.db_conn = dbutils.get_connection(self.conn_info)
            elif self.data_type == "mssql":
                self.db_conn = mssql_utils.get_mssql_conn(self.conn_info)
        return self.db_conn

    def change_configuration(self):
        self.search_line_edit.setText("")
        self.line_edit_timer.start(0)
        self.read_config(self.config_combo.currentText())

    def read_config(self, key=""):
        # the following code reads the configuration file which setups the plugin to search in the correct database,
        # table and method

        settings = QgsSettings()
        settings.beginGroup("/Discovery")

        connection = settings.value(key + "connection", "", type=str)
        self.data_type = settings.value(key + "data_type", "", type=str)
        self.file = settings.value(key + "file", "", type=str)
        self.postgisschema = settings.value(key + "schema", "", type=str)
        self.postgistable = settings.value(key + "table", "", type=str)
        self.postgissearchcolumn = settings.value(key + "search_column",
                                                  "",
                                                  type=str)
        self.echosearchcolumn = settings.value(key + "echo_search_column",
                                               True,
                                               type=bool)
        self.postgisdisplaycolumn = settings.value(key + "display_columns",
                                                   "",
                                                   type=str)
        self.postgisgeomcolumn = settings.value(key + "geom_column",
                                                "",
                                                type=str)
        if settings.value("marker_time_enabled", True, type=bool):
            self.display_time = settings.value("marker_time", 5000, type=int)
        else:
            self.display_time = -1
        if settings.value("bar_info_time_enabled", True, type=bool):
            self.bar_info_time = settings.value("bar_info_time", 30, type=int)
        else:
            self.bar_info_time = 0
        self.info_to_clipboard = settings.value("info_to_clipboard",
                                                True,
                                                type=bool)

        scale_expr = settings.value(key + "scale_expr", "", type=str)
        bbox_expr = settings.value(key + "bbox_expr", "", type=str)

        if self.is_displayed:
            self.hide_marker()
            self.hide_rubber_band()
            self.is_displayed = False

        self.make_enabled(False)  # assume the config is invalid first

        self.db_conn = None
        if self.data_type == "postgres":
            self.conn_info = dbutils.get_postgres_conn_info(connection)
            self.layer = None

            if len(connection) == 0 or len(self.postgisschema) == 0 or len(self.postgistable) == 0 or \
                    len(self.postgissearchcolumn) == 0 or len(self.postgisgeomcolumn) == 0:
                return

            if len(self.conn_info) == 0:
                iface.messageBar().pushMessage(
                    "Discovery",
                    "The database connection '%s' does not exist!" %
                    connection,
                    level=Qgis.Critical)
                return
        if self.data_type == "mssql":
            self.conn_info = mssql_utils.get_mssql_conn_info(connection)
            self.layer = None

            if len(connection) == 0 or len(self.postgisschema) == 0 or len(self.postgistable) == 0 or \
                    len(self.postgissearchcolumn) == 0 or len(self.postgisgeomcolumn) == 0:
                return

            if len(self.conn_info) == 0:
                iface.messageBar().pushMessage(
                    "Discovery",
                    "The database connection '%s' does not exist!" %
                    connection,
                    level=Qgis.Critical)
                return
        elif self.data_type == "gpkg":
            self.layer = QgsVectorLayer(
                self.file + '|layername=' + self.postgistable,
                self.postgistable, 'ogr')
            self.conn_info = None
        self.extra_expr_columns = []
        self.scale_expr = None
        self.bbox_expr = None

        self.make_enabled(True)

        # optional scale expression when zooming in to results
        if len(scale_expr) != 0:
            expr = QgsExpression(scale_expr)
            if expr.hasParserError():
                iface.messageBar().pushMessage("Discovery",
                                               "Invalid scale expression: " +
                                               expr.parserErrorString(),
                                               level=Qgis.Warning)
            else:
                self.scale_expr = scale_expr
                self.extra_expr_columns += expr.referencedColumns()

        # optional bbox expression when zooming in to results
        if len(bbox_expr) != 0:
            expr = QgsExpression(bbox_expr)
            if expr.hasParserError():
                iface.messageBar().pushMessage("Discovery",
                                               "Invalid bbox expression: " +
                                               expr.parserErrorString(),
                                               level=Qgis.Warning)
            else:
                self.bbox_expr = bbox_expr
                self.extra_expr_columns += expr.referencedColumns()

    def show_config_dialog(self):
        dlg = config_dialog.ConfigDialog()
        if (self.config_combo.currentIndex() >= 0):
            dlg.configOptions.setCurrentIndex(self.config_combo.currentIndex())

        if dlg.exec_():
            dlg.write_config()
            self.config_combo.clear()
            for key in [
                    dlg.configOptions.itemText(i)
                    for i in range(dlg.configOptions.count())
            ]:
                self.config_combo.addItem(key)

            self.config_combo.setCurrentIndex(dlg.configOptions.currentIndex())
            self.change_configuration()

    def make_enabled(self, enabled):
        self.search_line_edit.setEnabled(enabled)
        self.search_line_edit.setPlaceholderText(
            "Search for..."
            if enabled else "Search disabled: check configuration")

    def show_marker(self, point):
        for m in [self.marker, self.marker2]:
            m.setCenter(point)
            m.setOpacity(1.0)
            m.setVisible(True)
        if self.display_time == -1:
            self.is_displayed = True
        else:
            QTimer.singleShot(self.display_time, self.hide_marker)

    def hide_marker(self):
        opacity = self.marker.opacity()
        if opacity > 0.:
            # produce a fade out effect
            opacity -= 0.1
            self.marker.setOpacity(opacity)
            self.marker2.setOpacity(opacity)
            QTimer.singleShot(100, self.hide_marker)
        else:
            self.marker.setVisible(False)
            self.marker2.setVisible(False)

    def show_line_rubber_band(self, geom):
        self.rubber_band.reset(geom.type())
        self.rubber_band.setToGeometry(geom, None)
        self.rubber_band.setVisible(True)
        self.rubber_band.setOpacity(1.0)
        self.rubber_band.show()
        if self.display_time == -1:
            self.is_displayed = True
        else:
            QTimer.singleShot(self.display_time, self.hide_rubber_band)
        pass

    def hide_rubber_band(self):
        opacity = self.rubber_band.opacity()
        if opacity > 0.:
            # produce a fade out effect
            opacity -= 0.1
            self.rubber_band.setOpacity(opacity)
            QTimer.singleShot(100, self.hide_rubber_band)
        else:
            self.rubber_band.setVisible(False)
            self.rubber_band.hide()
Beispiel #59
0
class MLSRuleQueryTab(SEToolsWidget, QScrollArea):
    """An MLS rule query."""
    def __init__(self, parent, policy, perm_map):
        super(MLSRuleQueryTab, self).__init__(parent)
        self.log = logging.getLogger(self.__class__.__name__)
        self.policy = policy
        self.query = MLSRuleQuery(policy)
        self.setupUi()

    def __del__(self):
        self.thread.quit()
        self.thread.wait(5000)

    def setupUi(self):
        self.load_ui("mlsrulequery.ui")

        # set up source/target autocompletion
        typeattr_completion_list = [str(t) for t in self.policy.types()]
        typeattr_completion_list.extend(
            str(a) for a in self.policy.typeattributes())
        typeattr_completer_model = QStringListModel(self)
        typeattr_completer_model.setStringList(
            sorted(typeattr_completion_list))
        self.typeattr_completion = QCompleter()
        self.typeattr_completion.setModel(typeattr_completer_model)
        self.source.setCompleter(self.typeattr_completion)
        self.target.setCompleter(self.typeattr_completion)

        # setup indications of errors on source/target/default
        self.orig_palette = self.source.palette()
        self.error_palette = self.source.palette()
        self.error_palette.setColor(QPalette.Base, Qt.red)
        self.clear_source_error()
        self.clear_target_error()
        self.clear_default_error()

        # populate class list
        self.class_model = SEToolsListModel(self)
        self.class_model.item_list = sorted(self.policy.classes())
        self.tclass.setModel(self.class_model)

        # set up results
        self.table_results_model = MLSRuleListModel(self)
        self.sort_proxy = QSortFilterProxyModel(self)
        self.sort_proxy.setSourceModel(self.table_results_model)
        self.table_results.setModel(self.sort_proxy)

        # set up processing thread
        self.thread = QThread()
        self.worker = ResultsUpdater(self.query, self.table_results_model)
        self.worker.moveToThread(self.thread)
        self.worker.raw_line.connect(self.raw_results.appendPlainText)
        self.worker.finished.connect(self.update_complete)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.update)

        # create a "busy, please wait" dialog
        self.busy = QProgressDialog(self)
        self.busy.setModal(True)
        self.busy.setRange(0, 0)
        self.busy.setMinimumDuration(0)
        self.busy.canceled.connect(self.thread.requestInterruption)

        # Ensure settings are consistent with the initial .ui state
        self.set_source_regex(self.source_regex.isChecked())
        self.set_target_regex(self.target_regex.isChecked())
        self.criteria_frame.setHidden(not self.criteria_expander.isChecked())
        self.results_frame.setHidden(not self.results_expander.isChecked())
        self.notes.setHidden(not self.notes_expander.isChecked())

        # connect signals
        self.buttonBox.clicked.connect(self.run)
        self.clear_ruletypes.clicked.connect(self.clear_all_ruletypes)
        self.all_ruletypes.clicked.connect(self.set_all_ruletypes)
        self.source.textEdited.connect(self.clear_source_error)
        self.source.editingFinished.connect(self.set_source)
        self.source_regex.toggled.connect(self.set_source_regex)
        self.target.textEdited.connect(self.clear_target_error)
        self.target.editingFinished.connect(self.set_target)
        self.target_regex.toggled.connect(self.set_target_regex)
        self.tclass.selectionModel().selectionChanged.connect(self.set_tclass)
        self.invert_class.clicked.connect(self.invert_tclass_selection)
        self.default_range.textEdited.connect(self.clear_default_error)
        self.default_range.editingFinished.connect(self.set_default_range)

    #
    # Ruletype criteria
    #

    def _set_ruletypes(self, value):
        self.range_transition.setChecked(value)

    def set_all_ruletypes(self):
        self._set_ruletypes(True)

    def clear_all_ruletypes(self):
        self._set_ruletypes(False)

    #
    # Source criteria
    #

    def clear_source_error(self):
        self.source.setToolTip("Match the source type/attribute of the rule.")
        self.source.setPalette(self.orig_palette)

    def set_source(self):
        try:
            self.query.source = self.source.text()
        except Exception as ex:
            self.source.setToolTip("Error: " + str(ex))
            self.source.setPalette(self.error_palette)

    def set_source_regex(self, state):
        self.log.debug("Setting source_regex {0}".format(state))
        self.query.source_regex = state
        self.clear_source_error()
        self.set_source()

    #
    # Target criteria
    #

    def clear_target_error(self):
        self.target.setToolTip("Match the target type/attribute of the rule.")
        self.target.setPalette(self.orig_palette)

    def set_target(self):
        try:
            self.query.target = self.target.text()
        except Exception as ex:
            self.target.setToolTip("Error: " + str(ex))
            self.target.setPalette(self.error_palette)

    def set_target_regex(self, state):
        self.log.debug("Setting target_regex {0}".format(state))
        self.query.target_regex = state
        self.clear_target_error()
        self.set_target()

    #
    # Class criteria
    #

    def set_tclass(self):
        selected_classes = []
        for index in self.tclass.selectionModel().selectedIndexes():
            selected_classes.append(self.class_model.data(index, Qt.UserRole))

        self.query.tclass = selected_classes

    def invert_tclass_selection(self):
        invert_list_selection(self.tclass.selectionModel())

    #
    # Default criteria
    #

    def clear_default_error(self):
        self.default_range.setToolTip("Match the default type the rule.")
        self.default_range.setPalette(self.orig_palette)

    def set_default_range(self):
        try:
            self.query.default = self.default_range.text()
        except Exception as ex:
            self.default_range.setToolTip("Error: " + str(ex))
            self.default_range.setPalette(self.error_palette)

    #
    # Results runner
    #

    def run(self, button):
        # right now there is only one button.

        self.query.ruletype = ['range_transition']
        self.query.source_indirect = self.source_indirect.isChecked()
        self.query.target_indirect = self.target_indirect.isChecked()

        # start processing
        self.busy.setLabelText("Processing query...")
        self.busy.show()
        self.raw_results.clear()
        self.thread.start()

    def update_complete(self):
        # update sizes/location of result displays
        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Resizing the result table's columns; GUI may be unresponsive")
            self.busy.repaint()
            self.table_results.resizeColumnsToContents()

        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Resizing the result table's rows; GUI may be unresponsive")
            self.busy.repaint()
            self.table_results.resizeRowsToContents()

        if not self.busy.wasCanceled():
            self.busy.setLabelText(
                "Moving the raw result to top; GUI may be unresponsive")
            self.busy.repaint()
            self.raw_results.moveCursor(QTextCursor.Start)

        self.busy.reset()
Beispiel #60
0
    def __init__(self, number, parent: QWidget = None):
        super().__init__(parent)

        self._number: int = number
        self._edit_pair: StudentPair = None
        self._dates: DatePair = DatePair()

        # window settings
        self.setWindowFlag(Qt.WindowContextHelpButtonHint, False)
        self.setWindowTitle(self.tr("Creator"))
        self.setMinimumSize(640, 350)
        self.resize(800, 400)

        # general settings window
        self.group_box_general = QGroupBox(self.tr("General"))
        self.layout_general = QFormLayout(self.group_box_general)

        # title
        self.label_title = QLabel(self.tr("Title"))
        self.layout_general.setWidget(0, QFormLayout.LabelRole,
                                      self.label_title)
        self.line_edit_title = QLineEdit("")
        self.layout_general.setWidget(0, QFormLayout.FieldRole,
                                      self.line_edit_title)

        # lecturer
        self.label_lecturer = QLabel(self.tr("Lecturer"))
        self.layout_general.setWidget(1, QFormLayout.LabelRole,
                                      self.label_lecturer)
        self.line_edit_lecturer = QLineEdit("")
        self.layout_general.setWidget(1, QFormLayout.FieldRole,
                                      self.line_edit_lecturer)

        self.completer = QCompleter(LecturerPair.get_lecturers())
        self.completer.setModelSorting(QCompleter.CaseSensitivelySortedModel)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setFilterMode(Qt.MatchContains)
        self.line_edit_lecturer.setCompleter(self.completer)

        # type
        self.label_type = QLabel(self.tr("Type"))
        self.layout_general.setWidget(2, QFormLayout.LabelRole,
                                      self.label_type)
        self.combo_box_type = QComboBox()
        self.layout_general.setWidget(2, QFormLayout.FieldRole,
                                      self.combo_box_type)

        for name, attrib in TypePairAttrib.items():
            self.combo_box_type.addItem(name, attrib)

        # classes
        self.label_classes = QLabel(self.tr("Classes"))
        self.layout_general.setWidget(3, QFormLayout.LabelRole,
                                      self.label_classes)
        self.line_edit_classes = QLineEdit("")
        self.layout_general.setWidget(3, QFormLayout.FieldRole,
                                      self.line_edit_classes)

        # subgroup
        self.label_subgroup = QLabel(self.tr("Subgroup"))
        self.layout_general.setWidget(4, QFormLayout.LabelRole,
                                      self.label_subgroup)
        self.combo_box_subgroup = QComboBox()
        self.layout_general.setWidget(4, QFormLayout.FieldRole,
                                      self.combo_box_subgroup)

        for name, attrib in SubgroupPairAttrib.items():
            self.combo_box_subgroup.addItem(name, attrib)

        # time setting
        self.group_box_time = QGroupBox(self.tr("Time"))
        self.layout_time = QFormLayout(self.group_box_time)

        self.label_start = QLabel(self.tr("Start"))
        self.layout_time.setWidget(0, QFormLayout.LabelRole, self.label_start)
        self.combo_box_start = QComboBox()
        self.layout_time.setWidget(0, QFormLayout.FieldRole,
                                   self.combo_box_start)

        self.label_end = QLabel(self.tr("End"))
        self.layout_time.setWidget(1, QFormLayout.LabelRole, self.label_end)
        self.combo_box_end = QComboBox()
        self.layout_time.setWidget(1, QFormLayout.FieldRole,
                                   self.combo_box_end)

        self.combo_box_start.addItems(TimePair.time_starts())
        self.combo_box_start.setCurrentIndex(self._number)
        self.combo_box_end.addItems(TimePair.time_ends())
        self.combo_box_end.setCurrentIndex(self._number)

        # date setting
        self.group_box_date = QGroupBox(self.tr("Date"))
        self.layout_date_edit = QHBoxLayout(self.group_box_date)

        self.list_widget_date = QListWidget(self.group_box_date)
        self.layout_date_edit.addWidget(self.list_widget_date)

        self.layout_date_edit_navigate = QVBoxLayout()
        self.layout_date_edit.addLayout(self.layout_date_edit_navigate)

        self.push_button_add_date = QPushButton(self.tr("Add"))
        self.layout_date_edit_navigate.addWidget(self.push_button_add_date)

        self.push_button_edit_date = QPushButton(self.tr("Edit"))
        self.layout_date_edit_navigate.addWidget(self.push_button_edit_date)

        self.push_button_remove_date = QPushButton(self.tr("Remove"))
        self.layout_date_edit_navigate.addWidget(self.push_button_remove_date)

        self.layout_date_edit_navigate.addStretch(1)

        # navigate
        self.layout_navigate = QHBoxLayout()

        self.layout_navigate.addStretch(1)

        self.push_button_ok = QPushButton(self.tr("OK"))
        self.layout_navigate.addWidget(self.push_button_ok)

        self.push_button_cancel = QPushButton(self.tr("Cancel"))
        self.layout_navigate.addWidget(self.push_button_cancel)

        # layout settings
        self.layout_general_time = QVBoxLayout()
        self.layout_general_time.addWidget(self.group_box_general)
        self.layout_general_time.addWidget(self.group_box_time)

        self.layout_center = QHBoxLayout()
        self.layout_center.addLayout(self.layout_general_time)
        self.layout_center.addWidget(self.group_box_date)

        self.layout_main = QVBoxLayout()
        self.layout_main.addLayout(self.layout_center)
        self.layout_main.addLayout(self.layout_navigate)

        self.setLayout(self.layout_main)

        # connection
        self.combo_box_start.currentIndexChanged.connect(
            self.combo_box_start_changed)
        self.list_widget_date.itemDoubleClicked.connect(
            self.push_button_edit_date_clicked)
        self.push_button_add_date.clicked.connect(
            self.push_button_add_date_clicked)
        self.push_button_edit_date.clicked.connect(
            self.push_button_edit_date_clicked)
        self.push_button_remove_date.clicked.connect(
            self.push_button_remove_date_clicked)
        self.push_button_ok.clicked.connect(self.push_button_ok_clicked)
        self.push_button_cancel.clicked.connect(
            self.push_button_cancel_clicked)