Skip to content

Commit

Permalink
Merge pull request #16 from nucleic/item-views
Browse files Browse the repository at this point in the history
Item views
  • Loading branch information
sccolbert committed Apr 2, 2013
2 parents 963cee8 + 660c42c commit de0d8e3
Show file tree
Hide file tree
Showing 10 changed files with 1,079 additions and 331 deletions.
308 changes: 140 additions & 168 deletions enaml/qt/q_item_model_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,211 +5,165 @@
#
# The full license is in the file COPYING.txt, distributed with this software.
#------------------------------------------------------------------------------
from PyQt4.QtCore import Qt, QAbstractTableModel, QSize
from PyQt4.QtCore import Qt, QAbstractTableModel

from enaml.itemmodels.enums import Orientation
from enaml.widgets.item import ItemModel

from .q_resource_helpers import get_cached_qcolor, get_cached_qfont, get_cached_qicon
from .q_resource_helpers import (
get_cached_qcolor, get_cached_qfont, get_cached_qicon
)


#------------------------------------------------------------------------------
# Item Data Role Handlers
# Role Handlers
#------------------------------------------------------------------------------
def display_role_handler(model, row, column):
return model.data(row, column)
def _display_data(item):
return item.get_data()


def decoration_role_handler(model, row, column):
icon = model.icon(row, column)
if icon is not None:
tk = icon._tkdata
if tk is None:
tk = get_cached_qicon(icon)
return tk
def _edit_data(item):
return item.get_data()


def edit_role_handler(model, row, column):
return model.edit_data(row, column)
def _check_state(item):
return item.check_state


def tool_tip_role_handler(model, row, column):
return model.tool_tip(row, column)
def _tool_tip(item):
return item.tool_tip


def status_tip_role_handler(model, row, column):
return model.status_tip(row, column)
def _status_tip(item):
return item.status_tip


def font_role_handler(model, row, column):
font = model.font(row, column)
if font is not None:
tk = font._tkdata
if tk is None:
tk = get_cached_qfont(font)
return tk
def _background(item):
style = item.style
if style is not None:
color = style.background
if color is not None:
tk = color._tkdata
if tk is None:
tk = get_cached_qcolor(color)
return tk


def text_alignment_role_handler(model, row, column):
return Qt.Alignment(model.text_alignment(row, column))
def _foreground(item):
style = item.style
if style is not None:
color = style.foreground
if color is not None:
tk = color._tkdata
if tk is None:
tk = get_cached_qcolor(color)
return tk


def background_role_handler(model, row, column):
color = model.background(row, column)
if color is not None:
tk = color._tkdata
if tk is None:
tk = get_cached_qcolor(color)
return tk
def _font(item):
style = item.style
if style is not None:
font = style.font
if font is not None:
tk = font._tkdata
if tk is None:
tk = get_cached_qfont(font)
return tk


def foreground_role_handler(model, row, column):
color = model.foreground(row, column)
if color is not None:
tk = color._tkdata
if tk is None:
tk = get_cached_qcolor(color)
return tk
def _decoration(item):
style = item.style
if style is not None:
icon = style.icon
if icon is not None:
tk = icon._tkdata
if tk is None:
tk = get_cached_qicon(icon)
return tk


def check_state_role_handler(model, row, column):
state = model.check_state(row, column)
if state is not None:
return Qt.CheckState(state)
def _text_alignment(item):
style = item.style
if style is not None:
return style.text_alignment


def size_hint_role_handler(model, row, column):
size = model.size_hint(row, column)
if size is not None:
return QSize(*size)


ITEM_DATA_ROLE_HANDLERS = {
Qt.DisplayRole: display_role_handler,
Qt.DecorationRole: decoration_role_handler,
Qt.EditRole: edit_role_handler,
Qt.ToolTipRole: tool_tip_role_handler,
Qt.StatusTipRole: status_tip_role_handler,
Qt.FontRole: font_role_handler,
Qt.TextAlignmentRole: text_alignment_role_handler,
Qt.BackgroundRole: background_role_handler,
Qt.ForegroundRole: foreground_role_handler,
Qt.CheckStateRole: check_state_role_handler,
Qt.SizeHintRole: size_hint_role_handler,
}


def set_edit_role_handler(model, row, column, value):
return model.set_data(row, column, value)


def set_check_state_role_handler(model, row, column, value):
return model.set_check_state(row, column, value)


ITEM_DATA_SET_ROLE_HANDLERS = {
Qt.EditRole: set_edit_role_handler,
Qt.CheckStateRole: set_check_state_role_handler,
ROLE_HANDLERS = {
Qt.DisplayRole: _display_data,
Qt.EditRole: _edit_data,
Qt.CheckStateRole: _check_state,
Qt.ToolTipRole: _tool_tip,
Qt.StatusTipRole: _status_tip,
Qt.BackgroundRole: _background,
Qt.ForegroundRole: _foreground,
Qt.FontRole: _font,
Qt.DecorationRole: _decoration,
Qt.TextAlignmentRole: _text_alignment,
}


#------------------------------------------------------------------------------
# Header Data Role Handlers
# Item Model Wrapper
#------------------------------------------------------------------------------
def header_display_role_handler(model, orientation, section):
return model.header_data(orientation, section)


def header_decoration_role_handler(model, orientation, section):
icon = model.header_icon(orientation, section)
if icon is not None:
tk = icon._tkdata
if tk is None:
tk = get_cached_qicon(icon)
return tk


def header_tool_tip_role_handler(model, orientation, section):
return model.header_tool_tip(orientation, section)


def header_status_tip_role_handler(model, orientation, section):
return model.header_status_tip(orientation, section)




def header_text_alignment_role_handler(model, orientation, section):
return Qt.Alignment(model.header_text_alignment(orientation, section))


def header_background_role_handler(model, orientation, section):
color = model.header_background(orientation, section)
if color is not None:
tk = color._tkdata
if tk is None:
tk = get_cached_qcolor(color)
return tk


def header_foreground_role_handler(model, orientation, section):
color = model.header_foreground(orientation, section)
if color is not None:
tk = color._tkdata
if tk is None:
tk = get_cached_qcolor(color)
return tk


def header_font_role_handler(model, orientation, section):
font = model.header_font(orientation, section)
if font is not None:
tk = font._tkdata
if tk is None:
tk = get_cached_qfont(font)
return tk
class QItemModelWrapper(QAbstractTableModel):
""" A concrete QAbstractTableModel which wraps an ItemModel.
"""
def __init__(self, model=None):
""" Initialize a QItemModelWrapper.
def header_size_hint_role_handler(model, orientation, section):
size = model.header_size_hint(orientation, section)
if size is not None:
return QSize(*size)
Parameters
----------
model : ItemModel, optional
The ItemModel instance to be wrapped by this model.
"""
super(QItemModelWrapper, self).__init__()
self._model = ItemModel()
if model is not None:
self.setItemModel(model)

HEADER_DATA_ROLE_HANDLERS = {
Qt.DisplayRole: display_role_handler,
Qt.DecorationRole: decoration_role_handler,
Qt.EditRole: edit_role_handler,
Qt.ToolTipRole: tool_tip_role_handler,
Qt.StatusTipRole: status_tip_role_handler,
Qt.FontRole: font_role_handler,
Qt.TextAlignmentRole: text_alignment_role_handler,
Qt.BackgroundRole: background_role_handler,
Qt.ForegroundRole: foreground_role_handler,
Qt.CheckStateRole: check_state_role_handler,
Qt.SizeHintRole: size_hint_role_handler,
}
#--------------------------------------------------------------------------
# Public API
#--------------------------------------------------------------------------
def setItemModel(self, model):
""" Set the ItemModel to wrap with this model.
#------------------------------------------------------------------------------
# Item model wrapper
#------------------------------------------------------------------------------
class QItemModelWrapper(QAbstractTableModel):
Parameters
----------
model : ItemModel or None
The ItemModel instance to wrap, or None.
def __init__(self, model):
super(QItemModelWrapper, self).__init__()
self._model = model
"""
assert isinstance(model, ItemModel)
self.beginResetModel()
old = self._model
old.model_reset.disconnect(self._on_model_reset)
old.data_changed.disconnect(self._on_data_changed)
self._model = model or ItemModel()
model.model_reset.connect(self._on_model_reset)
model.data_changed.connect(self._on_data_changed)
model.model_changed.connect(self._on_model_changed)
self.endResetModel()

def _on_data_changed(self, row, column):
index = self.index(row, column)
self.dataChanged.emit(index, index)
#--------------------------------------------------------------------------
# Private API
#--------------------------------------------------------------------------
def _on_model_reset(self):
""" A signal handler for the 'model_reset' signal on the model.
def _on_model_changed(self):
"""
self.beginResetModel()
self.endResetModel()

def _on_data_changed(self, start, end):
""" A signal handler for the 'data_changed' signal on the model.
"""
start_index = self.index(*start)
end_index = self.index(*end)
self.dataChanged.emit(start_index, end_index)

#--------------------------------------------------------------------------
# QAbstractTableModel API Implementation
# QAbstractTableModel Interface
#--------------------------------------------------------------------------
def rowCount(self, parent):
if parent.isValid():
Expand All @@ -222,15 +176,33 @@ def columnCount(self, parent):
return self._model.column_count()

def flags(self, index):
return Qt.ItemFlags(self._model.flags(index.row(), index.column()))
item = self._model.item(index.row(), index.column())
if item is not None:
return Qt.ItemFlags(item.item_flags)
return Qt.ItemFlags(0)

def headerData(self, section, orientation, role):
if orientation == Qt.Horizontal:
item = self._model.column_header_item(section)
else:
item = self._model.row_header_item(section)
if item is not None:
handler = ROLE_HANDLERS.get(role)
if handler is not None:
return handler(item)

def data(self, index, role):
handler = ITEM_DATA_ROLE_HANDLERS.get(role)
if handler is not None:
return handler(self._model, index.row(), index.column())
item = self._model.item(index.row(), index.column())
if item is not None:
handler = ROLE_HANDLERS.get(role)
if handler is not None:
return handler(item)

def setData(self, index, value, role):
handler = ITEM_DATA_SET_ROLE_HANDLERS.get(role)
if handler is not None:
return handler(self._model, index.row(), index.column(), value)
if role == Qt.EditRole:
item = self._model.item(index.row(), index.column())
if item is not None:
if item.set_data(value):
self.dataChanged.emit(index, index)
return True
return False
Loading

0 comments on commit de0d8e3

Please sign in to comment.