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
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)
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])
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()
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.")
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)
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()
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)
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)
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)
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 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()
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
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)
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 __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 __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()
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 __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)
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()
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
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)
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
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
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_()
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)
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
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()
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)
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)
def creaCompleter(self, datos=[]): completer = QCompleter(datos) completer.setCaseSensitivity(Qt.CaseInsensitive) self.setCompleter(completer)
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()
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)
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')
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)
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()
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)
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)
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()
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( ["Имя", "Тип", "Класс", "Редкость", "Стоимость"])
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:])
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()
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()
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)