예제 #1
0
class ListDialog(DwarfDialog):
    def __init__(self,
                 parent=None,
                 setup_list_cb=None,
                 setup_list_cb_args=None,
                 double_click_to_accept=False,
                 checkable=False):
        super(ListDialog, self).__init__(parent)

        self.right_click_handler = None

        layout = QVBoxLayout(self)
        self.list = DwarfListView()  # QListWidget()

        self.list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        if double_click_to_accept:
            self.list.doubleClicked.connect(self.accept)

        if setup_list_cb is not None:
            setup_list_cb(self.list, setup_list_cb_args)

        layout.addWidget(self.list)
        if checkable:
            buttons = QHBoxLayout()
            select_all = QPushButton('select all')
            select_all.clicked.connect(self.select_all)
            buttons.addWidget(select_all)
            unselect_all = QPushButton('unselect all')
            unselect_all.clicked.connect(self.unselect_all)
            buttons.addWidget(unselect_all)
            ok = QPushButton('ok')
            ok.clicked.connect(self.accept)
            buttons.addWidget(ok)
            cancel = QPushButton('cancel')
            cancel.clicked.connect(self.close)
            buttons.addWidget(cancel)
            layout.addLayout(buttons)

    def get_checked_items(self):
        ret = []
        for i in range(0, self.list.count()):
            item = self.list.item(i)
            if item.checkState() == Qt.Checked:
                ret.append(item)
        return ret

    def select_all(self):
        for i in range(0, self.list.count()):
            item = self.list.item(i)
            item.setCheckState(Qt.Checked)

    def unselect_all(self):
        for i in range(0, self.list.count()):
            item = self.list.item(i)
            item.setCheckState(Qt.Unchecked)

    def keyPressEvent(self, event):
        super(ListDialog, self).keyPressEvent(event)
        if event.key() == Qt.Key_Return:
            self.accept()

    @staticmethod
    def build_and_show(setup_list_cb,
                       setup_list_cb_args,
                       double_click_to_accept=False,
                       checkable=False):
        dialog = ListDialog(setup_list_cb=setup_list_cb,
                            setup_list_cb_args=setup_list_cb_args,
                            double_click_to_accept=double_click_to_accept,
                            checkable=checkable)
        if dialog.list.count() > 0:
            result = dialog.exec_()
            if checkable:
                if result == QDialog.Accepted:
                    checked_items = dialog.get_checked_items()
                else:
                    checked_items = []
                return result == QDialog.Accepted, checked_items

            return result == QDialog.Accepted, dialog.list.selectedItems()
        return None
예제 #2
0
class JavaTracePanel(QWidget):
    def __init__(self, app, *__args):
        super().__init__(app)
        self.app = app

        self.app.dwarf.onJavaTraceEvent.connect(self.on_event)
        self.app.dwarf.onEnumerateJavaClassesStart.connect(self.on_enumeration_start)
        self.app.dwarf.onEnumerateJavaClassesMatch.connect(self.on_enumeration_match)
        self.app.dwarf.onEnumerateJavaClassesComplete.connect(self.on_enumeration_complete)

        self.tracing = False
        self.trace_classes = []
        self.trace_depth = 0

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        self._record_icon = QIcon(utils.resource_path('assets/icons/record.png'))
        self._pause_icon = QIcon(utils.resource_path('assets/icons/pause.png'))
        self._stop_icon = QIcon(utils.resource_path('assets/icons/stop.png'))

        self._tool_bar = QToolBar()
        self._tool_bar.addAction('Start', self.start_trace)
        self._tool_bar.addAction('Pause', self.pause_trace)
        self._tool_bar.addAction('Stop', self.stop_trace)
        self._tool_bar.addSeparator()
        self._entries_lbl = QLabel('Entries: 0')
        self._entries_lbl.setStyleSheet('color: #ef5350;')
        self._entries_lbl.setContentsMargins(10, 0, 10, 2)
        self._entries_lbl.setAttribute(Qt.WA_TranslucentBackground, True) # keep this
        self._entries_lbl.setAlignment(Qt.AlignRight| Qt.AlignVCenter)
        self._entries_lbl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self._tool_bar.addWidget(self._entries_lbl)

        layout.addWidget(self._tool_bar)

        self.setup_splitter = QSplitter()
        self.events_list = JavaTraceView(self)
        self.events_list.setVisible(False)

        self.trace_list = DwarfListView()
        self.trace_list_model = QStandardItemModel(0, 1)
        self.trace_list_model.setHeaderData(0, Qt.Horizontal, 'Traced')
        self.trace_list.setModel(self.trace_list_model)

        self.trace_list.doubleClicked.connect(self.trace_list_double_click)

        self.class_list = DwarfListView()
        self.class_list_model = QStandardItemModel(0, 1)
        self.class_list_model.setHeaderData(0, Qt.Horizontal, 'Classes')
        self.class_list.setModel(self.class_list_model)

        self.class_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.class_list.customContextMenuRequested.connect(self.show_class_list_menu)
        self.class_list.doubleClicked.connect(self.class_list_double_click)

        self.current_class_search = ''

        bar = QScrollBar()
        bar.setFixedWidth(0)
        bar.setFixedHeight(0)
        self.trace_list.setHorizontalScrollBar(bar)
        bar = QScrollBar()
        bar.setFixedWidth(0)
        bar.setFixedHeight(0)
        self.class_list.setHorizontalScrollBar(bar)

        self.setup_splitter.addWidget(self.trace_list)
        self.setup_splitter.addWidget(self.class_list)

        layout.addWidget(self.setup_splitter)
        layout.addWidget(self.events_list)

        self.setLayout(layout)

    def class_list_double_click(self, item):
        item = self.class_list_model.itemFromIndex(item)
        try:
            if self.trace_classes.index(item.text()) >= 0:
                return
        except:
            pass
        self.trace_classes.append(item.text())
        self.trace_list_model.appendRow([QStandardItem(item.text())])
        self.trace_list_model.sort(0, Qt.AscendingOrder)

    def on_enumeration_start(self):
        self.class_list_model.setRowCount(0)

    def on_enumeration_match(self, java_class):
        try:
            if PREFIXED_CLASS.index(java_class) >= 0:
                try:
                    if self.trace_classes.index(java_class) >= 0:
                        return
                except:
                    pass
                self.trace_list_model.appendRow(QStandardItem(java_class))
                self.trace_classes.append(java_class)
        except:
            pass

        self.class_list_model.appendRow([QStandardItem(java_class)])

    def on_enumeration_complete(self):
        self.class_list_model.sort(0, Qt.AscendingOrder)
        self.trace_list_model.sort(0, Qt.AscendingOrder)

    def on_event(self, data):
        trace, event, clazz, data = data
        if trace == 'java_trace':
            self.events_list.add_event(
                {
                    'event': event,
                    'class': clazz,
                    'data': data.replace(',', ', ')
                }
            )
            self._entries_lbl.setText('Events: %d' % len(self.events_list.data))

    def pause_trace(self):
        self.app.dwarf.dwarf_api('stopJavaTracer')
        self.tracing = False

    def search(self):
        accept, input = InputDialog.input(self.app, hint='Search',
                                          input_content=self.current_class_search,
                                          placeholder='Search something...')
        if accept:
            self.current_class_search = input.lower()
            for i in range(0, self.class_list.count()):
                try:
                    if self.class_list.item(i).text().lower().index(self.current_class_search.lower()) >= 0:
                        self.class_list.setRowHidden(i, False)
                except:
                    self.class_list.setRowHidden(i, True)

    def show_class_list_menu(self, pos):
        menu = QMenu()
        search = menu.addAction('Search')
        action = menu.exec_(self.class_list.mapToGlobal(pos))
        if action:
            if action == search:
                self.search()

    def start_trace(self):
        self.app.dwarf.dwarf_api('startJavaTracer', [self.trace_classes])
        self.trace_depth = 0
        self.tracing = True
        self.setup_splitter.setVisible(False)
        self.events_list.setVisible(True)

    def stop_trace(self):
        self.app.dwarf.dwarf_api('stopJavaTracer')
        self.tracing = False
        self.setup_splitter.setVisible(True)
        self.events_list.setVisible(False)
        self.events_list.clear()

    def trace_list_double_click(self, item):
        try:
            index = self.trace_classes.index(item.text())
        except:
            return
        if index < 0:
            return
        self.trace_classes.pop(index)
        self.trace_list.takeItem(self.trace_list.row(item))

    def keyPressEvent(self, event):
        if event.modifiers() & Qt.ControlModifier:
            if event.key() == Qt.Key_F:
                self.search()
        super(JavaTracePanel, self).keyPressEvent(event)