示例#1
0
class SearchDialog(QDialog):
    """
    SearchDialog class for the Financeager application.
    """
    def __init__(self, parent=None):
        """
        Loads the ui layout file. 
        Populates the model and does some layout adjustments. 
        
        :param      parent | FinanceagerWindow 
        """
        super(SearchDialog, self).__init__(parent)
        loadUi(__file__, self)

        self.__model = QStandardItemModel(self.tableView)
        # sorts model according to Item.data, Item.text
        self.__model.setSortRole(Qt.UserRole + 1)
        self.__model.setHorizontalHeaderLabels(
            ['Name', 'Value', 'Date', 'Category'])
        self.tableView.setModel(self.__model)
        self.__sortOrder = 1  #Descending order

        self.tableView.horizontalHeader().setResizeMode(QHeaderView.Stretch)
        self.tableView.adjustSize()
        self.setFixedSize(self.size())
        self.buttonBox.button(QDialogButtonBox.Ok).setDefault(False)
        # CONNECTIONS
        self.lineEdit.textEdited.connect(self.displaySearchResult)
        self.expendituresButton.clicked.connect(self.displaySearchResult)
        self.receiptsButton.clicked.connect(self.displaySearchResult)
        self.bothButton.clicked.connect(self.displaySearchResult)
        self.tableView.horizontalHeader().sectionClicked.connect(
            self.sortByColumn)
        self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.close)

    def keyPressEvent(self, event):
        """
        Reimplementation. 
        Avoids triggering the OK button when pressing Enter. Considered a
        common reaction when searching for stuff.
        Unchecks the action_Search of the MainWindow if Esc pressed.
        """
        if event.key() == Qt.Key_Enter:
            return
        elif event.key() == Qt.Key_Escape:
            self.parentWidget().action_Search.setChecked(False)
        super(SearchDialog, self).keyPressEvent(event)

    def closeEvent(self, event):
        """ Reimplementation. Unchecks the action_Search of the MainWindow. """
        self.parentWidget().action_Search.setChecked(False)
        event.accept()

    def displaySearchResult(self, pattern=None):
        """
        Searches for the pattern given by the user in all months of the current
        year. If specified, only the respective expenditures or receipts are
        scanned. 
        If a match is found, new items are cloned and appended to the table.

        :param      pattern | QString emitted by QLineEdit.textChanged signal
                              or bool emitted by QRadioButton.clicked signal
                              or None if called from a BalanceModel (resp.
                              FinanceagerWindow.updateSearchDialog())
        """
        if type(pattern) is bool or pattern is None:
            pattern = self.lineEdit.text()
        pattern = unicode(pattern)
        self.__model.clear()
        self.__model.setHorizontalHeaderLabels(
            ['Name', 'Value', 'Date', 'Category'])
        self.setWindowTitle('Search for \'%s\'' % pattern)
        if not len(pattern):
            self.__model.setItem(0, 0, ResultItem('No pattern specified.'))
            return
        pattern = pattern.upper()
        monthsTabWidget = self.parent().monthsTabWidget
        for m in range(12):
            if self.expendituresButton.isChecked():
                modelList = [monthsTabWidget.widget(m).expendituresModel()]
            elif self.receiptsButton.isChecked():
                modelList = [monthsTabWidget.widget(m).receiptsModel()]
            elif self.bothButton.isChecked():
                modelList = [
                    monthsTabWidget.widget(m).expendituresModel(),
                    monthsTabWidget.widget(m).receiptsModel()
                ]
            for model in modelList:
                for r in range(model.rowCount()):
                    category = model.item(r)
                    for e in range(category.rowCount()):
                        entry = category.child(e)
                        name = unicode(entry.text())
                        if name.upper().find(pattern) > -1:
                            value = category.child(e, 1).value()
                            date = category.child(e, 2).data()
                            self.__model.appendRow([
                                ResultItem(name),
                                ResultItem(value),
                                ResultItem(date),
                                ResultItem(category.text())
                            ])
        if not self.__model.hasChildren():
            self.__model.setItem(0, 0, ResultItem('No match found.'))

    def sortByColumn(self, col):
        """
        Called when a section of the horizontalHeader of the model is clicked.
        Toggles the sortOrder from descending to ascending and vice versa. 
        Finally the respective column is sorted. 

        :param      col | int 
        """
        self.__sortOrder = not self.__sortOrder
        self.__model.sort(col, self.__sortOrder)