Пример #1
0
    def __init__(self, *args, **kwargs):

        super(Widget_referenceFiles, self).__init__(*args, **kwargs)
        self.installEventFilter(self)
        mainLayout = QVBoxLayout(self)
        mainLayout.setContentsMargins(0, 0, 0, 0)
        mainLayout.setSpacing(8)

        treeWidget = QTreeWidget()
        headerItem = treeWidget.headerItem()
        checkBox_allItems = QCheckBox(treeWidget)
        checkBox_allItems.setFixedWidth(20)
        checkBox_allItems.setChecked(True)
        checkBox_allItems.setStyleSheet("margin: 6px 6px")
        treeWidget.setItemWidget(headerItem, 0, checkBox_allItems)
        headerItem.setText(0, "")
        headerItem.setText(1, "Reference File Name")
        treeWidget.setRootIsDecorated(False)
        treeWidget.setStyleSheet(
            "QTreeWidget::item { border-left: 1px solid gray;border-bottom: 1px solid gray; padding: 3px}\
                                 QTreeWidget{ font-size:13px;}")
        treeWidget.header().setStyleSheet("font-size:12px;")
        treeWidget.setColumnWidth(0, 22)

        w_buttons = QWidget()
        lay_buttons = QHBoxLayout(w_buttons)
        lay_buttons.setContentsMargins(0, 0, 0, 0)
        buttonReference = QPushButton("REFERENCE")
        buttonCleanExceptSelected = QPushButton("CLEAN EXCEPT SELECTED")
        lay_buttons.addWidget(buttonCleanExceptSelected)
        lay_buttons.addWidget(buttonReference)

        mainLayout.addWidget(treeWidget)
        mainLayout.addWidget(w_buttons)

        self.treeWidget = treeWidget

        self.treeWidget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.treeWidget.checkBox_allItems = checkBox_allItems

        checkBox_allItems.stateChanged.connect(self.cmd_setCheckAsset)
        treeWidget.itemPressed.connect(self.cmd_selectItems)
        buttonReference.clicked.connect(self.referenceFiles)
        buttonCleanExceptSelected.clicked.connect(self.cmd_cleanScene)

        self.cmd_loadList()
Пример #2
0
class PushupList(QWidget):
    '''
    classdocs
    '''

    deletePushup = Signal(int)
    deletePushups_in_a_day = Signal(tuple)

    def __init__(self, pushups):
        '''
        Constructor
        '''
        QWidget.__init__(self)

        self.pushups = pushups
        self.createGUI()

    def createGUI(self):
        self.layout = QVBoxLayout()
        # self.pushupsListWidget = QListWidget(self)
        self.pushupsListWidget = QTreeWidget(self)

        self.pushupsListWidget.setMinimumHeight(250)
        #self.pushupsListWidget.setMaximumWidth(500)
        self.pushupsListWidget.setAlternatingRowColors(True)

        self.pushupsListWidget.doubleClicked.connect(self.doubleClick_Test)

        self.pushupsListWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.pushupsListWidget.customContextMenuRequested.connect(
            self._customMenu)

        self._populateTree()

        self.layout.addWidget(self.pushupsListWidget)

        self.setLayout(self.layout)

    # Slot
    def _customMenu(self):
        selectedItems = self.pushupsListWidget.selectedItems()

        if selectedItems is not None:
            selectedItem = selectedItems[0]

            if selectedItem.parent() is not None:  # Child Item selected
                menu = QMenu()

                delete = QAction(self.pushupsListWidget)
                delete.setText("Delete this pushup")
                delete.triggered.connect(self._emitDeleteSignal)
                menu.addAction(delete)
                menu.exec_(QCursor.pos())
            else:  # Top level Item selected
                menu = QMenu()

                delete = QAction(self.pushupsListWidget)
                delete.setText("Delete this day and all of its exercises")
                delete.triggered.connect(self._emitDeleteDaySignal)
                menu.addAction(delete)
                menu.exec_(QCursor.pos())

    def _emitDeleteSignal(self):
        selectedItem = self.pushupsListWidget.selectedItems()[0]
        pushupId = selectedItem.data(0, Qt.UserRole)._id

        self.deletePushup.emit(pushupId)

    def _emitDeleteDaySignal(self):
        selectedItem = self.pushupsListWidget.selectedItems()[0]

        treeWidgetItems = selectedItem.takeChildren()

        pushupsIdList = []
        for item in treeWidgetItems:
            pushup = item.data(0, Qt.UserRole)._id
            pushupsIdList.append(pushup)

        self.deletePushups_in_a_day.emit(pushupsIdList)

    def _populateTree(self):
        self.pushupsListWidget.clear()
        self.pushupsListWidget.setColumnCount(4)
        self.pushupsListWidget.setHeaderLabels([
            "Date", "TotalPushups", "Series", "Repetitions",
            "Average Heart Rate"
        ])
        self.pushupsListWidget.setSortingEnabled(True)
        self.pushupsListWidget.setColumnWidth(0, 180)
        self.pushupsListWidget.setColumnWidth(4, 150)

        pushupDict = self._getPushupDictionary()

        for it, dayOfExercise in enumerate(sorted(pushupDict.keys())):

            dateItem = QTreeWidgetItem()

            dayLabel = dayOfExercise.strftime("%Y/%m/%d")

            dateItem.setText(0, "\n" + dayLabel + "\nDay : " + str(it))

            self.pushupsListWidget.addTopLevelItem(dateItem)

            totalPushups = 0
            for pushup in pushupDict[dayOfExercise]:
                pushupItem = QTreeWidgetItem()

                pushupItem.setText(2, "#" + str(pushup._series))
                pushupItem.setText(3, str(pushup._repetitions))
                pushupItem.setText(4, str(pushup._averageHeartRate))
                pushupItem.setData(0, Qt.UserRole, pushup)

                totalPushups = totalPushups + pushup._repetitions

                dateItem.addChild(pushupItem)

            dateItem.setText(1, str(totalPushups))

    def doubleClick_Test(self):
        selectedItems = self.pushupsListWidget.selectedItems()

        if selectedItems is not None:
            selectedItem = selectedItems[0]

            if selectedItem.parent() is not None:  # Child Item selected
                selectedPushups = self.pushupsListWidget.selectedItems(
                )[0].data(0, Qt.UserRole)
                print selectedPushups._id
            else:
                print "Top level widget double clicked"

    def reloadPushupsList(self, pushups):
        self.pushups = pushups
        self._populateTree()

    def _populateListWidget(self):
        ''' 
        unused old method
        '''

        self.pushupsListWidget.clear()

        pushupDict = self._getPushupDictionary()

        for dayOfExercise in pushupDict:
            listItemString = "Date : " + dayOfExercise + "\n"
            listItem_Data = []

            for pushup in pushupDict[dayOfExercise]:
                listItemString += "Series : " + str(pushup._series) + \
                                  " Repetition : " + str(pushup._repetitions) + "\n"
                listItem_Data.append(pushup)

            listItem = QListWidgetItem(listItemString)
            listItem.setData(Qt.UserRole, listItem_Data)

            self.pushupsListWidget.addItem(listItem)

    def _getPushupDictionary(self):
        '''
        Returns a dictionary with the following structure : 
        - Key : date of the exercises. Type datetime.date
        - Value : list containing pushups made that day . Type : [Pushup model object]    
        
        example : 
        {
            2014-08-18: [pushupModelObj1, pushupModelObj2, pushupModelObj3],
            2014-08-19: [pushupModelObj4, pushupModelObj5, pushupModelObj6]
        } 
        '''
        pushupDateList = {}  # dictionary initialization

        for pushup in self.pushups:
            if not pushupDateList.has_key(pushup._date):
                pushupsList = [pushup]
                pushupDateList[pushup._date] = pushupsList
            else:
                pushupDateList[pushup._date].append(pushup)

#         for k in pushupDateList.keys():
#             print k
#
#             for pu in pushupDateList[k]:
#                 print pu

        return pushupDateList
Пример #3
0
class PushupList(QWidget):
    '''
    classdocs
    ''' 
    
    deletePushup = Signal(int)
    deletePushups_in_a_day = Signal(tuple)
    
    def __init__(self, pushups):
        '''
        Constructor
        '''
        QWidget.__init__(self)
        
        self.pushups = pushups
        self.createGUI()
    
    def createGUI(self):
        self.layout = QVBoxLayout()
        # self.pushupsListWidget = QListWidget(self)
        self.pushupsListWidget = QTreeWidget(self)
        
        self.pushupsListWidget.setMinimumHeight(250)        
        #self.pushupsListWidget.setMaximumWidth(500)
        self.pushupsListWidget.setAlternatingRowColors(True)
        
        self.pushupsListWidget.doubleClicked.connect(self.doubleClick_Test)
        
        self.pushupsListWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.pushupsListWidget.customContextMenuRequested.connect(self._customMenu)
        
        self._populateTree()
        
        self.layout.addWidget(self.pushupsListWidget)
        
        self.setLayout(self.layout)   
    
    # Slot
    def _customMenu(self):
        selectedItems = self.pushupsListWidget.selectedItems()
        
        if selectedItems is not None :
            selectedItem = selectedItems[0] 
            
            if selectedItem.parent() is not None : # Child Item selected
                menu = QMenu()
                
                delete = QAction(self.pushupsListWidget)
                delete.setText("Delete this pushup")
                delete.triggered.connect(self._emitDeleteSignal)
                menu.addAction(delete)
                menu.exec_(QCursor.pos())
            else : # Top level Item selected
                menu = QMenu()
             
                delete = QAction(self.pushupsListWidget)
                delete.setText("Delete this day and all of its exercises")
                delete.triggered.connect(self._emitDeleteDaySignal)
                menu.addAction(delete)
                menu.exec_(QCursor.pos())
    
    def _emitDeleteSignal(self):
        selectedItem = self.pushupsListWidget.selectedItems()[0]
        pushupId = selectedItem.data(0, Qt.UserRole)._id
        
        self.deletePushup.emit(pushupId)
    
    def _emitDeleteDaySignal(self):
        selectedItem = self.pushupsListWidget.selectedItems()[0]
        
        treeWidgetItems = selectedItem.takeChildren()
        
        pushupsIdList = []
        for item in treeWidgetItems:
            pushup = item.data(0, Qt.UserRole)._id
            pushupsIdList.append(pushup)
            
        self.deletePushups_in_a_day.emit(pushupsIdList)

    def _populateTree(self):
        self.pushupsListWidget.clear()
        self.pushupsListWidget.setColumnCount(4)
        self.pushupsListWidget.setHeaderLabels(["Date", "TotalPushups", 
                                                "Series", "Repetitions",
                                                "Average Heart Rate"])
        self.pushupsListWidget.setSortingEnabled(True)
        self.pushupsListWidget.setColumnWidth(0, 180)
        self.pushupsListWidget.setColumnWidth(4, 150)
        
        pushupDict = self._getPushupDictionary()
        
        for it, dayOfExercise in enumerate(sorted(pushupDict.keys())):                  
             
            dateItem = QTreeWidgetItem()
            
            dayLabel = dayOfExercise.strftime("%Y/%m/%d")
            
            dateItem.setText(0, "\n" + dayLabel + "\nDay : " + str(it))
            
            self.pushupsListWidget.addTopLevelItem(dateItem)
            
            totalPushups = 0
            for pushup in pushupDict[dayOfExercise]:
                pushupItem = QTreeWidgetItem()
                
                pushupItem.setText(2, "#" + str(pushup._series))
                pushupItem.setText(3, str(pushup._repetitions))
                pushupItem.setText(4, str(pushup._averageHeartRate))
                pushupItem.setData(0, Qt.UserRole, pushup)
                
                totalPushups = totalPushups + pushup._repetitions 
                
                dateItem.addChild(pushupItem)  
            
            dateItem.setText(1, str(totalPushups))
                 
                
    def doubleClick_Test(self):
        selectedItems = self.pushupsListWidget.selectedItems()
        
        if selectedItems is not None :
            selectedItem = selectedItems[0] 
            
            if selectedItem.parent() is not None : # Child Item selected
                selectedPushups = self.pushupsListWidget.selectedItems()[0].data(0, Qt.UserRole)
                print selectedPushups._id    
            else :
                print "Top level widget double clicked"                
        
    def reloadPushupsList(self, pushups):
        self.pushups = pushups
        self._populateTree()
        
    def _populateListWidget(self):
        ''' 
        unused old method
        '''
        
        self.pushupsListWidget.clear()
        
        pushupDict = self._getPushupDictionary()
        
        for dayOfExercise in pushupDict:                  
            listItemString = "Date : " + dayOfExercise + "\n"
            listItem_Data = []
            
            for pushup in pushupDict[dayOfExercise]:
                listItemString += "Series : " + str(pushup._series) + \
                                  " Repetition : " + str(pushup._repetitions) + "\n"
                listItem_Data.append(pushup)
                             
            listItem = QListWidgetItem(listItemString)
            listItem.setData(Qt.UserRole, listItem_Data)
            
            self.pushupsListWidget.addItem(listItem)        
            
    def _getPushupDictionary(self):
        '''
        Returns a dictionary with the following structure : 
        - Key : date of the exercises. Type datetime.date
        - Value : list containing pushups made that day . Type : [Pushup model object]    
        
        example : 
        {
            2014-08-18: [pushupModelObj1, pushupModelObj2, pushupModelObj3],
            2014-08-19: [pushupModelObj4, pushupModelObj5, pushupModelObj6]
        } 
        '''
        pushupDateList = {} # dictionary initialization
        
        for pushup in self.pushups:
            if not pushupDateList.has_key(pushup._date):
                pushupsList = [pushup]
                pushupDateList[pushup._date] = pushupsList
            else:
                pushupDateList[pushup._date].append(pushup)
                 
#         for k in pushupDateList.keys():
#             print k
#             
#             for pu in pushupDateList[k]:
#                 print pu
         
        return pushupDateList    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
Пример #4
0
class CustomWidget(QtGui.QMainWindow):
    def __init__(self):
        """
        Constructor
        """
        QtGui.QMainWindow.__init__(self)
        self.name = "Custom widget"
        self.central_widget = QtGui.QWidget()
        self.setCentralWidget(self.central_widget)

        # TODO: This is ugly, improve it
        self.iconp = JConfig().icons_path

        self._createLayout()

    def _createGui(self):
        """
        Subclasses must override this
        depending on the elements they want to add
        self._createOutputTree(),
        self._createOutputTable(),
        self._createOutputWindow() and add them to
        the corresponding layouts.
        """
        raise NotImplementedError

    def _createToolBar(self, name):
        """
        Subclasses need to define the
        specific Actions
        """
        self.toolbar = self.addToolBar(name)
        self.toolbar.setMovable(False)

    def _createLayout(self):
        """
        This creates the basic layout:
        Buttons & Outputs
        """

        # Layouts (This is a common disposition)
        main_layout = QtGui.QVBoxLayout()
        self.button_layout = QtGui.QHBoxLayout()
        output_layout = QtGui.QVBoxLayout()

        # You will need to create your buttons
        # and add them to your layout like this:
        # self.button_layout.addWidget(button_1)

        # Output Layout Inner (QSplitter)
        # Add as many widgets as you please
        # They will be ordered vertically and
        # be resizable by the user
        # self.splitter.addWidget(self.table_label)
        # self.splitter.addWidget(...)
        self.splitter = QSplitter(QtCore.Qt.Vertical)

        # Nested layouts
        main_layout.addLayout(self.button_layout)
        output_layout.addWidget(self.splitter)
        main_layout.addLayout(output_layout)
        self.central_widget.setLayout(main_layout)

    def _createOutputWindow(self):
        """
        Some binary analysis commands will output to this.
        """

        self.output_label = QtGui.QLabel('Output')

        self.output_window = QTextEdit()
        self.output_window.setFontPointSize(10)
        self.output_window.setReadOnly(True)
        # Save it for later use
        self.output_window.original_textcolor = self.output_window.textColor()

    def _createOutputTable(self):
        """
        A vanilla QTableWidget. Callbacks modify
        its properties, like number of columns, etc.
        """
        self.table_label = QtGui.QLabel('Table Output')

        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setColumnWidth(0, 100)
        self.table.setColumnWidth(1, 300)
        self.table.setColumnWidth(2, 300)

        self.table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

        # Connect signals to slots
        self.table.customContextMenuRequested.connect(self._tablePopup)
        self.table.horizontalHeader().sectionDoubleClicked.connect(
            self._tableHeaderDoubleClicked)
        self.table.cellDoubleClicked.connect(self._tableCellDoubleClicked)

    def _createOutputTree(self):
        """
        A QtreeWidget. Initially used to display those pesky
        dword comparison to immediate values.
        """
        self.tree_label = QtGui.QLabel('Tree Output')

        self.tree = QTreeWidget()
        self.tree.setColumnCount(3)
        self.tree.setColumnWidth(0, 150)
        self.tree.setColumnWidth(1, 150)
        self.tree.setColumnWidth(2, 50)

        # Connect signals to slots
        self.tree.itemDoubleClicked.connect(self._treeElementDoubleClicked)

    #################################################################
    # GUI Callbacks
    #################################################################
    def _console_output(self, s="", err=False):
        """
        Convenience wrapper
        """
        if err:
            # Error message
            err_color = QColor('red')
            self.output_window.setTextColor(err_color)
            self.output_window.append(s)
            # restore original color
            self.output_window.setTextColor(
                self.output_window.original_textcolor)

        else:
            self.output_window.append(s)

    def _tableCellDoubleClicked(self, row, col):
        """
        Most of the info displayed in QTableWidgets represent addresses.
        Default action: try to jump to it.
        """
        it = self.table.item(row, col).text()

        try:
            addr = int(it, 16)
            jump_to_address(addr)

        except ValueError:
            self._console_output("[!] That does not look like an address...",
                                 err=True)
            return

    def _tablePopup(self, pos):
        """
        Popup menu activated clicking the secondary
        button on the table
        """
        menu = QtGui.QMenu()

        # Add menu entries
        delRow = menu.addAction(QIcon(self.iconp + "close.png"), "Delete Row")
        selItem = menu.addAction(QIcon(self.iconp + "bookmark.png"),
                                 "Mark entry")
        menu.addSeparator()
        origFunc = menu.addAction(QIcon(self.iconp + "lightning.png"),
                                  "Select origin function")
        destFunc = menu.addAction(QIcon(self.iconp + "flag.png"),
                                  "Select destination function")

        # Get entry clicked
        action = menu.exec_(self.mapToGlobal(pos))

        # Dispatch :)
        if action == delRow:
            self.table.removeRow(self.table.currentRow())

        elif action == selItem:
            self.table.currentItem().setBackground(QtGui.QColor('red'))

        elif action == origFunc:
            try:
                addr = self.table.currentItem().text()
                InfoUI.function_orig_ea = int(addr, 16)

            except:
                self._console_output("This does not look like an address...",
                                     err=True)

        elif action == destFunc:
            try:
                addr = self.table.currentItem().text()
                InfoUI.function_dest_ea = int(addr, 16)

            except:
                self._console_output("This does not look like an address...",
                                     err=True)

    def _tableHeaderDoubleClicked(self, index):
        """
        Used to sort the contents
        """
        self.table.sortItems(index, order=QtCore.Qt.AscendingOrder)

    def _treeElementDoubleClicked(self, item, column):
        """
        QTreeWidgetElement callback. Basically it jumps to
        the selected address in IDA disassembly window.
        """
        try:
            # Only interested in addresses
            addr_int = int(item.text(column), 16)
            jump_to_address(addr_int)
            # Paint some color
            item.setBackground(column, QtGui.QColor('green'))

        except:
            self._console_output("[!] That does not look like an address...",
                                 err=True)
Пример #5
0
class DirectoryDetectWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle('Directory Detective Tool')
        main_layout = QVBoxLayout()

        path_layout = self._init_path_layout()
        guide_layout = self._init_guide_layout()
        detail_layout = self._init_detail_layout()

        main_layout.addLayout(path_layout)
        main_layout.addLayout(guide_layout)
        main_layout.addLayout(detail_layout)
        self.setLayout(main_layout)
        self.setGeometry(300, 300, 400, 350)
        self._connect()

        self._walk_folder = None
        self._last_path = None
        self.directory_info = None
        self._button_list = list()
        self._last_info = None

    def _init_path_layout(self):
        path_layout = QHBoxLayout()
        self.input_path = QLineEdit(self)
        self.input_path.setFixedHeight(35)
        self.input_path.setPlaceholderText('Type search path here')
        self.button_path = QPushButton('Scan', self)
        self.button_path.setFixedHeight(35)
        self.button_path.setFocus()

        path_layout.addWidget(QLabel('Path:', self))
        path_layout.addWidget(self.input_path, stretch=True)
        path_layout.addWidget(self.button_path)
        return path_layout

    def _init_guide_layout(self):
        self.guide_layout = QHBoxLayout()
        self.guide_layout.setAlignment(Qt.AlignLeft)
        return self.guide_layout

    def refresh_trees(self, store_list, ignore_list):
        self._refresh_key_tree(store_list, ignore_list=ignore_list)
        self._refresh_value_tree(store_list)

    def add_button(self, name, store_list, ignore_list=None):
        button = QPushButton(name)
        button.setFixedSize(60, 35)
        item = (name, button, store_list, ignore_list)
        self._button_list.append(item)
        self.guide_layout.addWidget(button)
        self.refresh_trees(store_list=store_list, ignore_list=ignore_list)
        button.clicked.connect(lambda: self._set_button(item=item))

    def _set_button(self, item):
        index_item = self._button_list.index(item)

        if len(self._button_list) > index_item + 1:
            for name, button, store_list, ignore_list in self._button_list[index_item + 1:]:
                button.setParent(None)

        name, button, store_list, ignore_list = item
        self.refresh_trees(store_list=store_list, ignore_list=ignore_list)

    def _init_detail_layout(self):
        detail_layout = QGridLayout()
        self.key_tree = QTreeWidget()
        self.key_tree.setColumnCount(2)
        self.key_tree.setColumnWidth(0, 200)
        self.key_tree.setHeaderLabels(['Key', 'Size'])

        self.value_tree = QTreeWidget()
        self.value_tree.setColumnCount(2)
        self.value_tree.setColumnWidth(0, 200)
        self.value_tree.setHeaderLabels(['Path', 'Size'])

        detail_layout.setColumnStretch(0, 1)
        detail_layout.setColumnStretch(1, 1)
        detail_layout.addWidget(self.value_tree)
        detail_layout.addWidget(self.key_tree)
        return detail_layout

    def _connect(self):
        self.button_path.clicked.connect(self.button_path_clicked)
        self.key_tree.doubleClicked.connect(self.key_tree_double_clicked)

    def button_path_clicked(self):
        del self._button_list[:]
        for _ in range(self.guide_layout.count()):
            current_item = self.guide_layout.takeAt(0)
            current_item.widget().setParent(None)

        path = unicode.encode(self.input_path.text())
        if self._last_path != path:
            self._walk_folder = walk_folder.run(path=path)

        max_level = 4
        self.directory_info = list(self._walk_folder.get_children_by_level(level=max_level))
        self.add_button('/', self.directory_info)

    def key_tree_double_clicked(self, selected_index=QModelIndex()):
        select_data = selected_index.data()
        ignore_list = [select_data]
        for item in self._button_list[1:]:
            ignore_list.append(item[0])

        store_dict = dict(self._last_info.get_children_by_key(key=select_data, ignore_list=ignore_list).sort_dictionary)
        store_list = list()

        for item in store_dict.values():
            store_list.extend(item['children'])

        store_list = list(set(store_list))
        self.add_button(select_data, store_list or list(), ignore_list=ignore_list)

    def _get_size(self, size):
        return '{} <> {}%'.format(human_size(size), round(size * 100 / self._walk_folder.total_size, 2))

    def _refresh_key_tree(self, directory_info, ignore_list=None):
        info = LabelInfo(make_dictionary_by_classification(directory_info, ignore_list))

        # Clear
        for _ in range(self.key_tree.topLevelItemCount()):
            self.key_tree.takeTopLevelItem(0)

        # Add
        for k, v in info.sort_dictionary:
            tree_widget = QTreeWidgetItem()
            tree_widget.setText(0, k)
            total_size = 0
            for child in v['children']:
                total_size += child.total_size
            tree_widget.setText(1, self._get_size(v[constant.sort_size_name]))
            self.key_tree.addTopLevelItem(tree_widget)
        self._last_info = info

    def _refresh_value_tree(self, directory_info):
        info = sorted(directory_info, key=lambda x: x.total_size, reverse=True)

        # Clear
        for _ in range(self.value_tree.topLevelItemCount()):
            self.value_tree.takeTopLevelItem(0)

        # Add
        for item in info:
            tree_widget = QTreeWidgetItem()
            tree_widget.setText(0, item.part_path)
            tree_widget.setText(1, self._get_size(item.total_size))
            self.value_tree.addTopLevelItem(tree_widget)
Пример #6
0
class CustomWidget(QtGui.QMainWindow):

    def __init__(self):
        """
        Constructor
        """
        QtGui.QMainWindow.__init__(self)
        self.name = "Custom widget"
        self.central_widget = QtGui.QWidget()
        self.setCentralWidget(self.central_widget)

        # TODO: This is ugly, improve it
        self.iconp = JConfig().icons_path

        self._createLayout()


    def _createGui(self):
        """
        Subclasses must override this
        depending on the elements they want to add
        self._createOutputTree(),
        self._createOutputTable(),
        self._createOutputWindow() and add them to
        the corresponding layouts.
        """
        raise NotImplementedError


    def _createToolBar(self, name):
        """
        Subclasses need to define the
        specific Actions
        """
        self.toolbar = self.addToolBar(name)
        self.toolbar.setMovable(False)


    def _createLayout(self):
        """
        This creates the basic layout:
        Buttons & Outputs
        """

        # Layouts (This is a common disposition)
        main_layout = QtGui.QVBoxLayout()
        self.button_layout = QtGui.QHBoxLayout()
        output_layout = QtGui.QVBoxLayout()

        # You will need to create your buttons
        # and add them to your layout like this:
        # self.button_layout.addWidget(button_1)

        # Output Layout Inner (QSplitter)
        # Add as many widgets as you please
        # They will be ordered vertically and
        # be resizable by the user
        # self.splitter.addWidget(self.table_label)
        # self.splitter.addWidget(...)
        self.splitter = QSplitter(QtCore.Qt.Vertical)

        # Nested layouts
        main_layout.addLayout(self.button_layout)
        output_layout.addWidget(self.splitter)
        main_layout.addLayout(output_layout)
        self.central_widget.setLayout(main_layout)


    def _createOutputWindow(self):
        """
        Some binary analysis commands will output to this.
        """

        self.output_label = QtGui.QLabel('Output')

        self.output_window = QTextEdit()
        self.output_window.setFontPointSize(10)
        self.output_window.setReadOnly(True)
        # Save it for later use
        self.output_window.original_textcolor = self.output_window.textColor()


    def _createOutputTable(self):
        """
        A vanilla QTableWidget. Callbacks modify
        its properties, like number of columns, etc.
        """
        self.table_label = QtGui.QLabel('Table Output')

        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setColumnWidth(0, 100)
        self.table.setColumnWidth(1, 300)
        self.table.setColumnWidth(2, 300)

        self.table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

        # Connect signals to slots
        self.table.customContextMenuRequested.connect(self._tablePopup)
        self.table.horizontalHeader().sectionDoubleClicked.connect(self._tableHeaderDoubleClicked)
        self.table.cellDoubleClicked.connect(self._tableCellDoubleClicked)


    def _createOutputTree(self):
        """
        A QtreeWidget. Initially used to display those pesky
        dword comparison to immediate values.
        """
        self.tree_label = QtGui.QLabel('Tree Output')

        self.tree = QTreeWidget()
        self.tree.setColumnCount(3)
        self.tree.setColumnWidth(0, 150)
        self.tree.setColumnWidth(1, 150)
        self.tree.setColumnWidth(2, 50)

        # Connect signals to slots
        self.tree.itemDoubleClicked.connect(self._treeElementDoubleClicked)



    #################################################################
    # GUI Callbacks
    #################################################################
    def _console_output(self, s = "", err = False):
        """
        Convenience wrapper
        """
        if err:
            # Error message
            err_color = QColor('red')
            self.output_window.setTextColor(err_color)
            self.output_window.append(s)
            # restore original color
            self.output_window.setTextColor(self.output_window.original_textcolor)

        else:
            self.output_window.append(s)


    def _tableCellDoubleClicked(self, row, col):
        """
        Most of the info displayed in QTableWidgets represent addresses.
        Default action: try to jump to it.
        """
        it = self.table.item(row, col).text()

        try:
            addr = int(it, 16)
            jump_to_address(addr)

        except ValueError:
            self._console_output("[!] That does not look like an address...", err = True)
            return


    def _tablePopup(self, pos):
        """
        Popup menu activated clicking the secondary
        button on the table
        """
        menu = QtGui.QMenu()

        # Add menu entries
        delRow = menu.addAction(QIcon(self.iconp + "close.png"), "Delete Row")
        selItem = menu.addAction(QIcon(self.iconp + "bookmark.png"), "Mark entry")
        menu.addSeparator()
        origFunc = menu.addAction(QIcon(self.iconp + "lightning.png"), "Select origin function")
        destFunc = menu.addAction(QIcon(self.iconp + "flag.png"), "Select destination function")

        # Get entry clicked
        action = menu.exec_(self.mapToGlobal(pos))

        # Dispatch :)
        if action == delRow:
            self.table.removeRow(self.table.currentRow())

        elif action == selItem:
            self.table.currentItem().setBackground(QtGui.QColor('red'))

        elif action == origFunc:
            try:
                addr = self.table.currentItem().text()
                InfoUI.function_orig_ea = int(addr, 16)

            except:
                self._console_output("This does not look like an address...", err = True)

        elif action == destFunc:
            try:
                addr = self.table.currentItem().text()
                InfoUI.function_dest_ea = int(addr, 16)

            except:
                self._console_output("This does not look like an address...", err = True)


    def _tableHeaderDoubleClicked(self, index):
        """
        Used to sort the contents
        """
        self.table.sortItems(index, order = QtCore.Qt.AscendingOrder)


    def _treeElementDoubleClicked(self, item, column):
        """
        QTreeWidgetElement callback. Basically it jumps to
        the selected address in IDA disassembly window.
        """
        try:
            # Only interested in addresses
            addr_int = int(item.text(column), 16)
            jump_to_address(addr_int)
            # Paint some color
            item.setBackground(column, QtGui.QColor('green'))

        except:
            self._console_output("[!] That does not look like an address...", err = True)