1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
'''
Task Coach - Your friendly task manager
Copyright (C) 2004-2014 Task Coach developers <developers@taskcoach.org>
Task Coach is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Task Coach 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 this program. If not, see <http://www.gnu.org/licenses/>.
'''
from taskcoachlib import operating_system
from taskcoachlib.widgets import itemctrl
import wx.lib.mixins.listctrl
class VirtualListCtrl(itemctrl.CtrlWithItemsMixin, itemctrl.CtrlWithColumnsMixin,
itemctrl.CtrlWithToolTipMixin, wx.ListCtrl):
def __init__(self, parent, columns, selectCommand=None, editCommand=None,
itemPopupMenu=None, columnPopupMenu=None, resizeableColumn=0,
*args, **kwargs):
super(VirtualListCtrl, self).__init__(parent,
style=wx.LC_REPORT | wx.LC_VIRTUAL, columns=columns,
resizeableColumn=resizeableColumn, itemPopupMenu=itemPopupMenu,
columnPopupMenu=columnPopupMenu, *args, **kwargs)
self.__parent = parent
self.bindEventHandlers(selectCommand, editCommand)
def bindEventHandlers(self, selectCommand, editCommand):
# pylint: disable=W0201
if selectCommand:
self.selectCommand = selectCommand
self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.onSelect)
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onSelect)
self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.onSelect)
if editCommand:
self.editCommand = editCommand
self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onItemActivated)
self.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
def onSetFocus(self, event): # pylint: disable=W0613
# Send a child focus event to let the AuiManager know we received focus
# so it will activate our pane
wx.PostEvent(self, wx.ChildFocusEvent(self))
event.Skip()
def getItemWithIndex(self, rowIndex):
return self.__parent.getItemWithIndex(rowIndex)
def getItemText(self, domainObject, columnIndex):
return self.__parent.getItemText(domainObject, columnIndex)
def getItemTooltipData(self, domainObject):
return self.__parent.getItemTooltipData(domainObject)
def getItemImage(self, domainObject, columnIndex=0):
return self.__parent.getItemImages(domainObject,
columnIndex)[wx.TreeItemIcon_Normal]
def OnGetItemText(self, rowIndex, columnIndex):
item = self.getItemWithIndex(rowIndex)
return self.getItemText(item, columnIndex)
def OnGetItemTooltipData(self, rowIndex, columnIndex):
item = self.getItemWithIndex(rowIndex)
return self.getItemTooltipData(item)
def OnGetItemImage(self, rowIndex):
item = self.getItemWithIndex(rowIndex)
return self.getItemImage(item)
def OnGetItemColumnImage(self, rowIndex, columnIndex):
item = self.getItemWithIndex(rowIndex)
return self.getItemImage(item, columnIndex)
def OnGetItemAttr(self, rowIndex):
item = self.getItemWithIndex(rowIndex)
foreground_color = item.foregroundColor(recursive=True)
background_color = item.backgroundColor(recursive=True)
item_attribute_arguments = [foreground_color, background_color]
font = item.font(recursive=True)
if font:
item_attribute_arguments.append(font)
# We need to keep a reference to the item attribute to prevent it
# from being garbage collected too soon:
self.__item_attribute = wx.ListItemAttr(*item_attribute_arguments) # pylint: disable=W0142,W0201
return self.__item_attribute
def onSelect(self, event):
event.Skip()
self.selectCommand(event)
def onItemActivated(self, event):
''' Override default behavior to attach the column clicked on
to the event so we can use it elsewhere. '''
window = self.GetMainWindow()
if operating_system.isMac():
window = window.GetChildren()[0]
mouse_position = window.ScreenToClient(wx.GetMousePosition())
index, dummy_flags, column = self.HitTest(mouse_position)
if index >= 0:
# Only get the column name if the hittest returned an item,
# otherwise the item was activated from the menu or by double
# clicking on a portion of the tree view not containing an item.
column = max(0, column) # FIXME: Why can the column be -1?
event.columnName = self._getColumn(column).name() # pylint: disable=E1101
self.editCommand(event)
def RefreshAllItems(self, count):
self.SetItemCount(count)
if count == 0:
self.DeleteAllItems()
else:
# The VirtualListCtrl makes sure only visible items are updated
super(VirtualListCtrl, self).RefreshItems(0, count - 1)
self.selectCommand()
def RefreshItems(self, *items):
''' Refresh specific items. '''
if len(items) <= 7:
for item in items:
self.RefreshItem(self.__parent.getIndexOfItem(item))
else:
self.RefreshAllItems(self.GetItemCount())
def HitTest(self, (x, y), *args, **kwargs):
''' Always return a three-tuple (item, flag, column). '''
index, flags = super(VirtualListCtrl, self).HitTest((x, y),
*args, **kwargs)
column = 0
if self.InReportView():
# Determine the column in which the user clicked
cumulative_column_width = 0
for column_index in range(self.GetColumnCount()):
cumulative_column_width += self.GetColumnWidth(column_index)
if x <= cumulative_column_width:
column = column_index
break
return index, flags, column
def curselection(self):
return [self.getItemWithIndex(index) \
for index in self.__curselection_indices()]
def select(self, items):
indices = [self.__parent.getIndexOfItem(item) for item in items]
for index in range(self.GetItemCount()):
self.Select(index, index in indices)
if self.curselection():
self.Focus(self.GetFirstSelected())
def clear_selection(self):
''' Unselect all selected items. '''
for index in self.__curselection_indices():
self.Select(index, False)
def select_all(self):
''' Select all items. '''
for index in range(self.GetItemCount()):
self.Select(index)
def __curselection_indices(self):
''' Return the indices of the currently selected items. '''
return wx.lib.mixins.listctrl.getListCtrlSelection(self)
|