Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
 def set_auto_completion(self, string_list):
     completer = QCompleter()
     model = QStringListModel()
     model.setStringList(string_list)
     completer.setModel(model)
     completer.activated.connect(self.search, type=Qt.QueuedConnection)
     self.combobox_search.setCompleter(completer)
Пример #4
0
    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
Пример #5
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)
Пример #7
0
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.")
Пример #8
0
    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
Пример #10
0
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)
Пример #11
0
    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'])
Пример #12
0
    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()
Пример #13
0
    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))
Пример #14
0
    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()
Пример #15
0
class FileSystemOpener(QWidget):
    requestHide = pyqtSignal()
    def __init__(self):
        super(FileSystemOpener, self).__init__()
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        self.btnClose = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.completer = QCompleter(self)
        self.pathLine = ui_tools.LineEditTabCompleter(self.completer)
        fileModel = QFileSystemModel(self.completer)
        fileModel.setRootPath("")
        self.completer.setModel(fileModel)
        self.pathLine.setCompleter(self.completer)
        self.btnOpen = QPushButton(
            self.style().standardIcon(QStyle.SP_ArrowRight), 'Open!')
        hbox.addWidget(self.btnClose)
        hbox.addWidget(QLabel(_translate("FileSystemOpener", "Path:")))
        hbox.addWidget(self.pathLine)
        hbox.addWidget(self.btnOpen)

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

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

    def showEvent(self, event):
        super(FileSystemOpener, self).showEvent(event)
        self.pathLine.selectAll()
Пример #16
0
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()
Пример #17
0
    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)
Пример #19
0
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])
Пример #20
0
    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))
Пример #21
0
    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()
Пример #22
0
class Completer(QGraphicsProxyWidget, object):
    ''' Class for handling text autocompletion in the SDL scene '''
    def __init__(self, parent):
        ''' Create an autocompletion list popup '''
        widget = QListWidget()
        super(Completer, self).__init__(parent)
        self.setWidget(widget)
        self.string_list = QStringListModel()
        self._completer = QCompleter()
        self.parent = parent
        self._completer.setCaseSensitivity(Qt.CaseInsensitive)
        # For some reason the default minimum size is (61,61)
        # Set it to 0 so that the size of the box is not taken
        # into account when it is hidden.
        self.setMinimumSize(0, 0)
        self.prepareGeometryChange()
        self.resize(0, 0)
        self.hide()

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

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

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

    # pylint: disable=C0103
    def focusOutEvent(self, event):
        ''' When the user leaves the popup, return focus to parent '''
        super(Completer, self).focusOutEvent(event)
        self.hide()
        self.resize(0, 0)
        self.parentItem().setFocus()
Пример #23
0
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])
Пример #24
0
def initiate_completer(codes):
    edit = thirdPage.lineEditCode
    completer = QCompleter()
    edit.setCompleter(completer)
    model = QStringListModel()
    model.setStringList(codes)
    completer.setModel(model)
    edit.show()
Пример #25
0
 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)
Пример #26
0
 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()))
Пример #27
0
    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)
Пример #28
0
    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()
Пример #29
0
    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()
Пример #30
0
    def __init__(self,
                 device_name: str,
                 project_manager: ProjectManager,
                 signal=None,
                 backend_handler=None,
                 network_raw_mode=False,
                 signals=None,
                 parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

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

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

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

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

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

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

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

        self.signals = signals

        if len(signals) == 0:
            self.ui.label_sniff_Signal.hide()
            self.ui.btn_sniff_use_signal.hide()
            self.ui.comboBox_sniff_signal.hide()
        else:
            for signal in signals:
                self.ui.comboBox_sniff_signal.addItem(signal.name)
Пример #31
0
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)
Пример #32
0
 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)
Пример #33
0
 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
Пример #34
0
    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)
Пример #35
0
    def __init__(self, parent, completion_model=None):
        super(SearchBarComboBox, self).__init__(parent)

        self.setFont(get_monospace_font())
        self.setToolTip('Enter the search pattern here')
        completer = QCompleter(self)
        completer.setCaseSensitivity(Qt.CaseSensitive)
        if completion_model is not None:
            completer.setModel(completion_model)
        else:
            completer.setModel(self.model())
        self.setCompleter(completer)
Пример #36
0
	def __init__(self,expdat):
		super(DBAnnotateSave, self).__init__()
		print("DBAnnotateSave")
		uic.loadUi(os.path.join(hs.heatsequerdir,'ui/manualdata.py'), self)
		self.bplus.clicked.connect(self.plus)
		self.bminus.clicked.connect(self.minus)
		self.bontoinput.returnPressed.connect(self.plus)
		self.bstudyinfo.clicked.connect(self.studyinfo)
		self.bisa.toggled.connect(self.radiotoggle)
		self.bdiffpres.toggled.connect(self.radiotoggle)
		self.bisatype.currentIndexChanged.connect(self.isatypechanged)
		self.bhistory.clicked.connect(self.history)
		self.cexp=expdat
		self.lnumbact.setText(str(len(expdat.selectedseqs)))
		completer = QCompleter()
		self.bontoinput.setCompleter(completer)
		scdb=hs.scdb
		self.scdb=scdb
		self.dataid=hs.supercooldb.finddataid(scdb,datamd5=self.cexp.datamd5,mapmd5=self.cexp.mapmd5)

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

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

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

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

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

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

		self.prefillinfo()
		self.bontoinput.setFocus()
Пример #37
0
    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)
Пример #38
0
    def __init__(self, device_name: str, project_manager: ProjectManager, signal=None, backend_handler=None,
                 network_raw_mode=False, signals=None, parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

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

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

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

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

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

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

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

        self.signals = signals

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

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

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

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

        self.create_connects()
Пример #40
0
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()
Пример #41
0
    def __init__(self, namespace, parent):
        """Constructor.

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

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

        self._history = cmdhistory.History()
        self.returnPressed.connect(self.on_return_pressed)
Пример #42
0
    def __init__(self, parent, default=None):
        super(PathItem, self).__init__(parent)

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

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

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

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

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

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

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

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._remove_button)
        layout.addWidget(self._path_bar, 1)
        layout.addWidget(self._select_file_button)
        layout.addWidget(self._select_dir_button)
        layout.addWidget(self._hit_count_label)
        self.setLayout(layout)
Пример #43
0
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)
Пример #44
0
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()
Пример #45
0
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()
Пример #47
0
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()
Пример #48
0
    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
Пример #49
0
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()
Пример #50
0
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()
Пример #51
0
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()
Пример #52
0
    def __init__(self, installed_plugins, highlighted_plugins=None, parent=None):
        super().__init__(parent)

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

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

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

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

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

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

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

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

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

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

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

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

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

        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)
Пример #54
0
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()
Пример #55
0
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()
Пример #56
0
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()
Пример #57
0
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)