source: src/mlx/gui/flightlist.py@ 811:e84ebe7c6497

Last change on this file since 811:e84ebe7c6497 was 811:e84ebe7c6497, checked in by István Váradi <ivaradi@…>, 8 years ago

Extracted the flight list widget into its own class (re #307)

File size: 5.9 KB
Line 
1# A widget which is a generic list of flights
2
3#-----------------------------------------------------------------------------
4
5from mlx.gui.common import *
6
7#-----------------------------------------------------------------------------
8
9class ColumnDescriptor(object):
10 """A descriptor for a column in the list."""
11 def __init__(self, attribute, heading, type = str,
12 convertFn = None, renderer = gtk.CellRendererText(),
13 extraColumnAttributes = None):
14 """Construct the descriptor."""
15 self._attribute = attribute
16 self._heading = heading
17 self._type = type
18 self._convertFn = convertFn
19 self._renderer = renderer
20 self._extraColumnAttributes = extraColumnAttributes
21
22 def appendType(self, types):
23 """Append the type of this column to the given list of types."""
24 types.append(self._type)
25
26 def getViewColumn(self, index):
27 """Get a new column object for a tree view.
28
29 @param index is the 0-based index of the column."""
30 if self._extraColumnAttributes is None:
31 if isinstance(self._renderer, gtk.CellRendererText):
32 extraColumnAttributes = {"text" : index}
33 else:
34 extraColumnAttributes = {}
35 else:
36 extraColumnAttributes = self._extraColumnAttributes
37
38 column = gtk.TreeViewColumn(self._heading, self._renderer,
39 text = index)
40 column.set_expand(True)
41
42 return column
43
44 def getValueFrom(self, flight):
45 """Get the value from the given flight."""
46 value = getattr(flight, self._attribute)
47 return self._type(value) if self._convertFn is None \
48 else self._convertFn(value)
49
50#-----------------------------------------------------------------------------
51
52class FlightList(gtk.Alignment):
53 """Construct the flight list.
54
55 This is a complete widget with a scroll window. It is alignment centered
56 horizontally and expandable vertically."""
57 def __init__(self, columnDescriptors, popupMenuProducer = None,
58 widthRequest = None):
59 """Construct the flight list with the given column descriptors."""
60
61 self._columnDescriptors = columnDescriptors
62 self._popupMenuProducer = popupMenuProducer
63 self._popupMenu = None
64
65 types = []
66 for columnDescriptor in self._columnDescriptors:
67 columnDescriptor.appendType(types)
68
69 self._model = gtk.ListStore(*types)
70 self._view = gtk.TreeView(self._model)
71
72 index = 0
73 for columnDescriptor in self._columnDescriptors:
74 column = columnDescriptor.getViewColumn(index)
75 self._view.append_column(column)
76 index += 1
77
78 self._view.connect("row-activated", self._rowActivated)
79 self._view.connect("button-press-event", self._buttonPressEvent)
80
81 selection = self._view.get_selection()
82 selection.connect("changed", self._selectionChanged)
83
84 scrolledWindow = gtk.ScrolledWindow()
85 scrolledWindow.add(self._view)
86 if widthRequest is not None:
87 scrolledWindow.set_size_request(widthRequest, -1)
88 # FIXME: these should be constants in common.py
89 scrolledWindow.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
90 else gtk.POLICY_AUTOMATIC,
91 gtk.PolicyType.AUTOMATIC if pygobject
92 else gtk.POLICY_AUTOMATIC)
93 scrolledWindow.set_shadow_type(gtk.ShadowType.IN if pygobject
94 else gtk.SHADOW_IN)
95
96 super(FlightList, self).__init__(xalign = 0.5, yalign = 0.0,
97 xscale = 0.0, yscale = 1.0)
98 self.add(scrolledWindow)
99
100 @property
101 def selectedIndex(self):
102 """Get the index of the selected entry, if any."""
103 selection = self._view.get_selection()
104 (model, iter) = selection.get_selected()
105 if iter is None:
106 return None
107 else:
108 path = model.get_path(iter)
109 [index] = path.get_indices() if pygobject else path
110 return index
111
112 def clear(self):
113 """Clear the model."""
114 self._model.clear()
115
116 def addFlight(self, flight):
117 """Add the given booked flight."""
118 values = []
119 for columnDescriptor in self._columnDescriptors:
120 values.append(columnDescriptor.getValueFrom(flight))
121 self._model.append(values)
122
123 def _rowActivated(self, flightList, path, column):
124 """Called when a row is selected."""
125 self.emit("row-activated", self.selectedIndex)
126
127 def _buttonPressEvent(self, widget, event):
128 """Called when a mouse button is pressed or released."""
129 if event.type!=EVENT_BUTTON_PRESS or event.button!=3:
130 return
131
132 (path, _, _, _) = self._view.get_path_at_pos(int(event.x),
133 int(event.y))
134 selection = self._view.get_selection()
135 selection.unselect_all()
136 selection.select_path(path)
137
138 if self._popupMenu is None:
139 self._popupMenu = self._popupMenuProducer()
140 menu = self._popupMenu
141 if pygobject:
142 menu.popup(None, None, None, None, event.button, event.time)
143 else:
144 menu.popup(None, None, None, event.button, event.time)
145
146 def _selectionChanged(self, selection):
147 """Called when the selection has changed."""
148 self.emit("selection-changed", self.selectedIndex)
149
150#-------------------------------------------------------------------------------
151
152gobject.signal_new("row-activated", FlightList, gobject.SIGNAL_RUN_FIRST,
153 None, (int,))
154
155gobject.signal_new("selection-changed", FlightList, gobject.SIGNAL_RUN_FIRST,
156 None, (object,))
157
158#-----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.