def __init__(self, text="Enter object label", parent=None, listItem=None): super(LabelDialog, self).__init__(parent) self.edit = QLineEdit() self.edit.setText(text) self.edit.setValidator(self.labelValidator()) self.edit.editingFinished.connect(self.postProcess) model = QStringListModel() model.setStringList(listItem) completer = QCompleter() completer.setModel(model) self.edit.setCompleter(completer) layout = QVBoxLayout() layout.addWidget(self.edit) self.buttonBox = bb = BB(BB.Ok | BB.Cancel, Qt.Horizontal, self) bb.button(BB.Ok).setIcon(newIcon('done')) bb.button(BB.Cancel).setIcon(newIcon('undo')) bb.accepted.connect(self.validate) bb.rejected.connect(self.reject) layout.addWidget(bb) if listItem is not None and len(listItem) > 0: self.listWidget = QListWidget(self) for item in listItem: self.listWidget.addItem(item) self.listWidget.itemClicked.connect(self.listItemClick) self.listWidget.itemDoubleClicked.connect(self.listItemDoubleClick) layout.addWidget(self.listWidget) self.setLayout(layout)
def getUpdatedCountryAndSignList(self): self.CountryList[:] = [] self.SignList[:] = [] self.ui.CountryListV.clear() self.ui.SignListV.clear() cursor = self.DataBaseDataMapperI.GetSignList() countryCursor =self.DataBaseDataMapperI.GetCountryList() for obj in countryCursor["Country List"]: self.CountryList.append(str(obj)) for obj in cursor["Sign List"]: self.SignList.append(str(obj)) self.ui.CountryListV.addItems(self.CountryList) self.ui.CountryListV_image.addItems(self.CountryList) self.ui.CountryListV.itemActivated.connect(self.CountryselectUpdate) self.ui.CountryListV_image.itemActivated.connect(self.CountryselectUpdate) self.ui.SignListV.addItems(self.SignList) self.ui.SignListV_image.addItems(self.SignList) self.ui.SignListV.itemActivated.connect(self.SignlistUpdate) self.ui.SignListV_image.itemActivated.connect(self.SignlistUpdate) completer = QCompleter() completerCountry=QCompleter() self.ui.SelectSignClass.setCompleter(completer) self.ui.SelectSignClass_image.setCompleter(completer) model=QStringListModel() completer.setModel(model) model.setStringList(self.SignList) self.ui.SelectCountry.setCompleter(completerCountry) self.ui.SelectCountry_image.setCompleter(completerCountry) modelCountry=QStringListModel() completerCountry.setModel(modelCountry) modelCountry.setStringList(self.CountryList)
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)
def __init__(self, widget, main_app, db, serial): Ui_RequestSignature.__init__(self) super().__init__(widget) self.widget = widget self.main_app = main_app self.setupUi(widget) self.session_storage = SessionStorage.getInstance() self.person = self.session_storage.session_info[serial]['personclient'] self.user = self.session_storage.session_info[serial]['user'] self.contacts_count = 0 self.path = None self.settings = UserSettings.getInstance() self.browseFiles.clicked.connect(self.get_document_path) self.filesWidget.set_parent(self) self.contacts_model = ContactModel(user=self.user, db=db) self.sign_list = [] self.status_widgets = {} completer = QCompleter() completer.setModel(self.contacts_model) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setFilterMode(Qt.MatchContains) self.search.setCompleter(completer) self.add_contact.clicked.connect(lambda: self.add_contact_to_list()) self.requestSignature.clicked.connect(self.request_signature) self.initialize() self.sign_pending = 0
def setCompleter(self, lineEdit): self.getHotelData() model = QStringListModel() model.setStringList(self.hotelStringList) completer = QCompleter() completer.setModel(model) lineEdit.setCompleter(completer)
def __init__(self, parent): super(DirectorySelectionWidget, self).__init__('Location of custom DSDL definitions [optional]', parent) self._dir_selection = None dir_textbox = QLineEdit(self) dir_textbox.setText(self._dir_selection) dir_text_completer = QCompleter(self) dir_text_completer.setCaseSensitivity(Qt.CaseSensitive) dir_text_completer.setModel(QDirModel(self)) dir_textbox.setCompleter(dir_text_completer) def on_edit(): self._dir_selection = str(dir_textbox.text()) dir_textbox.textChanged.connect(on_edit) dir_browser = QPushButton('Browse', self) def on_browse(): self._dir_selection = str( QFileDialog.getExistingDirectory(self, 'Select Directory')) dir_textbox.setText(self._dir_selection) dir_browser.clicked.connect(on_browse) layout = QHBoxLayout(self) layout.addWidget(dir_textbox) layout.addWidget(dir_browser) self.setLayout(layout)
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 retranslateUi(self, Dialog): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.groupBox.setTitle(_translate("Dialog", "이벤트 기간")) self.groupBox_2.setTitle(_translate("Dialog", "당첨자 조건")) self.checkBox_Cherry.setText(_translate("Dialog", "체리피커 필터링")) self.checkBox_Cherry.setChecked(True) self.checkBox_URL.setText(_translate("Dialog", "URL 첨부")) self.checkBox_URL.setChecked(True) self.checkBox_Keyword.setText(_translate("Dialog", "키워드 포함")) self.checkBox_Keyword.setChecked(True) self.keywordLabel1.setText(_translate("Dialog", "키워드 1")) self.keywordLabel2.setText(_translate("Dialog", "키워드 2")) self.keywordLabel3.setText(_translate("Dialog", "키워드 3")) self.keywordLabel4.setText(_translate("Dialog", "키워드 4")) self.endTime.dateTimeChanged.connect(self.onOverStartTime) #자동완성기능(추후 제작예정) prizeModel = QStringListModel() prizeModel.setStringList([]) completer = QCompleter() completer.setModel(prizeModel) #self.prizeEdit1.setCompleter(completer) self.tabWidget.setTabText(self.tabWidget.indexOf(self.eventTab), _translate("Dialog", "이벤트 설정")) self.prizeLabel.setText(_translate("Dialog", "상품 종류")) # 콤보박스에 이벤트슬롯 추가 self.prizeComboBox.currentTextChanged.connect(self.onSelected) self.tabWidget.setTabText(self.tabWidget.indexOf(self.prizeTab), _translate("Dialog", "경품 설정"))
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
class ExtendedComboBox(QComboBox): def __init__(self): QComboBox.__init__(self) self.setFocusPolicy(Qt.StrongFocus) self.setEditable(True) self.filter_model = QSortFilterProxyModel(self) self.filter_model.setFilterCaseSensitivity(Qt.CaseInsensitive) self.filter_model.setSourceModel(self.model()) self.completer = QCompleter(self.filter_model, self) self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.setCompleter(self.completer) self.lineEdit().textEdited.connect( self.filter_model.setFilterFixedString) self.completer.activated.connect(self.on_completer_activated) def on_completer_activated(self, text): if text: index = self.findText(text) self.setCurrentIndex(index) self.activated[str].emit(self.itemText(index)) def setModel(self, model): self.setModel(model) self.filter_model.setSourceModel(model) self.completer.setModel(self.filter_model) def setModelColumn(self, column): self.completer.setCompletionColumn(column) self.filter_model.setFilterKeyColumn(column) self.setModelColumn(column)
def __init__(self, root_widget=None): self.east = 180 self.west = -180 self.north = 90 self.south = -90 self.valid = True super(self.__class__, self).__init__() self.schema = 'bdp' self.root_widget = root_widget self.after_load = False self.in_xml_load = False self.has_rect = True completer = QCompleter() self.ui.fgdc_descgeog.setCompleter(completer) model = QStringListModel() completer.setModel(model) completer.setCaseSensitivity(0) fname = utils.get_resource_path("spatial/BNDCoords.csv") self.bnds_df = pd.read_csv(fname) model.setStringList(self.bnds_df['Name'])
def __init__(self, new_project=True, parent=None): super().__init__(parent) self.ui = Ui_ProjectDialog() self.ui.setupUi(self) self.sample_rate = self.ui.spinBoxSampleRate.value() self.freq = self.ui.spinBoxFreq.value() self.path = self.ui.lineEdit_Path.text() self.new_project = new_project self.commited = False self.setModal(True) completer = QCompleter() completer.setModel(QDirModel(completer)) self.ui.lineEdit_Path.setCompleter(completer) if not self.new_project: self.ui.btnSelectPath.hide() self.ui.lineEdit_Path.setDisabled(True) self.ui.lblNewPath.hide() self.create_connects() self.ui.lineEdit_Path.setText( os.path.realpath(os.path.join(os.curdir, "new"))) self.on_path_edited()
def fuzzy_search_action(self): """Open a dialog for quick access to actions with fuzzy search.""" focussed_widget = QApplication.focusWidget() self.fuzzy_search_ui.ui.fuzzy_search_field.setFocus() def get_data(model): plugins = [x[1].name for x in self.plugins.available_plugins] for p in self.plugins.codecs + \ self.plugins.compressions +\ self.plugins.assemblies: plugins.append('-' + p[1].name) plugins.extend(['-' + x for x in p[1].aliases]) for p in self.plugins.available_plugins: plugins.extend(p[1].aliases) model.setStringList(plugins) completer = QCompleter() self.fuzzy_search_ui.ui.fuzzy_search_field.setCompleter(completer) model = QStringListModel() completer.setModel(model) get_data(model) if self.fuzzy_search_ui.exec_() == 0: return search_data = self.fuzzy_search_ui.ui.fuzzy_search_field.text() parent_encoder = self.get_parent_encoder(focussed_widget) if parent_encoder: parent_encoder.action_fuzzy(search_data) else: LOGGER.error('Unable to find parent encoder for ' + str(focussed_widget))
def __init__(self): super(Ui, self).__init__() # https://github.com/mherrmann/fbs/issues/32 uic.loadUi(appctxt.get_resource('main.ui'), self) self.button = self.findChild(QtWidgets.QPushButton, 'pushButton') self.button.clicked.connect(self.playButtonPressed) self.input = self.findChild(QtWidgets.QLineEdit, 'lineEdit') self.pictureLabel = self.findChild(QtWidgets.QLabel, 'label') completer = QCompleter() self.input.setCompleter(completer) model = QStringListModel() completer.setModel(model) get_url_data(model) # timer 设置 self.timer = VideoTimer() self.timer.timeSignal.signal[str].connect(self.show_video_images) # self.save_mp4_process = None self.process1 = None self.width, self.height = None, None self.url_base = None self.play = False self.draw_count = 0 self.show()
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 HardwareWalletWordDlg(QDialog, ui_hw_word_dlg.Ui_HardwareWalletWordDlg, WndUtils): def __init__(self, message, wordlist): QDialog.__init__(self) WndUtils.__init__(self, app_config=None) ui_hw_word_dlg.Ui_HardwareWalletWordDlg.__init__(self) self.wordlist = wordlist self.message = message self.word = '' self.setupUi() def setupUi(self): ui_hw_word_dlg.Ui_HardwareWalletWordDlg.setupUi(self, self) self.setWindowTitle('') self.lblWord.setText(self.message) self.setWindowTitle('Get word') model = QStringListModel() model.setStringList(self.wordlist) self.completer = QCompleter() self.completer.setModel(model) self.edtWord.setCompleter(self.completer) self.layout().setSizeConstraint(QLayout.SetFixedSize) @pyqtSlot(bool) def on_btnEnter_clicked(self): text = self.edtWord.text() if not text: WndUtils.errorMsg('Word cannot be empty.') elif text not in self.wordlist: WndUtils.errorMsg('Word is not in the allowed wordlist.') else: self.accept() def get_word(self): return self.edtWord.text()
def connectWidgets(self): self.newfig_checkBox.setHidden(True) self.colorcode_checkBox.setHidden(True) completer = QCompleter() self.newfig_lineEdit.setCompleter(completer) model = QStringListModel() completer.setModel(model) self.get_data(model) choices2 = ['None'] datakey_choices = self.datakeys for choice in datakey_choices: choices2.append(choice) datakey_choices = choices2 fig_choices = self.figname fig_choices2 = ['New Figure'] for choice in fig_choices: fig_choices2.append(choice) fig_choices = fig_choices2 none_choice = ['None'] self.setComboBox(self.chooseDataComboBox, datakey_choices) self.setComboBox(self.figname_comboBox, fig_choices) self.setComboBox(self.chooseYVariableComboBox, self.get_choices()) self.setComboBox(self.chooseXVariableComboBox, self.get_choices()) self.setComboBox(self.comboBoxcolorvar, self.get_choices()) self.plotFilenamePushButton.clicked.connect( self.plotFilenamePushButton_clicked) self.figname_comboBox.activated[int].connect( lambda: self.newfig_check()) self.newfig_checkBox.stateChanged.connect(lambda: self.fig_options()) self.chooseDataComboBox.activated[int].connect( lambda: self.changeComboListVars(self.chooseXVariableComboBox, self.get_choices())) self.chooseDataComboBox.activated[int].connect( lambda: self.changeComboListVars(self.chooseYVariableComboBox, self.get_choices())) self.chooseDataComboBox.activated[int].connect( lambda: self.changeComboListVars(self.comboBoxcolorvar, self.get_choices())) self.chooseDataComboBox.activated[int].connect(lambda: self.get_minmax( self.xMinDoubleSpinBox, self.xMaxDoubleSpinBox, self.chooseXVariableComboBox.currentText())) self.chooseDataComboBox.activated[int].connect(lambda: self.get_minmax( self.yMinDoubleSpinBox, self.yMaxDoubleSpinBox, self.chooseYVariableComboBox.currentText())) self.chooseXVariableComboBox.activated[int].connect( lambda: self.get_minmax( self.xMinDoubleSpinBox, self.xMaxDoubleSpinBox, self.chooseXVariableComboBox.currentText())) self.chooseYVariableComboBox.activated[int].connect( lambda: self.get_minmax( self.yMinDoubleSpinBox, self.yMaxDoubleSpinBox, self.chooseYVariableComboBox.currentText())) self.comboBoxcolorvar.activated[int].connect(self.color_check) self.colorcode_checkBox.stateChanged.connect(self.disable_colors) self.chooseXVariableComboBox.activated[int].connect(self.set_xTitle) self.chooseYVariableComboBox.activated[int].connect(self.set_yTitle)
def _initAutoCompleter(self): completer = QCompleter() completer.setModel(self.autoCompleteModel) completer.setCaseSensitivity(Qt.CaseInsensitive) self.autoCompleteModel.setStringList( ApplicationGlobals.getInstance().causesOfDeath) self.causeOfDeathTextBox.setCompleter(completer)
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])
def __init__(self, new_project=True, project_manager: ProjectManager = None, parent=None): super().__init__(parent) if not new_project: assert project_manager is not None self.ui = Ui_ProjectDialog() self.ui.setupUi(self) self.setWindowFlags(Qt.Window) if new_project: self.participant_table_model = ParticipantTableModel([]) else: self.participant_table_model = ParticipantTableModel(project_manager.participants) self.ui.spinBoxSampleRate.setValue(project_manager.device_conf["sample_rate"]) self.ui.spinBoxFreq.setValue(project_manager.device_conf["frequency"]) self.ui.spinBoxBandwidth.setValue(project_manager.device_conf["bandwidth"]) self.ui.spinBoxGain.setValue(project_manager.device_conf.get("gain", config.DEFAULT_GAIN)) self.ui.txtEdDescription.setPlainText(project_manager.description) self.ui.lineEdit_Path.setText(project_manager.project_path) self.ui.lineEditBroadcastAddress.setText(project_manager.broadcast_address_hex) self.ui.btnSelectPath.hide() self.ui.lineEdit_Path.setDisabled(True) self.setWindowTitle("Edit project settings") self.ui.lNewProject.setText("Edit project") self.ui.tblParticipants.setModel(self.participant_table_model) self.participant_table_model.update() self.ui.lineEditBroadcastAddress.setValidator(QRegExpValidator(QRegExp("([a-fA-F ]|[0-9]){,}"))) self.sample_rate = self.ui.spinBoxSampleRate.value() self.freq = self.ui.spinBoxFreq.value() self.bandwidth = self.ui.spinBoxBandwidth.value() self.gain = self.ui.spinBoxGain.value() self.description = self.ui.txtEdDescription.toPlainText() self.broadcast_address_hex = self.ui.lineEditBroadcastAddress.text() self.path = self.ui.lineEdit_Path.text() self.new_project = new_project self.committed = False self.setModal(True) completer = QCompleter() completer.setModel(QDirModel(completer)) self.ui.lineEdit_Path.setCompleter(completer) self.create_connects() # add two participants if self.participant_table_model.rowCount() == 0 and new_project: self.ui.btnAddParticipant.click() self.ui.btnAddParticipant.click() if new_project: self.ui.lineEdit_Path.setText(os.path.realpath(os.path.join(os.curdir, "new"))) self.on_line_edit_path_text_edited() self.restoreGeometry(settings.read("{}/geometry".format(self.__class__.__name__), type=bytes))
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.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()
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()
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])
def initiate_completer(codes): edit = thirdPage.lineEditCode completer = QCompleter() edit.setCompleter(completer) model = QStringListModel() model.setStringList(codes) completer.setModel(model) edit.show()
def setCompleter(self, lineEdit): self.getHotelData() model = QStringListModel() model.setStringList(self.hotelStringList) completer = QCompleter() completer.setModel(model) completer.setFilterMode(QtCore.Qt.MatchContains) lineEdit.setCompleter(completer)
def connectWidgets(self): color_list = ["Red", "Green", "Blue", "Cyan", "Yellow", "Magenta", "Black"] line_list = ["No Line", "Line", "Dashed Line", "Dotted Line"] marker_list = ["Circles", "Squares", "Diamonds", "Triangle Up", "Triangle Down", "Triangle Left", "Triangle Right", "None"] completer = QCompleter() self.chooseXVariableComboBox.setMaximumWidth(200) self.chooseYVariableComboBox.setMaximumWidth(200) self.changeComboListVars(self.chooseXVariableComboBox, self.get_choices()) self.figureNameLineEdit.setCompleter(completer) model = QStringListModel() completer.setModel(model) self.get_data(model) self.setComboBox(self.chooseDataComboBox, self.datakeys) self.changeComboListVars(self.chooseYVariableComboBox, self.get_choices()) self.setComboBox(self.colorComboBox, color_list) self.setComboBox(self.lineComboBox, line_list) self.setComboBox(self.markerComboBox, marker_list) self.alphaDoubleSpinBox.setValue(0.25) self.alphaDoubleSpinBox.setSingleStep(0.25) self.alphaDoubleSpinBox.setMaximum(1) self.xMinDoubleSpinBox.setMaximum(110) self.xMaxDoubleSpinBox.setMaximum(110) self.yMinDoubleSpinBox.setMaximum(110) self.yMaxDoubleSpinBox.setMaximum(110) self.plotFilenamePushButton.clicked.connect(self.plotFilenamePushButton_clicked) self.chooseDataComboBox.activated[int].connect( lambda: self.changeComboListVars(self.chooseXVariableComboBox, self.get_choices())) self.chooseDataComboBox.activated[int].connect( lambda: self.changeComboListVars(self.chooseYVariableComboBox, self.get_choices())) self.chooseDataComboBox.activated[int].connect( lambda: self.get_minmax(self.xMinDoubleSpinBox, self.xMaxDoubleSpinBox, self.chooseXVariableComboBox.currentText())) self.chooseDataComboBox.activated[int].connect( lambda: self.get_minmax(self.yMinDoubleSpinBox, self.yMaxDoubleSpinBox, self.chooseYVariableComboBox.currentText())) self.chooseXVariableComboBox.activated[int].connect( lambda: self.get_minmax(self.xMinDoubleSpinBox, self.xMaxDoubleSpinBox, self.chooseXVariableComboBox.currentText())) self.chooseYVariableComboBox.activated[int].connect( lambda: self.get_minmax(self.yMinDoubleSpinBox, self.yMaxDoubleSpinBox, self.chooseYVariableComboBox.currentText()))
def __init__(self, parent): super(SearchBarComboBox, self).__init__(parent) self.setFont(get_monospace_font()) self.setToolTip('Enter the search pattern here') combo_completer = QCompleter() combo_completer.setCaseSensitivity(Qt.CaseSensitive) combo_completer.setModel(self.model()) self.setCompleter(combo_completer)
def home(self): #the names of the column headers self.statLabels = [ 'Name', 'BA', 'HR', 'RBI', 'R', 'OBP', '2B', '3B', 'SB', 'AB', 'PA' ] self.currentRow = -1 #index to keep track of current row self.players = dict() #dictionary to hold stats #progress bar self.progress = QtWidgets.QProgressBar(self) self.progress.setGeometry(10, 35, 250, 20) #action for progress bar (download data) self.btn = QtWidgets.QPushButton("Download Data", self) self.btn.move(10, 60) self.btn.clicked.connect(self.getData) #text input line to tye name of player self.le = QLineEdit(self) self.le.setPlaceholderText("Enter Hitter Name") self.le.move(10, 100) #autocomplete for text line completer = QCompleter() completer.setCaseSensitivity(Qt.CaseInsensitive) self.le.setCompleter(completer) self.model = QStringListModel() completer.setModel(self.model) #some buttons #add player button self.btn2 = QPushButton('Add Player', self) self.btn2.move(10, 140) self.btn2.clicked.connect(self.addPlayer) #remove player button self.rembtn = QPushButton('Remove Prev', self) self.rembtn.move(110, 140) self.rembtn.clicked.connect(self.removeLastRow) #clear table self.clearbtn = QPushButton('Clear Table', self) self.clearbtn.move(210, 140) self.clearbtn.clicked.connect(self.clearTable) #mquit application quitbtn = QtWidgets.QPushButton("Close App", self) quitbtn.clicked.connect(self.close_application) quitbtn.move(310, 140) #build table self.tableWidget = QTableWidget(self) # set row/column counts self.tableWidget.setRowCount(10) self.tableWidget.setColumnCount(11) self.tableWidget.move(10, 180) self.tableWidget.resize(1400, 1000) #set name of headers self.tableWidget.setHorizontalHeaderLabels(self.statLabels) self.show()
def __init__(self, freq, samp_rate, bw, gain, device, noise, center, bit_length, tolerance, modulation_type_index, parent=None, testing_mode=False): self.is_rx = True super().__init__(freq, samp_rate, bw, gain, device, parent=parent, testing_mode=testing_mode) self.ui.stackedWidget.setCurrentIndex(2) self.hide_send_ui_items() self.hide_receive_ui_items() self.ui.sliderYscale.hide() self.ui.label_y_scale.hide() self.ui.spinbox_sniff_Noise.setValue(noise) self.ui.spinbox_sniff_Center.setValue(center) self.ui.spinbox_sniff_BitLen.setValue(bit_length) self.ui.spinbox_sniff_ErrorTolerance.setValue(tolerance) self.ui.combox_sniff_Modulation.setCurrentIndex(modulation_type_index) device = self.ui.cbDevice.currentText() self.sniffer = ProtocolSniffer(bit_length, center, noise, tolerance, modulation_type_index, samp_rate, freq, gain, bw, device, testing_mode=testing_mode) self.set_sniff_ui_items_visible(True) self.set_device_ui_items_visible( device != NetworkSDRInterfacePlugin.NETWORK_SDR_NAME) # Auto Complete like a Boss completer = QCompleter() completer.setModel(QDirModel(completer)) self.ui.lineEdit_sniff_OutputFile.setCompleter(completer) self.create_connects()
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)
class ExtendedComboBox(QComboBox): """An enhanced version of PyQt5's QComboBox widget that allows for search and filtering of the greater list. Implemented by armonge on StackOverflow, adapted for PyQt5 by Tamas Haver on StackOverflow. The Stackoverflow post can be found here: https://stackoverflow.com/questions/4827207/how-do-i-filter-the-pyqt-qcombobox-items-based-on-the-text-input """ def __init__(self, parent=None): super(ExtendedComboBox, self).__init__(parent) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.setEditable(True) # add a filter model to filter matching items self.pFilterModel = QtCore.QSortFilterProxyModel(self) self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) self.pFilterModel.setSourceModel(self.model()) # add a completer, which uses the filter model self.completer = QCompleter(self.pFilterModel, self) # always show all (filtered) completions self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) self.setCompleter(self.completer) # connect signals self.lineEdit().textEdited.connect( self.pFilterModel.setFilterFixedString) self.completer.activated.connect(self.on_completer_activated) def on_completer_activated(self, text): """On selection of an item from the completer, select the corresponding item from combobox. """ if text: index = self.findText(text) self.setCurrentIndex(index) self.activated[str].emit(self.itemText(index)) def setModel(self, model): """On model change, update the models of the filter and completer as well. """ super(ExtendedComboBox, self).setModel(model) self.pFilterModel.setSourceModel(model) self.completer.setModel(self.pFilterModel) def setModelColumn(self, column): """On model column change, update the model column of the filter and completer as well. """ self.completer.setCompletionColumn(column) self.pFilterModel.setFilterKeyColumn(column) super(ExtendedComboBox, self).setModelColumn(column)
def completerLine(self, lineEdit, layer, field): #Data la lista degli identificatori permette l'autocompletamento dell'input utente strList = QueryLayer().getFeaturesList(field, layer) completer = QCompleter() completer.setFilterMode(Qt.MatchContains) completer.setCaseSensitivity(0) lineEdit.setCompleter(completer) model = QStringListModel() model.setStringList(strList) completer.setModel(model)
def createEditor(self, parent, option, index): """Return the widget used to edit the item specified by index.""" completer = QCompleter(self) string_list_model = QStringListModel(get_last_unique_task_names(), completer) completer.setModel(string_list_model) editor = LineEdit(parent) editor.set_completer(completer) editor.return_pressed.connect(self.__commit_and_close_editor) return editor
def __init__(self, *args, **kwargs): super(DirLineEdit, self).__init__(*args, **kwargs) completer = QCompleter() completer.setCompletionMode(QCompleter.PopupCompletion) dirfilter = QDir.AllEntries | QDir.NoDotAndDotDot | QDir.Hidden sortflags = QDir.DirsFirst | QDir.IgnoreCase dirmodel = QDirModel(['*'], dirfilter, sortflags, completer) completer.setModel(dirmodel) self.setCompleter(completer)
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 __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, 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()
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, 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 __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)
class CLIWidget(QWidget): 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 _do_execute(self): self._response_box.clear() command = self._command_line.currentText() if not command.strip(): return self._command_line.add_current_text_to_history() def callback(lines): self.setEnabled(True) if lines is None: self.window().show_message('Command response timed out') self._response_box.setPlainText('<RESPONSE TIMED OUT>') else: self.window().show_message('Command response received') self._response_box.setPlainText(lines) self.setEnabled(False) self._cli_iface.execute_raw_command(command, callback)
class TERuleQueryTab(SEToolsWidget, QScrollArea): """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("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.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.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.log.error("Source type/attribute error: {0}".format(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.log.error("Target type/attribute error: {0}".format(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 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.xperms.setToolTip("Match the extended permissions of the rule. Comma-separated " "permissions or ranges of permissions.") self.xperms.setPalette(self.orig_palette) 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.xperms.setToolTip("Error: " + str(ex)) self.xperms.setPalette(self.error_palette) # # Default criteria # def clear_default_error(self): self.default_type.setToolTip("Match the default type the rule.") self.default_type.setPalette(self.orig_palette) 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.default_type.setToolTip("Error: " + str(ex)) self.default_type.setPalette(self.error_palette) 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.""" 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()
class MainWindow(QMainWindow): """Main window class.""" def __init__(self, parent=None): """Init class.""" 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) # group 5 miscelaneous stuff 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) # option to show or hide some widgets on the gui 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) # buttons from bottom to close or proceed 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 for all groups of widgets 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): """Check that the paths are valid.""" 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): """Generate a build command.""" 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): """Run the main method and run Nuitka.""" 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): """Finished sucessfuly.""" log.debug("Finished.") self.showNormal() def _read_output(self): """Read and return output.""" return str(self.process.readAllStandardOutput()).strip() def _read_errors(self): """Read and return errors.""" log.debug(self.process.readAllStandardError()) return str(self.process.readAllStandardError()).strip() def _process_failed(self): """Read and return errors.""" 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): """Switch between simple and full UX.""" 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): """Open QSS from filename,if no QSS return None,if no filename ask.""" 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): """Center the Window on the Current Screen,with Multi-Monitor support. >>> MainWindow().center() True """ 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): """Center the Window on the Current Mouse position. >>> MainWindow().move_to_mouse_position() True """ window_geometry = self.frameGeometry() window_geometry.moveCenter(QApplication.desktop().cursor().pos()) return bool(not self.move(window_geometry.topLeft())) def closeEvent(self, event): """Ask to Quit.""" 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()
class GeneralExecution(QWidget): """General Execution widget class""" def __init__(self, parent): super(GeneralExecution, self).__init__() self._preferences = parent vbox = QVBoxLayout(self) groupExecution = QGroupBox(translations.TR_WORKSPACE_PROJECTS) grid = QVBoxLayout(groupExecution) #Python Path hPath = QHBoxLayout() self._txtPythonPath = QLineEdit() self._btnPythonPath = 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._txtPythonPath.setCompleter(self.completer) hPath.addWidget(QLabel(translations.TR_SELECT_PYTHON_EXEC)) hPath.addWidget(self._txtPythonPath) hPath.addWidget(self._btnPythonPath) grid.addLayout(hPath) #Python Miscellaneous Execution options self.check_B = QCheckBox(translations.TR_SELECT_EXEC_OPTION_B) self.check_d = QCheckBox(translations.TR_SELECT_EXEC_OPTION_D) self.check_E = QCheckBox(translations.TR_SELECT_EXEC_OPTION_E) self.check_O = QCheckBox(translations.TR_SELECT_EXEC_OPTION_O) self.check_OO = QCheckBox(translations.TR_SELECT_EXEC_OPTION_OO) self.check_Q = QCheckBox(translations.TR_SELECT_EXEC_OPTION_Q) self.comboDivision = QComboBox() self.comboDivision.addItems(['old', 'new', 'warn', 'warnall']) self.check_s = QCheckBox(translations.TR_SELECT_EXEC_OPTION_s) self.check_S = QCheckBox(translations.TR_SELECT_EXEC_OPTION_S) self.check_t = QCheckBox(translations.TR_SELECT_EXEC_OPTION_T) self.check_tt = QCheckBox(translations.TR_SELECT_EXEC_OPTION_TT) self.check_v = QCheckBox(translations.TR_SELECT_EXEC_OPTION_V) self.check_W = QCheckBox(translations.TR_SELECT_EXEC_OPTION_W) self.comboWarning = QComboBox() self.comboWarning.addItems( ['default', 'ignore', 'all', 'module', 'once', 'error']) self.check_x = QCheckBox(translations.TR_SELECT_EXEC_OPTION_X) self.check_3 = QCheckBox(translations.TR_SELECT_EXEC_OPTION_3) grid.addWidget(self.check_B) grid.addWidget(self.check_d) grid.addWidget(self.check_E) grid.addWidget(self.check_O) grid.addWidget(self.check_OO) hDiv = QHBoxLayout() hDiv.addWidget(self.check_Q) hDiv.addWidget(self.comboDivision) grid.addLayout(hDiv) grid.addWidget(self.check_s) grid.addWidget(self.check_S) grid.addWidget(self.check_t) grid.addWidget(self.check_tt) grid.addWidget(self.check_v) hWarn = QHBoxLayout() hWarn.addWidget(self.check_W) hWarn.addWidget(self.comboWarning) grid.addLayout(hWarn) grid.addWidget(self.check_x) grid.addWidget(self.check_3) #Settings self._txtPythonPath.setText(settings.PYTHON_EXEC) options = settings.EXECUTION_OPTIONS.split() if '-B' in options: self.check_B.setChecked(True) if '-d' in options: self.check_d.setChecked(True) if '-E' in options: self.check_E.setChecked(True) if '-O' in options: self.check_O.setChecked(True) if '-OO' in options: self.check_OO.setChecked(True) if settings.EXECUTION_OPTIONS.find('-Q') > -1: self.check_Q.setChecked(True) index = settings.EXECUTION_OPTIONS.find('-Q') opt = settings.EXECUTION_OPTIONS[index + 2:].split(' ', 1)[0] index = self.comboDivision.findText(opt) self.comboDivision.setCurrentIndex(index) if '-s' in options: self.check_s.setChecked(True) if '-S' in options: self.check_S.setChecked(True) if '-t' in options: self.check_t.setChecked(True) if '-tt' in options: self.check_tt.setChecked(True) if '-v' in options: self.check_v.setChecked(True) if settings.EXECUTION_OPTIONS.find('-W') > -1: self.check_W.setChecked(True) index = settings.EXECUTION_OPTIONS.find('-W') opt = settings.EXECUTION_OPTIONS[index + 2:].split(' ', 1)[0] index = self.comboWarning.findText(opt) self.comboWarning.setCurrentIndex(index) if '-x' in options: self.check_x.setChecked(True) if '-3' in options: self.check_3.setChecked(True) vbox.addWidget(groupExecution) #Signals self._btnPythonPath.clicked['bool'].connect(self._load_python_path) self._preferences.savePreferences.connect(self.save) def _load_python_path(self): """Ask the user for a Python Path""" path = QFileDialog.getOpenFileName(self, translations.TR_SELECT_SELECT_PYTHON_EXEC) if path: self._txtPythonPath.setText(path) def save(self): """Save all the Execution Preferences""" qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('execution') qsettings.setValue('pythonPath', self._txtPythonPath.text()) settings.PYTHON_PATH = self._txtPythonPath.text() options = '' if self.check_B.isChecked(): options += ' -B' if self.check_d.isChecked(): options += ' -d' if self.check_E.isChecked(): options += ' -E' if self.check_O.isChecked(): options += ' -O' if self.check_OO.isChecked(): options += ' -OO' if self.check_Q.isChecked(): options += ' -Q' + self.comboDivision.currentText() if self.check_s.isChecked(): options += ' -s' if self.check_S.isChecked(): options += ' -S' if self.check_t.isChecked(): options += ' -t' if self.check_tt.isChecked(): options += ' -tt' if self.check_v.isChecked(): options += ' -v' if self.check_W.isChecked(): options += ' -W' + self.comboWarning.currentText() if self.check_x.isChecked(): options += ' -x' if self.check_3.isChecked(): options += ' -3' settings.EXECUTION_OPTIONS = options qsettings.setValue('executionOptions', options) qsettings.endGroup() qsettings.endGroup()
class InitialSIDQueryTab(SEToolsWidget, QScrollArea): """An initial SID query.""" def __init__(self, parent, policy, perm_map): super(InitialSIDQueryTab, self).__init__(parent) self.log = logging.getLogger(__name__) self.policy = policy self.query = InitialSIDQuery(policy) self.setupUi() def __del__(self): self.thread.quit() self.thread.wait(5000) logging.getLogger("setools.initsidquery").removeHandler(self.handler) def setupUi(self): self.load_ui("initsidquery.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.orig_palette = self.type_.palette() self.error_palette = self.type_.palette() self.error_palette.setColor(QPalette.Base, Qt.red) self.clear_name_error() self.clear_user_error() self.clear_type_error() self.clear_role_error() self.clear_range_error() # set up results self.table_results_model = InitialSIDTableModel(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.initsidquery").addHandler(self.handler) # Ensure settings are consistent with the initial .ui state self.set_name_regex(self.name_regex.isChecked()) 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.name.textEdited.connect(self.clear_name_error) self.name.editingFinished.connect(self.set_name) self.name_regex.toggled.connect(self.set_name_regex) 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) # # Name criteria # def clear_name_error(self): self.name.setToolTip("Match the name.") self.name.setPalette(self.orig_palette) def set_name(self): try: self.query.name = self.name.text() except Exception as ex: self.log.error("Name error: {0}".format(ex)) self.name.setToolTip("Error: " + str(ex)) self.name.setPalette(self.error_palette) def set_name_regex(self, state): self.log.debug("Setting name_regex {0}".format(state)) self.query.name_regex = state self.clear_name_error() self.set_name() # # User criteria # def clear_user_error(self): self.user.setToolTip("Match the user of the context.") self.user.setPalette(self.orig_palette) 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.user.setToolTip("Error: " + str(ex)) self.user.setPalette(self.error_palette) 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.role.setToolTip("Match the role of the context.") self.role.setPalette(self.orig_palette) 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.role.setToolTip("Error: " + str(ex)) self.role.setPalette(self.error_palette) 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.type_.setToolTip("Match the type of the context.") self.type_.setPalette(self.orig_palette) 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.type_.setToolTip("Error: " + str(ex)) self.type_.setPalette(self.error_palette) 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.range_.setToolTip("Match the range of the context.") self.range_.setPalette(self.orig_palette) def set_range(self): try: self.query.range_ = self.range_.text() except Exception as ex: self.log.info("Context range error: " + str(ex)) self.range_.setToolTip("Error: " + str(ex)) self.range_.setPalette(self.error_palette) # # Results runner # def run(self, button): # right now there is only one button. 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} initial SID statment(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 __init__(self, new_project=True, project_manager: ProjectManager = None, parent=None): super().__init__(parent) if not new_project: assert project_manager is not None self.ui = Ui_ProjectDialog() self.ui.setupUi(self) self.setWindowFlags(Qt.Window) if new_project: self.participant_table_model = ParticipantTableModel([]) else: self.participant_table_model = ParticipantTableModel(project_manager.participants) self.ui.spinBoxSampleRate.setValue(project_manager.device_conf["sample_rate"]) self.ui.spinBoxFreq.setValue(project_manager.device_conf["frequency"]) self.ui.spinBoxBandwidth.setValue(project_manager.device_conf["bandwidth"]) self.ui.spinBoxGain.setValue(project_manager.device_conf.get("gain", config.DEFAULT_GAIN)) self.ui.txtEdDescription.setPlainText(project_manager.description) self.ui.lineEdit_Path.setText(project_manager.project_path) self.ui.lineEditBroadcastAddress.setText(project_manager.broadcast_address_hex) self.ui.btnSelectPath.hide() self.ui.lineEdit_Path.setDisabled(True) self.setWindowTitle("Edit project settings") self.ui.lNewProject.setText("Edit project") self.ui.tblParticipants.setModel(self.participant_table_model) self.participant_table_model.update() self.ui.lineEditBroadcastAddress.setValidator(QRegExpValidator(QRegExp("([a-fA-F ]|[0-9]){,}"))) self.sample_rate = self.ui.spinBoxSampleRate.value() self.freq = self.ui.spinBoxFreq.value() self.bandwidth = self.ui.spinBoxBandwidth.value() self.gain = self.ui.spinBoxGain.value() self.description = self.ui.txtEdDescription.toPlainText() self.broadcast_address_hex = self.ui.lineEditBroadcastAddress.text() self.path = self.ui.lineEdit_Path.text() self.new_project = new_project self.committed = False self.setModal(True) completer = QCompleter() completer.setModel(QDirModel(completer)) self.ui.lineEdit_Path.setCompleter(completer) self.create_connects() # add two participants if self.participant_table_model.rowCount() == 0 and new_project: self.ui.btnAddParticipant.click() self.ui.btnAddParticipant.click() if new_project: self.ui.lineEdit_Path.setText(os.path.realpath(os.path.join(os.curdir, "new"))) self.on_line_edit_path_text_edited() try: self.restoreGeometry(constants.SETTINGS.value("{}/geometry".format(self.__class__.__name__))) except TypeError: pass
class ConstraintQueryTab(AnalysisTab): """A constraint query.""" def __init__(self, parent, policy, perm_map): super(ConstraintQueryTab, self).__init__(parent) self.log = logging.getLogger(__name__) self.policy = policy self.query = ConstraintQuery(policy) self.setupUi() def __del__(self): self.thread.quit() self.thread.wait(5000) logging.getLogger("setools.constraintquery").removeHandler(self.handler) def setupUi(self): self.load_ui("apol/constraintquery.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) # 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) # setup indications of errors 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_user_error() self.clear_type_error() self.clear_role_error() # set up results self.table_results_model = ConstraintTableModel(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.constraintquery").addHandler(self.handler) # Ensure settings are consistent with the initial .ui state self.set_user_regex(self.user_regex.isChecked()) self.set_role_regex(self.role_regex.isChecked()) self.set_type_regex(self.type_regex.isChecked()) self.criteria_frame.setHidden(not self.criteria_expander.isChecked()) self.notes.setHidden(not self.notes_expander.isChecked()) # MLS constraints available only if policy is MLS if not self.policy.mls: self.mlsconstrain.setEnabled(False) self.mlsvalidatetrans.setEnabled(False) self.mlsconstrain.setToolTip("MLS is disabled in this policy.") self.mlsvalidatetrans.setToolTip("MLS is disabled in this policy.") # 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.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.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) # # Ruletype criteria # def _set_ruletypes(self, value): self.constrain.setChecked(value) self.validatetrans.setChecked(value) if self.policy.mls: self.mlsconstrain.setChecked(value) self.mlsvalidatetrans.setChecked(value) def set_all_ruletypes(self): self._set_ruletypes(True) def clear_all_ruletypes(self): self._set_ruletypes(False) # # 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()) # # User criteria # def clear_user_error(self): self.clear_criteria_error(self.user, "Match constraints that have a user in the expression.") def set_user(self): try: self.query.user = self.user.text() except Exception as ex: self.log.error("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 constraints that have a role in the expression.") def set_role(self): try: self.query.role = self.role.text() except Exception as ex: self.log.error("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 constraints that have a type in the expression.") def set_type(self): try: self.query.type_ = self.type_.text() except Exception as ex: self.log.error("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() # # 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", "constrain", "mlsconstrain", "validatetrans", "mlsvalidatetrans", "user_regex", "role_regex", "type_regex", "perms_subset"]) save_lineedits(self, settings, ["user", "role", "type_"]) save_listviews(self, settings, ["tclass", "perms"]) save_textedits(self, settings, ["notes"]) return settings def load(self, settings): load_checkboxes(self, settings, ["criteria_expander", "notes_expander", "constrain", "mlsconstrain", "validatetrans", "mlsvalidatetrans", "user_regex", "role_regex", "type_regex", "perms_subset"]) load_lineedits(self, settings, ["user", "role", "type_"]) load_listviews(self, settings, ["tclass", "perms"]) load_textedits(self, settings, ["notes"]) # # Results runner # def run(self, button): # right now there is only one button. rule_types = [] for mode in [self.constrain, self.mlsconstrain, self.validatetrans, self.mlsvalidatetrans]: if mode.isChecked(): rule_types.append(mode.objectName()) self.query.ruletype = rule_types self.query.perms_subset = self.perms_subset.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} constraint(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 or expression column widths are too long, pull back # to a reasonable size header = self.table_results.horizontalHeader() if header.sectionSize(2) > 400: header.resizeSection(2, 400) if header.sectionSize(3) > 400: header.resizeSection(3, 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()
class RBACRuleQueryTab(SEToolsWidget, QScrollArea): """A RBAC rule query.""" def __init__(self, parent, policy, perm_map): super(RBACRuleQueryTab, self).__init__(parent) self.log = logging.getLogger(self.__class__.__name__) self.policy = policy self.query = RBACRuleQuery(policy) self.setupUi() def __del__(self): self.thread.quit() self.thread.wait(5000) def setupUi(self): self.load_ui("rbacrulequery.ui") # set up role autocompletion (source, default) 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.source.setCompleter(self.role_completion) self.default_role.setCompleter(self.role_completion) # set up role/type autocompletion (target) roletype_completion_list = [str(r) for r in self.policy.roles()] # roletype_completion_list.extend(str(a) for a in self.policy.roleattributes()) roletype_completion_list.extend(str(t) for t in self.policy.types()) roletype_completion_list.extend(str(a) for a in self.policy.typeattributes()) roletype_completer_model = QStringListModel(self) roletype_completer_model.setStringList(sorted(roletype_completion_list)) self.roletype_completion = QCompleter() self.roletype_completion.setModel(roletype_completer_model) self.target.setCompleter(self.roletype_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 = RBACRuleListModel(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.set_default_regex(self.default_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_role.textEdited.connect(self.clear_default_error) self.default_role.editingFinished.connect(self.set_default_role) self.default_regex.toggled.connect(self.set_default_regex) # # Ruletype criteria # def _set_ruletypes(self, value): self.allow.setChecked(value) self.role_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 role 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 role/type 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_role.setToolTip("Match the default role the rule.") self.default_role.setPalette(self.orig_palette) def set_default_role(self): self.query.default_regex = self.default_regex.isChecked() try: self.query.default = self.default_role.text() except Exception as ex: self.default_role.setToolTip("Error: " + str(ex)) self.default_role.setPalette(self.error_palette) 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_role() # # Results runner # def run(self, button): # right now there is only one button. rule_types = [] for mode in [self.allow, self.role_transition]: if mode.isChecked(): rule_types.append(mode.objectName()) self.query.ruletype = rule_types 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()
class DomainTransitionAnalysisTab(SEToolsWidget, QScrollArea): """A domain transition analysis tab.""" def __init__(self, parent, policy, perm_map): super(DomainTransitionAnalysisTab, self).__init__(parent) self.log = logging.getLogger(__name__) self.policy = policy self.query = DomainTransitionAnalysis(policy) self.query.source = None self.query.target = None self.setupUi() def __del__(self): self.thread.quit() self.thread.wait(5000) logging.getLogger("setools.dta").removeHandler(self.handler) 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 = ResultsUpdater(self.query) self.thread.raw_line.connect(self.raw_results.appendPlainText) self.thread.finished.connect(self.update_complete) self.thread.trans.connect(self.reset_browser) # set up browser thread self.browser_thread = BrowserUpdater(self.query) self.browser_thread.trans.connect(self.add_browser_children) # 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.setCancelButton(None) 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()) self.browser_tab.setEnabled(self.flows_in.isChecked() or self.flows_out.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) self.browser.currentItemChanged.connect(self.browser_item_selected) # # Analysis mode # def all_paths_toggled(self, value): self.clear_source_error() self.clear_target_error() self.max_path_length.setEnabled(value) def flows_in_toggled(self, value): self.clear_source_error() self.clear_target_error() self.source.setEnabled(not value) self.reverse.setEnabled(not value) self.limit_paths.setEnabled(not value) self.browser_tab.setEnabled(value) if value: self.reverse_old = self.reverse.isChecked() self.reverse.setChecked(True) else: self.reverse.setChecked(self.reverse_old) def flows_out_toggled(self, value): self.clear_source_error() self.clear_target_error() self.target.setEnabled(not value) self.reverse.setEnabled(not value) self.limit_paths.setEnabled(not value) self.browser_tab.setEnabled(value) if value: self.reverse_old = self.reverse.isChecked() self.reverse.setChecked(False) else: self.reverse.setChecked(self.reverse_old) # # Source criteria # def set_source_error(self, error_text): self.log.error("Source domain error: {0}".format(error_text)) self.source.setToolTip("Error: {0}".format(error_text)) self.source.setPalette(self.error_palette) def clear_source_error(self): self.source.setToolTip("The source domain of the analysis.") self.source.setPalette(self.orig_palette) def set_source(self): try: # look up the type here, so invalid types can be caught immediately text = self.source.text() if text: self.query.source = self.policy.lookup_type(text) else: self.query.source = None except Exception as ex: self.set_source_error(ex) # # Target criteria # def set_target_error(self, error_text): self.log.error("Target domain error: {0}".format(error_text)) self.target.setToolTip("Error: {0}".format(error_text)) self.target.setPalette(self.error_palette) def clear_target_error(self): self.target.setToolTip("The target domain of the analysis.") self.target.setPalette(self.orig_palette) def set_target(self): try: # look up the type here, so invalid types can be caught immediately text = self.target.text() if text: self.query.target = self.policy.lookup_type(text) else: self.query.target = None except Exception as ex: self.set_target_error(ex) # # Options # def choose_excluded_types(self): chooser = ExcludeTypes(self, self.policy) chooser.show() def reverse_toggled(self, value): self.query.reverse = value # # Infoflow browser # def _new_browser_item(self, type_, parent, rules=None, children=None): # build main item item = QTreeWidgetItem(parent if parent else self.browser) item.setText(0, str(type_)) item.type_ = type_ item.children = children if children else [] item.rules = rules if rules else [] item.child_populated = children is not None # add child items for child_type, child_rules in item.children: child_item = self._new_browser_item(child_type, item, rules=child_rules) item.addChild(child_item) item.setExpanded(children is not None) self.log.debug("Built item for {0} with {1} children and {2} rules".format( type_, len(item.children), len(item.rules))) return item def reset_browser(self, root_type, out, children): self.log.debug("Resetting browser.") # clear results self.browser.clear() self.browser_details.clear() # save browser details independent # from main analysis UI settings self.browser_root_type = root_type self.browser_mode = out root = self._new_browser_item(self.browser_root_type, self.browser, children=children) self.browser.insertTopLevelItem(0, root) def browser_item_selected(self, current, previous): if not current: # browser is being reset return self.log.debug("{0} selected in browser.".format(current.type_)) self.browser_details.clear() try: parent_type = current.parent().type_ except AttributeError: # should only hit his on the root item pass else: self.browser_details.appendPlainText("Domain Transitions {0} {1} {2}\n".format( current.parent().type_, "->" if self.browser_mode else "<-", current.type_)) print_transition(self.browser_details.appendPlainText, current.rules) self.browser_details.moveCursor(QTextCursor.Start) if not current.child_populated: self.busy.setLabelText("Gathering additional browser details for {0}...".format( current.type_)) self.busy.show() self.browser_thread.out = self.browser_mode self.browser_thread.type_ = current.type_ self.browser_thread.start() def add_browser_children(self, children): item = self.browser.currentItem() item.children = children self.log.debug("Adding children for {0}".format(item.type_)) for child_type, child_rules in item.children: child_item = self._new_browser_item(child_type, item, rules=child_rules) item.addChild(child_item) item.child_populated = True self.busy.reset() # # Results runner # def run(self, button): # right now there is only one button. fail = False if self.source.isEnabled() and not self.query.source: self.set_source_error("A source domain is required") fail = True if self.target.isEnabled() and not self.query.target: self.set_target_error("A target domain is required.") fail = True if fail: return for mode in [self.all_paths, self.all_shortest_paths, self.flows_in, self.flows_out]: if mode.isChecked(): break self.query.mode = mode.objectName() self.query.max_path_len = self.max_path_length.value() self.query.limit = self.limit_paths.value() # start processing self.busy.setLabelText("Processing query...") self.busy.show() self.raw_results.clear() self.thread.start() def update_complete(self): 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) if self.flows_in.isChecked() or self.flows_out.isChecked(): # move to browser tab for transitions in/out self.results_frame.setCurrentIndex(1) else: self.results_frame.setCurrentIndex(0) self.busy.reset()
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)) 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
class ProjectExecution(QWidget): """Project Execution widget class""" def __init__(self, parent): super(ProjectExecution, self).__init__() self._parent = parent grid = QGridLayout(self) grid.addWidget(QLabel(translations.TR_PROJECT_MAIN_FILE), 0, 0) # Main file self.path = QLineEdit() choose_main_file_action = QAction(self) choose_main_file_action.setIcon( self.style().standardIcon(self.style().SP_FileIcon)) choose_main_file_action.setToolTip( translations.TR_PROJECT_SELECT_MAIN_FILE) self.path.addAction( choose_main_file_action, QLineEdit.TrailingPosition) clear_main_file_action = self.path.addAction( self.style().standardIcon(self.style().SP_LineEditClearButton), QLineEdit.TrailingPosition) clear_main_file_action.triggered.connect(self.path.clear) self.path.setPlaceholderText( os.path.join(os.path.expanduser("~"), 'path', 'to', 'main.py')) self.path.setText(self._parent.project.main_file) grid.addWidget(self.path, 0, 1) # this should be changed, and ALL pythonPath names to # python_custom_interpreter or something like that. this is NOT the # PYTHONPATH self.line_interpreter = QLineEdit() choose_interpreter = self.line_interpreter.addAction( self.style().standardIcon(self.style().SP_DirIcon), QLineEdit.TrailingPosition) self.line_interpreter.setText(self._parent.project.python_exec) completer = QCompleter(utils.get_python()) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setFilterMode(Qt.MatchContains) self.line_interpreter.setCompleter(completer) self.line_interpreter.setPlaceholderText("python") grid.addWidget(QLabel( translations.TR_PROJECT_PYTHON_INTERPRETER), 1, 0) grid.addWidget(self.line_interpreter, 1, 1) # PYTHONPATH grid.addWidget(QLabel(translations.TR_PROJECT_PYTHON_PATH), 2, 0) self.txt_python_path = QPlainTextEdit() # TODO : better widget self.txt_python_path.setPlainText(self._parent.project.python_path) self.txt_python_path.setToolTip(translations.TR_PROJECT_PATH_PER_LINE) grid.addWidget(self.txt_python_path, 2, 1) # Additional builtins/globals for pyflakes grid.addWidget(QLabel(translations.TR_PROJECT_BUILTINS), 3, 0) self.additional_builtins = QLineEdit() self.additional_builtins.setText( ' '.join(self._parent.project.additional_builtins)) self.additional_builtins.setToolTip( translations.TR_PROJECT_BUILTINS_TOOLTIP) grid.addWidget(self.additional_builtins, 3, 1) # Pre script self._line_pre_exec = QLineEdit() choose_pre_exec = QAction(self) choose_pre_exec.setToolTip( "Choose Script to execute before run project") choose_pre_exec.setIcon( self.style().standardIcon(self.style().SP_FileIcon)) self._line_pre_exec.addAction( choose_pre_exec, QLineEdit.TrailingPosition) clear_pre_action = self._line_pre_exec.addAction( self.style().standardIcon(self.style().SP_LineEditClearButton), QLineEdit.TrailingPosition) clear_pre_action.triggered.connect(self._line_pre_exec.clear) self._line_pre_exec.setReadOnly(True) self._line_pre_exec.setText(self._parent.project.pre_exec_script) self._line_pre_exec.setPlaceholderText( os.path.join(os.path.expanduser("~"), 'path', 'to', 'script.sh')) grid.addWidget(QLabel(translations.TR_PROJECT_PRE_EXEC), 4, 0) grid.addWidget(self._line_pre_exec, 4, 1) # Post script self._line_post_exec = QLineEdit() choose_post_exec = QAction(self) choose_post_exec.setToolTip( "Choose script to execute after run project") choose_post_exec.setIcon( self.style().standardIcon(self.style().SP_FileIcon)) self._line_post_exec.addAction( choose_post_exec, QLineEdit.TrailingPosition) clear_post_action = self._line_post_exec.addAction( self.style().standardIcon(self.style().SP_LineEditClearButton), QLineEdit.TrailingPosition) clear_post_action.triggered.connect(self._line_post_exec.clear) self._line_post_exec.setReadOnly(True) self._line_post_exec.setText(self._parent.project.post_exec_script) self._line_post_exec.setPlaceholderText( os.path.join(os.path.expanduser("~"), 'path', 'to', 'script.sh')) grid.addWidget(QLabel(translations.TR_PROJECT_POST_EXEC), 5, 0) grid.addWidget(self._line_post_exec, 5, 1) # grid.addItem(QSpacerItem(5, 10, QSizePolicy.Expanding, # QSizePolicy.Expanding), 6, 0) # Properties grid.addWidget(QLabel(translations.TR_PROJECT_PROPERTIES), 7, 0) self._line_params = QLineEdit() self._line_params.setToolTip(translations.TR_PROJECT_PARAMS_TOOLTIP) self._line_params.setText(self._parent.project.program_params) self._line_params.setPlaceholderText('verbose, debug, force') grid.addWidget(QLabel(translations.TR_PROJECT_PARAMS), 8, 0) grid.addWidget(self._line_params, 8, 1) # Widgets for virtualenv properties self.txtVenvPath = QLineEdit() # ui_tools.LineEditButton( # self.txtVenvPath, self.txtVenvPath.clear, # self.style().standardPixmap(self.style().SP_TrashIcon)) self.txtVenvPath.setText(self._parent.project.venv) self._dir_completer = QCompleter() self._dir_completer.setModel(QDirModel(self._dir_completer)) self.txtVenvPath.setCompleter(self._dir_completer) self.txtVenvPath.setPlaceholderText( os.path.join(os.path.expanduser("~"), 'path', 'to', 'virtualenv')) # self.btnVenvPath = QPushButton(QIcon(":img/open"), '') grid.addWidget(QLabel(translations.TR_PROJECT_VIRTUALENV), 9, 0) grid.addWidget(self.txtVenvPath, 9, 1) # grid.addWidget(self.btnVenvPath, 9, 2) choose_main_file_action.triggered.connect(self.select_file) choose_interpreter.triggered.connect(self._load_python_path) choose_pre_exec.triggered.connect(self.select_pre_exec_script) choose_post_exec.triggered.connect(self.select_post_exec_script) # self.connect(self.btnBrowse, SIGNAL("clicked()"), self.select_file) # self.connect(self.btnPythonPath, SIGNAL("clicked()"), # self._load_python_path) # self.connect(self.btnVenvPath, SIGNAL("clicked()"), # self._load_python_venv) # self.connect(self.btnPreExec, SIGNAL("clicked()"), # self.select_pre_exec_script) # self.connect(self.btnPostExec, SIGNAL("clicked()"), # self.select_post_exec_script) @property def main_file(self): return self.path.text() @property def interpreter(self): return self.line_interpreter.text() @property def pre_script(self): return self._line_pre_exec.text() @property def post_script(self): return self._line_post_exec.text() @property def params(self): return self._line_params.text() def _load_python_path(self): """Ask the user a python path and set its value""" path_interpreter = QFileDialog.getOpenFileName( self, translations.TR_PROJECT_SELECT_PYTHON_PATH)[0] if path_interpreter: self.line_interpreter.setText(path_interpreter) def _load_python_venv(self): """Ask the user a python venv and set its value""" venv = QFileDialog.getExistingDirectory( self, translations.TR_PROJECT_SELECT_VIRTUALENV) if sys.platform == 'win32': venv = os.path.join(venv, 'Scripts', 'python.exe') else: venv = os.path.join(venv, 'bin', 'python') # check if venv folder exists if not os.path.exists(venv): QMessageBox.information( self, translations.TR_PROJECT_SELECT_VIRTUALENV_MESSAGE_TITLE, translations.TR_PROJECT_SELECT_VIRTUALENV_MESSAGE_BODY) self.txtVenvPath.setText("") else: self.txtVenvPath.setText(venv) def select_file(self): """Ask the user a python main file and set its value""" filename, _ = QFileDialog.getOpenFileName( self, translations.TR_PROJECT_SELECT_MAIN_FILE, self._parent.project.path, 'Python Files (*.py);;Python Bytecode (*.py[codw]);;All Files(*)') if filename: filename = file_manager.convert_to_relative( self._parent.project.path, filename) self.path.setText(filename) def select_pre_exec_script(self): """Ask the user a python pre-exec script and set its value""" filename = QFileDialog.getOpenFileName( self, translations.TR_PROJECT_SELECT_PRE_SCRIPT, self._parent.project.path, '*(*.*);;Bash(*.sh);;Python PY(*.py);;Python Bytecode(*.py[codw]);;' 'Bat(*.bat);;Cmd(*.cmd);;Exe(*.exe);;Bin(*.bin);;App(*.app)')[0] if filename: filename = file_manager.convert_to_relative( self._parent.project.path, filename) self._line_pre_exec.setText(filename) def select_post_exec_script(self): """Ask the user a python post-exec script and set its value""" filename = QFileDialog.getOpenFileName( self, translations.TR_PROJECT_SELECT_POST_SCRIPT, self._parent.project.path, '*(*.*);;Bash(*.sh);;Python PY(*.py);;Python Bytecode(*.py[codw]);;' 'Bat(*.bat);;Cmd(*.cmd);;Exe(*.exe);;Bin(*.bin);;App(*.app)')[0] if filename: filename = file_manager.convert_to_relative( self._parent.project.path, filename) self._line_post_exec.setText(filename)
class MLSRuleQueryTab(AnalysisTab): """An MLS rule query.""" def __init__(self, parent, policy, perm_map): super(MLSRuleQueryTab, self).__init__(parent) self.log = logging.getLogger(__name__) self.policy = policy self.query = MLSRuleQuery(policy) self.setupUi() def __del__(self): self.thread.quit() self.thread.wait(5000) logging.getLogger("setools.mlsrulequery").removeHandler(self.handler) def setupUi(self): self.load_ui("apol/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.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() # 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 = MLSRuleTableModel(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(1, 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.mlsrulequery").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.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.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.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 def invert_tclass_selection(self): invert_list_selection(self.tclass.selectionModel()) # # Default criteria # def clear_default_error(self): self.clear_criteria_error(self.default_range, "Match the default type the rule.") def set_default_range(self): try: self.query.default = self.default_range.text() except Exception as ex: self.log.error("Default range error: {0}".format(ex)) self.set_criteria_error(self.default_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", "range_transition", "source_indirect", "source_regex", "target_indirect", "target_regex"]) save_lineedits(self, settings, ["source", "target", "default_range"]) save_listviews(self, settings, ["tclass"]) save_textedits(self, settings, ["notes"]) return settings def load(self, settings): load_checkboxes(self, settings, ["criteria_expander", "notes_expander", "range_transition", "source_indirect", "source_regex", "target_indirect", "target_regex"]) load_lineedits(self, settings, ["source", "target", "default_range"]) load_listviews(self, settings, ["tclass"]) load_textedits(self, settings, ["notes"]) # # 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, count): self.log.info("{0} MLS 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 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()
class InfoFlowAnalysisTab(AnalysisTab): """An information flow analysis tab.""" @property def perm_map(self): return self.query.perm_map @perm_map.setter def perm_map(self, pmap): # copy permission map to keep enabled/disabled # settings private to this map. perm_map = copy.deepcopy(pmap) # transfer enabled/disabled settings from # current permission map, to the new map for classname in self.query.perm_map.classes(): for mapping in self.query.perm_map.perms(classname): try: perm_map.mapping(classname, mapping.perm).enabled = mapping.enabled except (UnmappedClass, UnmappedPermission): pass # apply updated permission map self.query.perm_map = perm_map def __init__(self, parent, policy, perm_map): super(InfoFlowAnalysisTab, self).__init__(parent) self.log = logging.getLogger(__name__) self.policy = policy self.query = InfoFlowAnalysis(policy, perm_map) self.query.source = None self.query.target = None self.setupUi() def __del__(self): self.thread.quit() self.thread.wait(5000) logging.getLogger("setools.infoflow").removeHandler(self.handler) def setupUi(self): self.log.debug("Initializing UI.") self.load_ui("infoflow.ui") # set up error message for missing perm map self.error_msg = QMessageBox(self) self.error_msg.setStandardButtons(QMessageBox.Ok) # set up perm map editor self.permmap_editor = PermissionMapEditor(self, False) # 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.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() # set up processing thread self.thread = ResultsUpdater(self.query) self.thread.raw_line.connect(self.raw_results.appendPlainText) self.thread.finished.connect(self.update_complete) self.thread.flows.connect(self.reset_browser) # set up browser thread self.browser_thread = BrowserUpdater(self.query) self.browser_thread.flows.connect(self.add_browser_children) # 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.setCancelButton(None) self.busy.reset() # update busy dialog from infoflow INFO logs self.handler = LogHandlerToSignal() self.handler.message.connect(self.busy.setLabelText) logging.getLogger("setools.infoflow").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()) self.browser_tab.setEnabled(self.flows_in.isChecked() or self.flows_out.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.min_perm_weight.valueChanged.connect(self.set_min_weight) self.exclude_types.clicked.connect(self.choose_excluded_types) self.edit_permmap.clicked.connect(self.open_permmap_editor) self.browser.currentItemChanged.connect(self.browser_item_selected) # # Analysis mode # def all_paths_toggled(self, value): self.clear_source_error() self.clear_target_error() self.max_path_length.setEnabled(value) def flows_in_toggled(self, value): self.clear_source_error() self.clear_target_error() self.source.setEnabled(not value) self.limit_paths.setEnabled(not value) self.browser_tab.setEnabled(value) def flows_out_toggled(self, value): self.clear_source_error() self.clear_target_error() self.target.setEnabled(not value) self.limit_paths.setEnabled(not value) self.browser_tab.setEnabled(value) # # Source criteria # def clear_source_error(self): self.clear_criteria_error(self.source, "The source type of the analysis.") def set_source(self): try: # look up the type here, so invalid types can be caught immediately text = self.source.text() if text: self.query.source = self.policy.lookup_type(text) else: self.query.source = None except Exception as ex: self.log.error("Source type error: {0}".format(str(ex))) self.set_criteria_error(self.source, ex) # # Target criteria # def clear_target_error(self): self.clear_criteria_error(self.target, "The target type of the analysis.") def set_target(self): try: # look up the type here, so invalid types can be caught immediately text = self.target.text() if text: self.query.target = self.policy.lookup_type(text) else: self.query.target = None except Exception as ex: self.log.error("Target type error: {0}".format(str(ex))) self.set_criteria_error(self.target, ex) # # Options # def set_min_weight(self, value): self.query.min_weight = value def choose_excluded_types(self): chooser = ExcludeTypes(self, self.policy) chooser.show() def open_permmap_editor(self): self.permmap_editor.show(self.perm_map) def apply_permmap(self, pmap): # used only by permission map editor self.query.perm_map = pmap # # 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", "all_paths", "all_shortest_paths", "flows_in", "flows_out"]) save_lineedits(self, settings, ["source", "target"]) save_spinboxes(self, settings, ["max_path_length", "limit_paths", "min_perm_weight"]) save_textedits(self, settings, ["notes"]) settings["exclude"] = [str(t) for t in self.query.exclude] settings["exclude_perms"] = defaultdict(list) for mapping in self.perm_map: if not mapping.enabled: settings["exclude_perms"][mapping.class_].append(mapping.perm) return settings def load(self, settings): load_checkboxes(self, settings, ["criteria_expander", "notes_expander", "all_paths", "all_shortest_paths", "flows_in", "flows_out"]) load_lineedits(self, settings, ["source", "target"]) load_spinboxes(self, settings, ["max_path_length", "limit_paths", "min_perm_weight"]) load_textedits(self, settings, ["notes"]) try: self.query.exclude = settings["exclude"] except KeyError: self.log.warning("Excluded types criteria missing from settings file.") if "exclude_perms" not in settings: self.log.warning("Excluded permissions missing from settings file.") else: for mapping in self.perm_map: # iterate over the map so that any permission # not in the setting file's exclude list is enabled. try: mapping.enabled = mapping.perm not in settings["exclude_perms"][mapping.class_] except KeyError: mapping.enabled = True # # Infoflow browser # def _new_browser_item(self, type_, parent, rules=None, children=None): # build main item item = QTreeWidgetItem(parent if parent else self.browser) item.setText(0, str(type_)) item.type_ = type_ item.children = children if children else [] item.rules = rules if rules else [] item.child_populated = children is not None # add child items for child_type, child_rules in item.children: child_item = self._new_browser_item(child_type, item, rules=child_rules) item.addChild(child_item) item.setExpanded(children is not None) self.log.debug("Built item for {0} with {1} children and {2} rules".format( type_, len(item.children), len(item.rules))) return item def reset_browser(self, root_type, out, children): self.log.debug("Resetting browser.") # clear results self.browser.clear() self.browser_details.clear() # save browser details independent # from main analysis UI settings self.browser_root_type = root_type self.browser_mode = out root = self._new_browser_item(self.browser_root_type, self.browser, children=children) self.browser.insertTopLevelItem(0, root) def browser_item_selected(self, current, previous): if not current: # browser is being reset return self.log.debug("{0} selected in browser.".format(current.type_)) self.browser_details.clear() try: parent_type = current.parent().type_ except AttributeError: # should only hit his on the root item pass else: self.browser_details.appendPlainText("Information flows {0} {1} {2}\n".format( current.parent().type_, "->" if self.browser_mode else "<-", current.type_)) for rule in current.rules: self.browser_details.appendPlainText(rule) self.browser_details.moveCursor(QTextCursor.Start) if not current.child_populated: self.busy.setLabelText("Gathering additional browser details for {0}...".format( current.type_)) self.busy.show() self.browser_thread.out = self.browser_mode self.browser_thread.type_ = current.type_ self.browser_thread.start() def add_browser_children(self, children): item = self.browser.currentItem() item.children = children self.log.debug("Adding children for {0}".format(item.type_)) for child_type, child_rules in item.children: child_item = self._new_browser_item(child_type, item, rules=child_rules) item.addChild(child_item) item.child_populated = True self.busy.reset() # # Results runner # def run(self, button): # right now there is only one button. fail = False if self.source.isEnabled() and not self.query.source: self.set_criteria_error(self.source, "A source type is required") fail = True if self.target.isEnabled() and not self.query.target: self.set_criteria_error(self.target, "A target type is required.") fail = True if not self.perm_map: self.log.critical("A permission map is required to begin the analysis.") self.error_msg.critical(self, "No permission map available.", "Please load a permission map to begin the analysis.") fail = True if fail: return for mode in [self.all_paths, self.all_shortest_paths, self.flows_in, self.flows_out]: if mode.isChecked(): break self.query.mode = mode.objectName() self.query.max_path_len = self.max_path_length.value() self.query.limit = self.limit_paths.value() # start processing self.busy.setLabelText("Processing query...") self.busy.show() self.raw_results.clear() self.thread.start() def update_complete(self): 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) if self.flows_in.isChecked() or self.flows_out.isChecked(): # move to browser tab for flows in/out self.results_frame.setCurrentIndex(1) else: self.results_frame.setCurrentIndex(0) self.busy.reset()
class PortconQueryTab(AnalysisTab): """An portcon query.""" def __init__(self, parent, policy, perm_map): super(PortconQueryTab, self).__init__(parent) self.log = logging.getLogger(__name__) self.policy = policy self.query = PortconQuery(policy) self.setupUi() def __del__(self): self.thread.quit() self.thread.wait(5000) logging.getLogger("setools.portconquery").removeHandler(self.handler) def setupUi(self): self.load_ui("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() # 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) # # Ports criteria # def clear_ports_error(self): self.clear_criteria_error(self.ports, "Match the ports.") def set_ports(self): try: pending_ports = self.ports.text() if pending_ports: try: ports = [int(i) for i in pending_ports.split("-")] except ValueError: raise ValueError("Enter a port number or range, e.g. 22 or 6000-6020") if len(ports) == 2: self.query.ports = ports elif len(ports) == 1: self.query.ports = (ports[0], ports[0]) else: raise ValueError("Enter a port number or range, e.g. 22 or 6000-6020") else: self.query.ports = (0, 0) except Exception as ex: self.log.error("Ports error: {0}".format(ex)) self.set_criteria_error(self.ports, 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", "ports_exact", "ports_overlap", "ports_subset", "ports_superset", "user_regex", "role_regex", "type_regex", "range_exact", "range_overlap", "range_subset", "range_superset"]) save_lineedits(self, settings, ["ports", "user", "role", "type_", "range_"]) save_comboboxes(self, settings, ["protocol"]) save_textedits(self, settings, ["notes"]) return settings def load(self, settings): load_checkboxes(self, settings, ["criteria_expander", "notes_expander", "ports_exact", "ports_overlap", "ports_subset", "ports_superset", "user_regex", "role_regex", "type_regex", "range_exact", "range_overlap", "range_subset", "range_superset"]) load_lineedits(self, settings, ["ports", "user", "role", "type_", "range_"]) load_comboboxes(self, settings, ["protocol"]) load_textedits(self, settings, ["notes"]) # # Results runner # def run(self, button): # right now there is only one button. self.query.ports_overlap = self.ports_overlap.isChecked() self.query.ports_subset = self.ports_subset.isChecked() self.query.ports_superset = self.ports_superset.isChecked() self.query.protocol = self.protocol.currentData(Qt.DisplayRole) 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} portcon statment(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()
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)
class ProjectExecution(QWidget): def __init__(self, parent): super(ProjectExecution, self).__init__() self._parent = parent grid = QGridLayout(self) grid.addWidget(QLabel(_translate("ProjectExecution", "Main File:")), 0, 0) self.path = QLineEdit() ui_tools.LineEditButton(self.path, self.path.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.path.setText(self._parent._item.mainFile) self.path.setReadOnly(True) self.btnBrowse = QPushButton(QIcon( self.style().standardPixmap(self.style().SP_FileIcon)), '') grid.addWidget(self.path, 0, 1) grid.addWidget(self.btnBrowse, 0, 2) # this should be changed, and ALL pythonPath names to # python_custom_interpreter or something like that. this is NOT the # PYTHONPATH self.txtPythonPath = QLineEdit() self.txtPythonPath.setText(self._parent._item.pythonPath) self.btnPythonPath = QPushButton(QIcon(resources.IMAGES['open']), '') grid.addWidget(QLabel(_translate("ProjectExecution", "Python Custom Interpreter:")), 1, 0) grid.addWidget(self.txtPythonPath, 1, 1) grid.addWidget(self.btnPythonPath, 1, 2) # THIS IS THE MODAFUCKA REAL PYTHONPATH BRO, YEAH !!! grid.addWidget(QLabel(_translate("ProjectExecution", "Custom PYTHONPATH:")), 2, 0) self.PYTHONPATH = QPlainTextEdit() # TODO : better widget self.PYTHONPATH.setPlainText(self._parent._item.PYTHONPATH) self.PYTHONPATH.setToolTip(_translate("ProjectExecution", "One path per line")) grid.addWidget(self.PYTHONPATH, 2, 1) # Additional builtins/globals for pyflakes grid.addWidget(QLabel(_translate("ProjectExecution", "Additional builtins/globals:")), 3, 0) self.additional_builtins = QLineEdit() self.additional_builtins.setText( ' '.join(self._parent._item.additional_builtins)) self.additional_builtins.setToolTip(_translate("ProjectExecution", "Space-separated list of symbols that will be considered as " "builtin in every file")) grid.addWidget(self.additional_builtins, 3, 1) self.txtPreExec = QLineEdit() ui_tools.LineEditButton(self.txtPreExec, self.txtPreExec.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.txtPreExec.setReadOnly(True) self.txtPreExec.setText(self._parent._item.preExecScript) self.btnPreExec = QPushButton(QIcon(resources.IMAGES['open']), '') grid.addWidget(QLabel(_translate("ProjectExecution", "Pre-exec Script:")), 4, 0) grid.addWidget(self.txtPreExec, 4, 1) grid.addWidget(self.btnPreExec, 4, 2) self.txtPostExec = QLineEdit() ui_tools.LineEditButton(self.txtPostExec, self.txtPostExec.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.txtPostExec.setReadOnly(True) self.txtPostExec.setText(self._parent._item.postExecScript) self.btnPostExec = QPushButton(QIcon(resources.IMAGES['open']), '') grid.addWidget(QLabel(_translate("ProjectExecution", "Post-exec Script:")), 5, 0) grid.addWidget(self.txtPostExec, 5, 1) grid.addWidget(self.btnPostExec, 5, 2) grid.addItem(QSpacerItem(5, 10, QSizePolicy.Expanding, QSizePolicy.Expanding), 6, 0) # Properties grid.addWidget(QLabel(_translate("ProjectExecution", "Properties:")), 7, 0) self.txtParams = QLineEdit() self.txtParams.setToolTip( _translate("ProjectExecution", "Separate the params with commas (ie: help, verbose)")) self.txtParams.setText(self._parent._item.programParams) grid.addWidget(QLabel(_translate("ProjectExecution", "Params (comma separated):")), 8, 0) grid.addWidget(self.txtParams, 8, 1) #Widgets for virtualenv properties self.txtVenvPath = QLineEdit() ui_tools.LineEditButton(self.txtVenvPath, self.txtVenvPath.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.txtVenvPath.setText(self._parent._item.venv) self._dir_completer = QCompleter() self._dir_completer.setModel(QDirModel(self._dir_completer)) self.txtVenvPath.setCompleter(self._dir_completer) self.btnVenvPath = QPushButton(QIcon(resources.IMAGES['open']), '') grid.addWidget(QLabel(_translate("ProjectExecution", "Virtualenv Folder:")), 9, 0) grid.addWidget(self.txtVenvPath, 9, 1) grid.addWidget(self.btnVenvPath, 9, 2) self.btnBrowse.clicked['bool'].connect(self.select_file) self.btnPythonPath.clicked['bool'].connect(self._load_python_path) self.btnVenvPath.clicked['bool'].connect(self._load_python_venv) self.btnPreExec.clicked['bool'].connect(self.select_pre_exec_script) self.btnPostExec.clicked['bool'].connect(self.select_post_exec_script) def _load_python_path(self): path = QFileDialog.getOpenFileName( self, _translate("ProjectExecution", "Select Python Path")) self.txtPythonPath.setText(path) def _load_python_venv(self): venv = QFileDialog.getExistingDirectory( self, _translate("ProjectExecution", "Select Virtualenv Folder")) if sys.platform == 'win32': venv = os.path.join(venv, 'Scripts', 'python.exe') else: venv = os.path.join(venv, 'bin', 'python') #check if venv folder exists if not os.path.exists(venv): QMessageBox.information(self, _translate("ProjectExecution", "Virtualenv Folder"), _translate("ProjectExecution", "This is not a valid Virtualenv Folder")) self.txtVenvPath.setText("") else: self.txtVenvPath.setText(venv) def select_file(self): fileName = QFileDialog.getOpenFileName( self, _translate("ProjectExecution", "Select Main File"), self._parent._item.path, '(*.py);;(*.*)') if fileName != '': fileName = file_manager.convert_to_relative( self._parent._item.path, fileName) self.path.setText(fileName) def select_pre_exec_script(self): fileName = QFileDialog.getOpenFileName( self, _translate("ProjectExecution", "Select Pre Execution Script File"), self._parent._item.path, '(*.*)') if fileName != '': fileName = file_manager.convert_to_relative( self._parent._item.path, fileName) self.txtPreExec.setText(fileName) def select_post_exec_script(self): fileName = QFileDialog.getOpenFileName( self, _translate("ProjectExecution", "Select Post Execution Script File"), self._parent._item.path, '(*.*)') if fileName != '': fileName = file_manager.convert_to_relative( self._parent._item.path, fileName) self.txtPostExec.setText(fileName)