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)
class ModelAtrributesView(QListView): """ Custom QListView implementation that displays checkable model attributes. """ def __init__(self,parent=None,dataModel = None): QListView.__init__(self, parent) self._dataModel = dataModel self._selectedDisplayMapping = OrderedDict() self._modelDisplayMapping = OrderedDict() self._attrModel = QStandardItemModel(self) def dataModel(self): """ Returns the data model instance. """ return self._dataModel def setDataModel(self,dataModel): """ Sets the data model. Should be a callable class rather than the class. instance. """ if callable(dataModel): self._dataModel = dataModel else: self._dataModel = dataModel.__class__ def modelDisplayMapping(self): """ Returns the column name and display name collection. """ return self._modelDisplayMapping def setModelDisplayMapping(self, dataMapping): """ Sets the mapping dictionary for the table object """ if dataMapping != None: self._modelDisplayMapping=dataMapping def load(self, sort=False): """ Load the model's attributes into the list view. """ if self._dataModel == None: return try: self._loadAttrs(self._dataModel.displayMapping(), sort) except AttributeError: #Ignore error if model does not contain the displayMapping static method pass def load_mapping(self, mapping, sort=False): """ Load collection containing column name and corresponding display name. """ self._modelDisplayMapping = mapping self._loadAttrs(mapping, sort) def sort(self): """ Sorts display name in ascending order. """ self._attrModel.sort(0) def _loadAttrs(self, attrMapping, sort=False): """ Loads display mapping into the list view. Specify to sort display names in ascending order once items have been added to the model. """ self._attrModel.clear() self._attrModel.setColumnCount(2) for attrName,displayName in attrMapping.iteritems(): #Exclude row ID in the list, other unique identifier attributes in the model can be used if attrName != "id": displayNameItem = QStandardItem(displayName) displayNameItem.setCheckable(True) attrNameItem = QStandardItem(attrName) self._attrModel.appendRow([displayNameItem,attrNameItem]) self.setModel(self._attrModel) if sort: self._attrModel.sort(0) def selectedMappings(self): """ Return a dictionary of field names and their corresponding display values. """ selectedAttrs = {} for i in range(self._attrModel.rowCount()): displayNameItem = self._attrModel.item(i,0) if displayNameItem.checkState() == Qt.Checked: attrNameItem = self._attrModel.item(i,1) selectedAttrs[attrNameItem.text()] = displayNameItem.text() return selectedAttrs
class ModelAtrributesView(QListView): """ Custom QListView implementation that displays checkable model attributes. """ def __init__(self,parent=None,dataModel = None): QListView.__init__(self, parent) self._dataModel = dataModel self._selectedDisplayMapping = OrderedDict() self._modelDisplayMapping = OrderedDict() self._attrModel = QStandardItemModel(self) def dataModel(self): """ Returns the data model instance. """ return self._dataModel def setDataModel(self,dataModel): """ Sets the data model. Should be a callable class rather than the class. instance. """ if callable(dataModel): self._dataModel = dataModel else: self._dataModel = dataModel.__class__ def modelDisplayMapping(self): """ Returns the column name and display name collection. """ return self._modelDisplayMapping def setModelDisplayMapping(self, dataMapping): """ Sets the mapping dictionary for the table object """ if dataMapping != None: self._modelDisplayMapping=dataMapping def load(self, sort=False): """ Load the model's attributes into the list view. """ if self._dataModel == None: return try: self._loadAttrs(self._dataModel.displayMapping(), sort) except AttributeError: # Ignore error if model does not contain # the displayMapping static method pass def load_mapping(self, mapping, sort=False): """ Load collection containing column name and corresponding display name. """ self._modelDisplayMapping = mapping self._loadAttrs(mapping, sort) def sort(self): """ Sorts display name in ascending order. """ self._attrModel.sort(0) def _loadAttrs(self, attrMapping, sort=False): """ Loads display mapping into the list view. Specify to sort display names in ascending order once items have been added to the model. """ self._attrModel.clear() self._attrModel.setColumnCount(2) for attrName,displayName in attrMapping.iteritems(): #Exclude row ID in the list, other unique identifier attributes in the model can be used if attrName != "id": displayNameItem = QStandardItem(displayName) displayNameItem.setCheckable(True) attrNameItem = QStandardItem(attrName) self._attrModel.appendRow([displayNameItem,attrNameItem]) self.setModel(self._attrModel) if sort: self._attrModel.sort(0) def selectedMappings(self): """ Return a dictionary of field names and their corresponding display values. """ selectedAttrs = OrderedDict() for i in range(self._attrModel.rowCount()): displayNameItem = self._attrModel.item(i,0) if displayNameItem.checkState() == Qt.Checked: attrNameItem = self._attrModel.item(i,1) selectedAttrs[attrNameItem.text()] = displayNameItem.text() return selectedAttrs