def testSignals(self): self._called = False m = QStringListModel() m.rowsAboutToBeInserted[QModelIndex, int, int].connect(self.sigCallback) m.insertRows(0, 3) self.assert_(self._called)
class autocompleter(QtGuiWidgets.QLineEdit ): #easily reusable lineEdits with autocomplete def __init__(self, list, prefill=None): super(autocompleter, self).__init__() self.list = list self.prefillObject = prefill self.alreadyPrefilled = False self.qList = QStringListModel() self.qList.setStringList(self.list) self.fakeEnterFlag = False self.completer = QtGuiWidgets.QCompleter() self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) self.completer.setModel(self.qList) self.confirmText = '' self.setCompleter(self.completer) self.updateList(list) def updateList(self, list): #update Qcompleter model self.list = list self.qList.setStringList(self.list) def event(self, event): #override tab and enter/return behaviour if self.completer.popup().isVisible(): self.completer.highlighted.connect(self.setConfirmText) if event.type() == QtCore.QEvent.KeyPress: if event.key() == QtCore.Qt.Key_Tab: if self.confirmText == '' or self.text() not in self.list: self.setText(self.completer.currentCompletion()) else: self.setText(self.confirmText) self.fakeEnterFlag = True QtCore.QCoreApplication.postEvent( self, QtGui.QKeyEvent(QtCore.QEvent.KeyPress, QtCore.Qt.Key_Return, QtCore.Qt.NoModifier)) if event.key() == QtCore.Qt.Key_Enter or event.key( ) == QtCore.Qt.Key_Return: self.setText(self.completer.currentCompletion()) QtCore.QCoreApplication.postEvent( self, QtGui.QKeyEvent(QtCore.QEvent.KeyPress, QtCore.Qt.Key_Return, QtCore.Qt.NoModifier)) else: self.confirmText = '' if event.type() == QtCore.QEvent.FocusIn: if self.alreadyPrefilled == False: if not self.prefillObject == None: self.setText(self.prefillObject.text()) self.alreadyPrefilled = True return QtGuiWidgets.QLineEdit.event(self, event) def setConfirmText( self, text ): #store the currently highlighted value to use in tab completion self.confirmText = text
class Completer(QGraphicsProxyWidget, object): ''' Class for handling text autocompletion in the SDL scene ''' def __init__(self, parent): ''' Create an autocompletion list popup ''' widget = QListWidget() super(Completer, self).__init__(parent) self.setWidget(widget) self.string_list = QStringListModel() self._completer = QCompleter() self.parent = parent self._completer.setCaseSensitivity(Qt.CaseInsensitive) # For some reason the default minimum size is (61,61) # Set it to 0 so that the size of the box is not taken # into account when it is hidden. self.setMinimumSize(0, 0) self.prepareGeometryChange() self.resize(0, 0) self.hide() def set_completer_list(self): ''' Set list of items for the autocompleter popup ''' compl = [item.replace('-', '_') for item in self.parent.parentItem().completion_list] self.string_list.setStringList(compl) self._completer.setModel(self.string_list) def set_completion_prefix(self, completion_prefix): ''' Set the current completion prefix (user-entered text) and set the corresponding list of words in the popup widget ''' self._completer.setCompletionPrefix(completion_prefix) self.widget().clear() count = self._completer.completionCount() for i in xrange(count): self._completer.setCurrentRow(i) self.widget().addItem(self._completer.currentCompletion()) self.prepareGeometryChange() if count: self.resize(self.widget().sizeHintForColumn(0) + 40, 70) else: self.resize(0, 0) return count # pylint: disable=C0103 def keyPressEvent(self, e): super(Completer, self).keyPressEvent(e) if e.key() == Qt.Key_Escape: self.parentItem().setFocus() # Consume the event so that it is not repeated at EditableText level e.accept() # pylint: disable=C0103 def focusOutEvent(self, event): ''' When the user leaves the popup, return focus to parent ''' super(Completer, self).focusOutEvent(event) self.hide() self.resize(0, 0) self.parentItem().setFocus()
class 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 = list(self.parent.parentItem().completion_list) self.string_list.setStringList(compl) self._completer.setModel(self.string_list) def set_completion_prefix(self, completion_prefix): ''' Set the current completion prefix (user-entered text) and set the corresponding list of words in the popup widget ''' self._completer.setCompletionPrefix(completion_prefix) self.widget().clear() count = self._completer.completionCount() for i in xrange(count): self._completer.setCurrentRow(i) self.widget().addItem(self._completer.currentCompletion()) self.prepareGeometryChange() if count: self.resize(self.widget().sizeHintForColumn(0) + 40, 70) else: self.resize(0, 0) return count # pylint: disable=C0103 def keyPressEvent(self, e): super(Completer, self).keyPressEvent(e) if e.key() == Qt.Key_Escape: self.parentItem().setFocus() # Consume the event so that it is not repeated at EditableText level e.accept() # pylint: disable=C0103 def focusOutEvent(self, event): ''' When the user leaves the popup, return focus to parent ''' super(Completer, self).focusOutEvent(event) self.hide() self.resize(0, 0) self.parentItem().setFocus()
def setCompleterModel(self): result = self.search.text() if len(result) == 1: wordobjects = self.indexer.data['WORDS'].start_with_prefix(result) words = [] for wordobj in wordobjects: words.append(wordobj.word) model = QStringListModel() model.setStringList(words) self.completer.setModel(model)
def search(self, text, *args): li = [] tplus = text + "%" cur.execute("select ENGW from ENGTAM where ENGW like ? limit 20", (tplus, )) cuf = cur.fetchall() model = QStringListModel() for i in range(len(cuf)): k = cuf[i][0] li.append(k) model.setStringList(li) self.completer.setModel(model)
def __init__(self, *args, **kwargs): super(RuleTextEdit, self).__init__(*args, **kwargs) self.setAutoFillBackground(True) self.textChanged.connect(self.onTextChange) model = QStringListModel() model.setStringList(['<', '>', '=', 'vasya']) self.completer = QCompleter(model) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.setCompleter(self.completer)
def __init__(self, list, prefill=None): super(autocompleter, self).__init__() self.list = list self.prefillObject = prefill self.alreadyPrefilled = False self.qList = QStringListModel() self.qList.setStringList(self.list) self.fakeEnterFlag = False self.completer = QtGuiWidgets.QCompleter() self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) self.completer.setModel(self.qList) self.confirmText = '' self.setCompleter(self.completer) self.updateList(list)
class TagEdit(object): """Abstraction for tag edit""" def __init__(self, parent, widget, on_change): """Init and connect signals""" self.parent = parent self.app = QApplication.instance() self.widget = widget self.tags_list = map(lambda tag: Tag.from_tuple(tag).name, self.app.provider.list_tags(), ) self.completer = QCompleter() self.completer_model = QStringListModel() self.completer.setModel(self.completer_model) self.completer.activated.connect(self.update_completion) self.update_completion() self.widget.setCompleter(self.completer) self.widget.textChanged.connect(Slot()(on_change)) self.widget.textEdited.connect(self.update_completion) @property def tags(self): """Get tags""" # Split on comma and Arabic comma # 0x060c is the Arabic comma return map(lambda tag: tag.strip(), re.split(u',|\u060c', self.widget.text())) @tags.setter def tags(self, val): """Set tags""" self.widget.setText(', '.join(val)) @Slot() def update_completion(self): """Update completion model with exist tags""" orig_text = self.widget.text() text = ', '.join(orig_text.replace(', ', ',').split(',')[:-1]) tags = [] for tag in self.tags_list: if ',' in orig_text: if orig_text[-1] not in (',', ' '): tags.append('%s,%s' % (text, tag)) tags.append('%s, %s' % (text, tag)) else: tags.append(tag) if tags != self.completer_model.stringList(): self.completer_model.setStringList(tags)
def _createApiChooserLineedit(self): """ Create the I{QLineEdit }used for selecting API names. This includes a QCompleter to make suggestions based on the keyword database. """ self.api_chooser_lineedit = QLineEdit() self.api_chooser_lineedit.returnPressed.connect(self.populateBrowserWindow) self.api_chooser_lineedit.textChanged.connect(self._updateCompleterModel) completer = QCompleter() completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) completer.setModelSorting(QCompleter.CaseSensitivelySortedModel) self.completer_model = QStringListModel([]) completer.setModel(self.completer_model) self.api_chooser_lineedit.setCompleter(completer)
class TagEdit(object): """Abstraction for tag edit""" def __init__(self, parent, widget, on_change): """Init and connect signals""" self.parent = parent self.app = QApplication.instance() self.widget = widget self.tags_list = map( lambda tag: Tag.from_tuple(tag).name, self.app.provider.list_tags(), ) self.completer = QCompleter() self.completer_model = QStringListModel() self.completer.setModel(self.completer_model) self.completer.activated.connect(self.update_completion) self.update_completion() self.widget.setCompleter(self.completer) self.widget.textChanged.connect(Slot()(on_change)) self.widget.textEdited.connect(self.update_completion) @property def tags(self): """Get tags""" # Split on comma and Arabic comma # 0x060c is the Arabic comma return map(lambda tag: tag.strip(), re.split(u',|\u060c', self.widget.text())) @tags.setter def tags(self, val): """Set tags""" self.widget.setText(', '.join(val)) @Slot() def update_completion(self): """Update completion model with exist tags""" orig_text = self.widget.text() text = ', '.join(orig_text.replace(', ', ',').split(',')[:-1]) tags = [] for tag in self.tags_list: if ',' in orig_text: if orig_text[-1] not in (',', ' '): tags.append('%s,%s' % (text, tag)) tags.append('%s, %s' % (text, tag)) else: tags.append(tag) if tags != self.completer_model.stringList(): self.completer_model.setStringList(tags)
def __init__(self, parent): ''' Create an autocompletion list popup ''' widget = QListWidget() super(Completer, self).__init__(parent) self.setWidget(widget) self.string_list = QStringListModel() self._completer = QCompleter() self.parent = parent self._completer.setCaseSensitivity(Qt.CaseInsensitive) # For some reason the default minimum size is (61,61) # Set it to 0 so that the size of the box is not taken # into account when it is hidden. self.setMinimumSize(0, 0) self.prepareGeometryChange() self.resize(0, 0) self.hide()
def __init__(self, parent=None): super(LiteListView, self).__init__(parent) # モデルの作成 self.model = QStringListModel() self.setModel(self.model) # D&D処理を許可 self.setAcceptDrops(True)
def __create_filter_ui(self): """ Create filter widgets """ filter_layout = QHBoxLayout() filter_layout.setSpacing(1) filter_layout.setContentsMargins(0, 0, 0, 0) self.filter_reset_btn = QPushButton() icon = QIcon(':/filtersOff.png') self.filter_reset_btn.setIcon(icon) self.filter_reset_btn.setIconSize(QSize(22, 22)) self.filter_reset_btn.setFixedSize(24, 24) self.filter_reset_btn.setToolTip('Reset filter') self.filter_reset_btn.setFlat(True) self.filter_reset_btn.clicked.connect( partial(self.on_filter_set_text, '')) self.filter_line = QLineEdit() self.filter_line.setPlaceholderText('Enter filter string here') self.filter_line.textChanged.connect(self.on_filter_change_text) completer = QCompleter(self) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setModel(QStringListModel([], self)) self.filter_line.setCompleter(completer) filter_layout.addWidget(self.filter_reset_btn) filter_layout.addWidget(self.filter_line) return filter_layout
def __init__(self, parent=None): super(ExportDialog, self).__init__(parent) self._output_folder = None self.setModal(True) layout_main = QGridLayout() label_choose_format = QLabel(self.tr("Choose format")) self.combo_choose_format = QComboBox() self.combo_choose_format.setModel(QStringListModel(FileExporter.FORMATS_AVAILABLE)) label_saveto = QLabel(self.tr("Save location")) button_saveto = QPushButton(self.tr("Browse ...")) button_saveto.clicked.connect(self._openFolderChoiceDialog) self.label_output = QLabel() button_export = QPushButton(self.tr("Export")) button_export.clicked.connect(self.accept) button_cancel = QPushButton(self.tr("Cancel")) button_cancel.clicked.connect(self.reject) row = 0; col = 0; layout_main.addWidget(label_choose_format, row, col, 1, 2) col += 2 layout_main.addWidget(self.combo_choose_format, row, col, 1, 2) row += 1; col -= 2; layout_main.addWidget(label_saveto, row, col, 1, 2) col += 2 layout_main.addWidget(button_saveto, row, col, 1, 2) row += 1; col -= 2; layout_main.addWidget(self.label_output, row, col, 1, 4) row += 1; col += 2 layout_main.addWidget(button_export, row, col) col += 1 layout_main.addWidget(button_cancel, row, col) self.setWindowTitle(self.tr("Export Parameters")) self.setLayout(layout_main)
def setList(self, list): self.clear() self.addItems(list) autoCompleteModel = QStringListModel(list) completer = QCompleter() completer.setModel(autoCompleteModel) completer.setCaseSensitivity(Qt.CaseInsensitive) self.setCompleter(completer)
def __init__(self, parent, widget, on_change): """Init and connect signals""" self.parent = parent self.app = QApplication.instance() self.widget = widget self.tags_list = map( lambda tag: Tag.from_tuple(tag).name, self.app.provider.list_tags(), ) self.completer = QCompleter() self.completer_model = QStringListModel() self.completer.setModel(self.completer_model) self.completer.activated.connect(self.update_completion) self.update_completion() self.widget.setCompleter(self.completer) self.widget.textChanged.connect(Slot()(on_change)) self.widget.textEdited.connect(self.update_completion)
class TagEdit(object): """Abstraction for tag edit""" def __init__(self, parent, app, widget, on_change): """Init and connect signals""" self.parent = parent self.app = app self.widget = widget self.tags_list = map(lambda tag: Tag.from_tuple(tag).name, self.app.provider.list_tags()) self.completer = QCompleter() self.completer_model = QStringListModel() self.completer.setModel(self.completer_model) self.completer.activated.connect(self.update_completion) self.update_completion() self.widget.setCompleter(self.completer) self.widget.textChanged.connect(Slot()(on_change)) self.widget.textEdited.connect(self.update_completion) @property def tags(self): """Get tags""" return map(lambda tag: tag.strip(), self.widget.text().split(",")) @tags.setter def tags(self, val): """Set tags""" self.widget.setText(", ".join(val)) @Slot() def update_completion(self): """Update completion model with exist tags""" orig_text = self.widget.text() text = ", ".join(orig_text.replace(", ", ",").split(",")[:-1]) tags = [] for tag in self.tags_list: if "," in orig_text: if orig_text[-1] not in (",", " "): tags.append("%s,%s" % (text, tag)) tags.append("%s, %s" % (text, tag)) else: tags.append(tag) if tags != self.completer_model.stringList(): self.completer_model.setStringList(tags)
def __init__(self, parent, mframe, existing_filters): """Create a FilterTab with the given parent TabDialog, logical parent ModuleFrame mframe, and existing_filters list of Clause objects. """ super(FilterTab, self).__init__(parent) self.mframe = mframe self.parent = parent self.attributes = self.mframe.agent.datatree.generateAttributeList() self.clause_list = list() self.clause_dict = dict() # Right now we only look at the first passed in filter. # TODO: At GUI to switch between existing filters if existing_filters is not None and len(existing_filters) > 0: for clause in existing_filters[0].conditions.clauses: self.clause_list.append(str(clause)) self.clause_dict[str(clause)] = clause self.clause_model = QStringListModel(self.clause_list) layout = QVBoxLayout(self) self.sidesplitter = QSplitter(Qt.Horizontal) # You can only select one attribute at a time to build the # filter clauses self.data_view = QTreeView(self) self.data_view.setModel(self.mframe.agent.datatree) self.data_view.setDragEnabled(True) self.data_view.setDropIndicatorShown(True) self.data_view.expandAll() self.sidesplitter.addWidget(self.data_view) self.sidesplitter.setStretchFactor(1,1) self.filter_widget = self.buildFilterWidget() self.sidesplitter.addWidget(self.filter_widget) self.sidesplitter.setStretchFactor(1,0) layout.addWidget(self.sidesplitter) # Apply buttons buttonWidget = QWidget() buttonLayout = QHBoxLayout(buttonWidget) self.applyButton = QPushButton("Apply") self.applyButton.clicked.connect(self.applyFilter) self.closeButton = QPushButton("Apply & Close") self.closeButton.clicked.connect(self.applyCloseFilter) buttonLayout.addWidget(self.applyButton) buttonLayout.addWidget(self.closeButton) buttonWidget.setLayout(buttonLayout) layout.addWidget(buttonWidget) self.setLayout(layout)
def __init__(self): def paste(): loadPath = (self.repository+self.filename_base+"%s.nk")%(self.cb_list.currentText()) print loadPath nuke.nodePaste(loadPath) self.close() self.user = os.environ.get("USERNAME") self.repository = "T://_Nuke_tools//global_clipboard//" self.filename_base = "tempClipBoard_" os.chdir(self.repository) self.items = [] for file in glob.glob("*.nk"): self.items.append(file.split(self.filename_base)[-1].split('.')[0]) super(GlobalClipboard, self).__init__(QtGui.QApplication.activeWindow()) self.setWindowTitle('Global Clipboard') self.hbox=QtGui.QHBoxLayout() self.cb_list=QtGui.QComboBox() self.cb_list.setEditable(True) for item in self.items: self.cb_list.addItem(item) self.completer = QCompleter() self.cb_list.setCompleter(self.completer) self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) model_autocomplete = QStringListModel() self.completer.setModel(model_autocomplete) model_autocomplete.setStringList(self.items) self.description=QtGui.QLabel(self) self.description.setText("Paste from") self.hbox.addWidget(self.description)#desc self.hbox.addWidget(self.cb_list)#menu self.button=QtGui.QPushButton("Paste") self.hbox.addWidget(self.button)#button self.button.clicked.connect(paste) self.setLayout(self.hbox)
def __init__(self, parent, app, widget, on_change): """Init and connect signals""" self.parent = parent self.app = app self.widget = widget self.tags_list = map(lambda tag: Tag.from_tuple(tag).name, self.app.provider.list_tags()) self.completer = QCompleter() self.completer_model = QStringListModel() self.completer.setModel(self.completer_model) self.completer.activated.connect(self.update_completion) self.update_completion() self.widget.setCompleter(self.completer) self.widget.textChanged.connect(Slot()(on_change)) self.widget.textEdited.connect(self.update_completion)
def refresh(self): RWWidget.refresh(self) idx = self.relationSelector.currentIndex() self.treeWidget.clear() variant = None if idx != -1: variant = self.relationSelector.currentText() if variant is None: return abstractGraph = self.IA.get_graph([(0, variant)]) if abstractGraph is None or len(abstractGraph.relations) == 0: return createdNodes = buildRootNode(abstractGraph.relations, treeview=self.treeWidget) self.rootSelector.clear() model = QStringListModel() nodeList = list() for i in createdNodes: nodeList.append(i.text(0)) nodeList.sort() model.setStringList(nodeList) self.createdNodes = createdNodes self.rootSelector.setModel(model) self.rootSelector.setCurrentIndex(-1)
def __init__(self, parent=None, list=[]): QComboBox.__init__(self, parent) self.setEditable(True) self.setInsertPolicy(QComboBox.NoInsert) self.addItems(list) autoCompleteModel = QStringListModel(list) completer = QCompleter() completer.setModel(autoCompleteModel) completer.setCaseSensitivity(Qt.CaseInsensitive) self.setCompleter(completer) self.setEditText("") self.__textChangeStatus = True self.editTextChanged.connect(self.__onTextChange) shortcut = QShortcut(QKeySequence(Qt.Key_Return), self, self.__onEnter) shortcut = QShortcut(QKeySequence(Qt.Key_Enter), self, self.__onEnter)
class WinApiWidget(QtGui.QWidget): """ A widget for allowing easy access to Windows API information. Front-end to the I{idascope.core.WinApiProvider}. """ def __init__(self, parent): QtGui.QWidget.__init__(self) print "[|] loading WinApiWidget" self.parent = parent self.name = "WinAPI Browsing" self.icon = QIcon(self.parent.config.icon_file_path + "winapi.png") self.search_icon = QIcon(self.parent.config.icon_file_path + "search.png") self.back_icon = QIcon(self.parent.config.icon_file_path + "back.png") self.forward_icon = QIcon(self.parent.config.icon_file_path + "forward.png") self.online_icon = QIcon(self.parent.config.icon_file_path + "online.png") self.ida_proxy = self.parent.ida_proxy self.QtGui = QtGui self.QtCore = QtCore self.winapi = self.parent.winapi_provider self.old_keyword_initial = "" self.winapi.registerDataReceiver(self.populateBrowserWindow) self._createGui() self._updateAvailability() self._registerHotkeys() def _updateAvailability(self): """ Adjust the availability of this widget by checking if the keyword database has been loaded or online mode is enabled. """ if not self.winapi.hasOfflineMsdnAvailable() and \ not self.winapi.hasOnlineMsdnAvailable(): self.browser_window.setHtml("<p><font color=\"#FF0000\">Offline MSDN database is not available. To use " \ + "it, have a look at the installation instructions located in the manual: " \ + "IDAscope/documentation/manual.html. Online mode is deactivated as well.</font></p>") self.search_button.setEnabled(False) self.api_chooser_lineedit.setEnabled(False) else: self.browser_window.setHtml("<p>Enter a search term in the above field to search offline/online MSDN.</p>") self.search_button.setEnabled(True) self.api_chooser_lineedit.setEnabled(True) def _registerHotkeys(self): """ Register hotkeys with IDAscope in order to ease the use of this widget. """ self.parent.registerHotkey(self.parent.config.winapi_shortcut, self._navigateToHighlightedIdentifier) def _createGui(self): """ Create the GUI for this widget and all of its components. """ self._createBackButton() self._createNextButton() self._createOnlineButton() self._createApiChooserLineedit() self._createSearchButton() self._createBrowserWindow() winapi_layout = QtGui.QVBoxLayout() selection_widget = QtGui.QWidget() selection_layout = QtGui.QHBoxLayout() selection_layout.addWidget(self.online_button) selection_layout.addWidget(self.back_button) selection_layout.addWidget(self.next_button) selection_layout.addWidget(self.api_chooser_lineedit) selection_layout.addWidget(self.search_button) selection_widget.setLayout(selection_layout) winapi_layout.addWidget(selection_widget) winapi_layout.addWidget(self.browser_window) self.setLayout(winapi_layout) def _createBackButton(self): """ Create a back button to allow easier browsing """ self.back_button = QtGui.QPushButton(self.back_icon, "", self) self.back_button.setToolTip("Go back to previously accessed content.") self.back_button.resize(self.back_button.sizeHint()) self.back_button.setEnabled(False) self.back_button.clicked.connect(self._onBackButtonClicked) def _createNextButton(self): """ Create a next button to allow easier browsing """ self.next_button = QtGui.QPushButton(self.forward_icon, "", self) self.next_button.setToolTip("Go forward to previously accessed content.") self.next_button.resize(self.next_button.sizeHint()) self.next_button.setEnabled(False) self.next_button.clicked.connect(self._onNextButtonClicked) def _createOnlineButton(self): """ Create a next button to allow easier browsing """ self.online_button = QtGui.QPushButton(self.online_icon, "", self) self.online_button.setCheckable(True) if self.winapi.hasOnlineMsdnAvailable(): self.online_button.setChecked(QtCore.Qt.Checked) self.online_button.setToolTip("Enable/disable MSDN online lookup.") self.online_button.resize(self.online_button.sizeHint()) self.online_button.clicked.connect(self._onOnlineButtonClicked) def _createApiChooserLineedit(self): """ Create the I{QLineEdit }used for selecting API names. This includes a QCompleter to make suggestions based on the keyword database. """ self.api_chooser_lineedit = QLineEdit() self.api_chooser_lineedit.returnPressed.connect(self.populateBrowserWindow) self.api_chooser_lineedit.textChanged.connect(self._updateCompleterModel) completer = QCompleter() completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) completer.setModelSorting(QCompleter.CaseSensitivelySortedModel) self.completer_model = QStringListModel([]) completer.setModel(self.completer_model) self.api_chooser_lineedit.setCompleter(completer) def _createSearchButton(self): """ Create a search button besides the QLineEdit. """ self.search_button = QtGui.QPushButton(self.search_icon, "", self) self.search_button.setToolTip("Search for the chosen API name, structure or whatever WinAPI documentation " \ + "might have for you.") self.search_button.resize(self.search_button.sizeHint()) self.search_button.clicked.connect(self._onSearchButtonClicked) def _createBrowserWindow(self): """ Create the browser window with a I{QTextBrowser}. This display component is chosen over I{QWebView} because WebKit is not included in the standard PySide installation as distributed with IDA Pro. """ self.browser_window = QTextBrowser() self.browser_window.anchorClicked.connect(self._browserAnchorClicked) def _updateCompleterModel(self): """ Update the completer model used to make suggestions. The model is only updated if anything is entered into the search line and the initial character differs from the previous initial character. """ keyword_data = [] api_chooser_text = self.api_chooser_lineedit.text() if len(api_chooser_text) > 0: keyword_initial = api_chooser_text[0].lower() if keyword_initial != self.old_keyword_initial: self.old_keyword_initial = keyword_initial keyword_data = self.winapi.getKeywordsForInitial(keyword_initial) self.completer_model.setStringList(keyword_data) def populateBrowserWindow(self, content=""): """ Populate the browser window based upon the entered term in the search line. @param content: the content to render in the browser @type content: str """ if content == "": api_chooser_text = self.api_chooser_lineedit.text() if len(api_chooser_text) > 0: content = self.winapi.getKeywordContent(api_chooser_text) self.browser_window.setHtml(content) self._updateHistoryButtonState() def _onSearchButtonClicked(self): """ Action that is performed when the search button is clicked. This will populate the browser window. """ self.populateBrowserWindow() def _onBackButtonClicked(self): """ Action that is performed when the search button is clicked. This will populate the browser window. """ document_content, anchor = self.winapi.getPreviousDocumentContent() if document_content != "": self.browser_window.setHtml(document_content) self.browser_window.scrollToAnchor(anchor) self._updateHistoryButtonState() def _onNextButtonClicked(self): """ Action that is performed when the search button is clicked. This will populate the browser window. """ document_content, anchor = self.winapi.getNextDocumentContent() if document_content != "": self.browser_window.setHtml(document_content) self.browser_window.scrollToAnchor(anchor) self._updateHistoryButtonState() def _onOnlineButtonClicked(self): """ Action that is performed when the search button is clicked. This will populate the browser window. """ self.winapi.setOnlineMsdnEnabled(not self.winapi.hasOnlineMsdnAvailable()) self._updateAvailability() def _browserAnchorClicked(self, url): """ Callback for the case an anchor (or any link) within the browser window is clicked. This will fetch document content and anchor based on the URL of the link and update the browser window. @param url: a URL as triggered by the callback @type url: QUrl """ document_content, anchor = self.winapi.getLinkedDocumentContent(url) if document_content != "": self.browser_window.setHtml(document_content) self.browser_window.scrollToAnchor(anchor) self._updateHistoryButtonState() def navigate(self, api_name): """ A function exposed in order to allow the widget to be navigated to an arbitrary API name. @param api_name: the API name to navigate the widget to. @type api_name: str """ self.api_chooser_lineedit.setText(api_name) self.populateBrowserWindow() def _navigateToHighlightedIdentifier(self): """ A function exposed to allow navigating the widget to the currently highlighted identifier from the IDA view. """ if self.winapi.hasOfflineMsdnAvailable(): highlighted_identifier = Misc.cleanCountingSuffix(self.ida_proxy.get_highlighted_identifier()) highlighted_identifier = self.parent.semantic_identifier.lookupDisplayApiName(highlighted_identifier) self.navigate(highlighted_identifier) self.parent.setTabFocus(self.name) def _updateHistoryButtonState(self): """ Update the button state (enabled/disabled) according to availability of history information from the WinApiProvider """ self.back_button.setEnabled(self.winapi.hasBackwardHistory()) self.next_button.setEnabled(self.winapi.hasForwardHistory())
from PySide.QtCore import Qt, QPersistentModelIndex from PySide.QtGui import QStringListModel if __name__ == '__main__': stringListModel = QStringListModel(['one', 'two']) idx = stringListModel.index(1, 0) persistentModelIndex = QPersistentModelIndex(idx) stringListModel.data(persistentModelIndex, Qt.DisplayRole)
class FilterTab(QWidget): """This class is the GUI for creating filters for the FilterBox module. This GUI will be added as a tab to the ModuleFrame tab dialog. """ applySignal = Signal(Clause) def __init__(self, parent, mframe, existing_filters): """Create a FilterTab with the given parent TabDialog, logical parent ModuleFrame mframe, and existing_filters list of Clause objects. """ super(FilterTab, self).__init__(parent) self.mframe = mframe self.parent = parent self.attributes = self.mframe.agent.datatree.generateAttributeList() self.clause_list = list() self.clause_dict = dict() # Right now we only look at the first passed in filter. # TODO: At GUI to switch between existing filters if existing_filters is not None and len(existing_filters) > 0: for clause in existing_filters[0].conditions.clauses: self.clause_list.append(str(clause)) self.clause_dict[str(clause)] = clause self.clause_model = QStringListModel(self.clause_list) layout = QVBoxLayout(self) self.sidesplitter = QSplitter(Qt.Horizontal) # You can only select one attribute at a time to build the # filter clauses self.data_view = QTreeView(self) self.data_view.setModel(self.mframe.agent.datatree) self.data_view.setDragEnabled(True) self.data_view.setDropIndicatorShown(True) self.data_view.expandAll() self.sidesplitter.addWidget(self.data_view) self.sidesplitter.setStretchFactor(1,1) self.filter_widget = self.buildFilterWidget() self.sidesplitter.addWidget(self.filter_widget) self.sidesplitter.setStretchFactor(1,0) layout.addWidget(self.sidesplitter) # Apply buttons buttonWidget = QWidget() buttonLayout = QHBoxLayout(buttonWidget) self.applyButton = QPushButton("Apply") self.applyButton.clicked.connect(self.applyFilter) self.closeButton = QPushButton("Apply & Close") self.closeButton.clicked.connect(self.applyCloseFilter) buttonLayout.addWidget(self.applyButton) buttonLayout.addWidget(self.closeButton) buttonWidget.setLayout(buttonLayout) layout.addWidget(buttonWidget) self.setLayout(layout) def applyFilter(self): """Emits the applySignal with the Clause object currently represented by this FilterTab. """ num_clauses = len(self.clause_list) if num_clauses == 0: self.applySignal.emit(None) else: self.applySignal.emit(Clause("and", *self.clause_dict.values())) def applyCloseFilter(self): """Calls applyFilter and then closes the containing TabDialog.""" self.applyFilter() self.parent.close() def buildFilterWidget(self): """Creates the filter portion of the widget by laying out the subwidgets for relations, workspace and existing clauses. """ filter_widget = QWidget() filter_layout = QVBoxLayout(filter_widget) filter_layout.addWidget(self.buildRelationsWidget()) filter_layout.addItem(QSpacerItem(5,5)) filter_layout.addWidget(self.buildWorkFrame()) filter_layout.addItem(QSpacerItem(5,5)) filter_layout.addWidget(self.buildFilterListView()) filter_widget.setLayout(filter_layout) return filter_widget def buildFilterListView(self): """Creates the QListView that contains all of the basic Clause objects. """ groupBox = QGroupBox("Clauses") layout = QVBoxLayout(groupBox) self.list_view = QListView(groupBox) self.list_view.setModel(self.clause_model) layout.addWidget(self.list_view) layout.addItem(QSpacerItem(5,5)) self.delButton = QPushButton("Remove Selected Clause") self.delButton.clicked.connect(self.deleteClause) layout.addWidget(self.delButton) groupBox.setLayout(layout) return groupBox def buildWorkFrame(self): """Creates the grouped set of widgets that allow users to build basic Clause objects. """ groupBox = QGroupBox("Clause Workspace") layout = QHBoxLayout(groupBox) attributeCompleter = QCompleter(self.attributes) attributeCompleter.setCompletionMode(QCompleter.InlineCompletion) self.dropAttribute = DropLineEdit(self, self.mframe.agent.datatree, "", attributeCompleter) self.dropRelation = DropTextLabel("__") self.dropValue = FilterValueLineEdit(groupBox, self.mframe.agent.datatree, self.dropAttribute) # Clear dropValue when dropAttribute changes self.dropAttribute.textChanged.connect(self.dropValue.clear) # Enter in dropValue works like addButton self.dropValue.returnPressed.connect(self.addClause) self.addButton = QPushButton("Add", groupBox) self.addButton.clicked.connect(self.addClause) layout.addWidget(self.dropAttribute) layout.addItem(QSpacerItem(5,5)) layout.addWidget(self.dropRelation) layout.addItem(QSpacerItem(5,5)) layout.addWidget(self.dropValue) layout.addItem(QSpacerItem(5,5)) layout.addWidget(self.addButton) groupBox.setLayout(layout) return groupBox def buildRelationsWidget(self): """Creates the set of draggable relations. These relations are whatever is available in the relations dict of Table. """ relations_widget = QWidget() layout = QHBoxLayout(relations_widget) for relation in Table.relations: layout.addWidget(DragTextLabel(relation)) relations_widget.setLayout(layout) return relations_widget def addClause(self): """Adds a basic Clause to the current filter.""" if self.dropRelation.text() in Table.relations \ and len(self.dropValue.text()) > 0 \ and len(self.dropAttribute.text()) > 0: clause = Clause(self.dropRelation.text(), TableAttribute(self.dropAttribute.text()), self.dropValue.text()) # Guard double add if str(clause) not in self.clause_dict: self.clause_list.append(str(clause)) self.clause_dict[str(clause)] = clause self.clause_model.setStringList(self.clause_list) def deleteClause(self): """Removes the selected basic Clause objects from the current filter. """ clause = self.clause_model.data( self.list_view.selectedIndexes()[0], Qt.DisplayRole) if clause is not None and clause in self.clause_list: self.clause_list.remove(clause) del self.clause_dict[clause] self.clause_model.setStringList(self.clause_list)
def testSignals(self): self._called = False m = QStringListModel() m.rowsAboutToBeInserted[QModelIndex,int,int].connect(self.sigCallback) m.insertRows(0, 3) self.assert_(self._called)
class LiteListView(QListView): fileDropped = Signal(list) def __init__(self, parent=None): super(LiteListView, self).__init__(parent) # モデルの作成 self.model = QStringListModel() self.setModel(self.model) # D&D処理を許可 self.setAcceptDrops(True) def clearItems(self): self.model.setStringList([]) def addItems(self, itemlist): slist = [os.path.basename(p) for p in itemlist] self.model.setStringList(slist) def getItems(self): return self.model.stringList() # *************************************** # ドラッグアンドドロップのイベント処理 # *************************************** def dragEnterEvent(self, event): if event.mimeData().hasUrls: event.accept() else: event.ignore() def dragMoveEvent(self, event): if event.mimeData().hasUrls: event.setDropAction(Qt.CopyAction) event.accept() else: event.ignore() def dropEvent(self, event): if event.mimeData().hasUrls: event.setDropAction(Qt.CopyAction) # おまじない event.accept() # おまじない # ファイルの読み込み files = [unicode(u.toLocalFile()) for u in event.mimeData().urls()] self.clearItems() # Itemをクリア wav_files = [] # 各ファイルをアイテムに保存 for fname in files: root, ext = os.path.splitext(fname) # wavファイルを取得し、Itemを生成 if re.match(r"^\.(wav|WAV)$", ext, re.IGNORECASE): wav_files.append(fname) self.addItems(wav_files) # ドロップ処理終了のイベント発行 self.fileDropped.emit(wav_files) else: # おまじない event.ignore()
from PySide.QtCore import Qt, QPersistentModelIndex from PySide.QtGui import QStringListModel if __name__ == "__main__": stringListModel = QStringListModel(["one", "two"]) idx = stringListModel.index(1, 0) persistentModelIndex = QPersistentModelIndex(idx) stringListModel.data(persistentModelIndex, Qt.DisplayRole)
def _reinitializeFields(self, text): """Only one field is allowed to be added per dialog. If user wants to add another, erase the previous one he/she added""" self._items.pop(0) self._items.insert(0, text) self.combo_output_field.setModel(QStringListModel(self._items))