Source code for seriesmarker.gui.model.search.search_model

#==============================================================================
# -*- coding: utf-8 -*-
#
# Copyright (C) 2013 - 2016 Tobias Röttger <toroettg@gmail.com>
#
# This file is part of SeriesMarker.
#
# SeriesMarker is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# SeriesMarker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SeriesMarker.  If not, see <http://www.gnu.org/licenses/>.
#==============================================================================

from PySide.QtCore import QAbstractTableModel, QModelIndex, Qt
from seriesmarker.gui.model.search.search_node import SCALE_SIZE

import logging

logger = logging.getLogger(__name__)

[docs]class SearchModel(QAbstractTableModel): """This model is used to display search results in a :class:`.SearchDialog`."""
[docs] def __init__(self, parent=None): """Initializes the model. :param parent: The parent of the model. :type parent: :class:`.PySide.QtCore.QObject` """ super().__init__(parent) self._node_list = []
[docs] def node_at(self, index): """Returns the node at the given index of the model. :param index: The index to get the associated node from. :type index: :class:`~.PySide.QtCore.QModelIndex` .. todo:: The banner_loader may cause an access to an invalid index if another search with less results was initiated before all banner were loaded. Prevent the beginning of a new search before the last has been finished, or clear the banner_loader at clearing this model. Afterwards remove the warning log. Also remove the None check at setData of this model then. :returns: The :class:`.TreeNode` if a node is associated with the given index, otherwise None. """ if index.isValid(): try: return self._node_list[index.row()] except IndexError: logger.warning("Invalid index, probably started a new " "search before the last finished (banner loading).")
[docs] def add_node(self, node): """Appends a node to the end of the model. :param node: The node to add to the model. :type node: :class:`.SearchNode` """ self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount()) self._node_list.append(node) self.endInsertRows()
[docs] def clear(self): """Removes all nodes from the model.""" self.removeRows(0, self.rowCount())
[docs] def removeRows(self, position, rows, parent=QModelIndex()): """Removes a number of nodes from a given parent, beginning at a given position. :param position: The index to start removing nodes from. :type position: :class:`int` :param rows: The number of nodes to remove from the parent. :type rows: :class:`int` :param parent: The parent to remove the nodes from. :type parent: :class:`~.PySide.QtCore.QModelIndex` :returns: True if the nodes were successfully removed, otherwise False. :emphasis:`Overrides` :py:meth:`.QAbstractItemModel.removeRows` """ self.beginRemoveRows(parent, position, position + rows - 1) del self._node_list[position : position + rows] self.endRemoveRows() return True
[docs] def data(self, index, role=Qt.DisplayRole): """Returns the data under the given role from the model at a given index. :param index: The position of the model to get data from. :type index: :class:`~.PySide.QtCore.QModelIndex` :param role: Determines the kind of data to get from the model. :type role: :class:`int` :returns: The series name, at the given index, for :class:`PySide.QtCore.Qt.DisplayRole`. :returns: The :class:`.pytvdbapi.api.Show`, hold by the node at the given index, for :class:`PySide.QtCore.Qt.UserRole`. :returns: The :meth:`~DecoratedNode.decoration` of the node, at the given index, for :class:`PySide.QtCore.Qt.DecorationRole`. :returns: The desired column dimension, at the given index, for :class:`PySide.QtCore.Qt.SizeHintRole`. :emphasis:`Overrides` :py:meth:`.QAbstractItemModel.data` """ if index.isValid(): column = index.column() search_node = self.node_at(index) if role == Qt.DisplayRole: if column == 0: return search_node.show.SeriesName elif role == Qt.UserRole: return search_node.show elif role == Qt.DecorationRole: if column == 1: return search_node.decoration(index) elif role == Qt.SizeHintRole: if column == 1: return SCALE_SIZE return None
[docs] def setData(self, index, value, role=Qt.DecorationRole): """Sets the given value of the given role at the given index. This method is also whenever a banner was loaded to set the node's decoration to a :class:`.PySide.QtGui.Pixmap` and refresh the views afterwards. :param index: The position to set the value at. :type index: :class:`~.PySide.QtCore.QModelIndex` :param value: Value to be set at given index. :type value: :class:`.PySide.QtGui.Pixmap` :param role: Determines the kind of data to set for the item. :type role: :class:`int` :returns: True if successful, otherwise False. :emphasis:`Overrides` :py:meth:`.QAbstractItemModel.setData` """ node = self.node_at(index) if node is None or role != Qt.DecorationRole: return False node.banner_loaded(value) self.dataChanged.emit(index, index) return True
[docs] def rowCount(self, parent=QModelIndex()): """Returns the number of rows (nodes), currently added to the model. :param parent: The parent to return the number of rows for. :type parent: :class:`~.PySide.QtCore.QModelIndex` :returns: The number of :class:`.SearchNode` added to the model. :emphasis:`Overrides` :py:meth:`.QAbstractItemModel.rowCount` """ if parent.isValid(): return 0 else: return len(self._node_list)
[docs] def columnCount(self, parent=QModelIndex()): """Describes the number of columns the model is using. :param parent: The parent to return the number of columns for. :type parent: :class:`~.PySide.QtCore.QModelIndex` :returns: The number of columns. :emphasis:`Overrides` :py:meth:`.QAbstractItemModel.columnCount` """ if parent.isValid(): return 0 else: return 2