source: src/mlx/gui/delaycodes.py@ 916:4f738ffc3596

Last change on this file since 916:4f738ffc3596 was 840:62cef31d250a, checked in by István Váradi <ivaradi@…>, 7 years ago

It is possible to activate a delay code programmatically.

File size: 15.5 KB
Line 
1# Module to handle the GUI aspects of the table of the delay codes
2
3#------------------------------------------------------------------------------
4
5from dcdata import CAPTION, DELAYCODE, getTable
6
7from mlx.gui.common import *
8
9import mlx.const as const
10
11#------------------------------------------------------------------------------
12
13if pygobject:
14
15#------------------------------------------------------------------------------
16
17 class Viewport(gtk.Viewport):
18 """Viewport implementation that alleviates the problem with improper
19 resizing by the VBox."""
20 def __init__(self):
21 """Construct the viewport."""
22 gtk.Viewport.__init__(self)
23 self._recursive = False
24 self._vboxHeight = None
25
26 def setVBOXHeight(self, vboxHeight):
27 """Set the height of the VBox which will be used to calculate the
28 viewport's height."""
29 self._vboxHeight = vboxHeight
30
31 def do_size_allocate(self, allocation):
32 """Called when the viewport's size is allocated.
33
34 The height in the allocation object is modified so that it is only
35 so high to fit into the VBox."""
36 if self._vboxHeight is not None:
37 allocation.height = self._vboxHeight - allocation.y
38 self._vboxHeight = None
39 gtk.Viewport.do_size_allocate(self, allocation)
40
41 class DelayCodeTableBase(gtk.VBox, gtk.Scrollable):
42 """PyGObject-specific base class for the delay code table."""
43 __gproperties__ = {
44 "vscroll-policy" : ( gtk.ScrollablePolicy,
45 "vscroll-policy",
46 "The vertical scrolling policy",
47 gtk.ScrollablePolicy.MINIMUM,
48 gobject.PARAM_READWRITE ),
49 "vadjustment" : ( gtk.Adjustment,
50 "vadjustment",
51 "The vertical adjustment",
52 gobject.PARAM_READWRITE ),
53 "hscroll-policy" : ( gtk.ScrollablePolicy,
54 "hscroll-policy",
55 "The horizontal scrolling policy",
56 gtk.ScrollablePolicy.MINIMUM,
57 gobject.PARAM_READWRITE ),
58 "hadjustment" : ( gtk.Adjustment,
59 "hadjustment",
60 "The horizontal adjustment",
61 gobject.PARAM_READWRITE ) }
62
63
64 @staticmethod
65 def _createViewport():
66 """Create an instance of the viewport class used by this base class."""
67 return Viewport()
68
69 def __init__(self):
70 """Construct the delay code table."""
71 super(DelayCodeTableBase, self).__init__()
72
73 def do_size_allocate(self, allocation):
74 """Allocate the size for the table and its children.
75
76 This sets up the VBox height in the viewport and then calls the
77 do_size_allocate() function of VBox()."""
78 self._viewport.setVBOXHeight(allocation.height)
79 gtk.VBox.do_size_allocate(self, allocation)
80 self.allocate_column_sizes(allocation)
81
82 def do_get_property(self, prop):
83 """Get the value of one of the properties defined above.
84
85 The request is forwarded to the viewport."""
86 if prop.name=="vscroll-policy":
87 return self._viewport.get_vscroll_policy()
88 elif prop.name=="hscroll-policy":
89 return self._viewport.get_hscroll_policy()
90 elif prop.name=="vadjustment":
91 return self._viewport.get_vadjustment()
92 elif prop.name=="hadjustment":
93 return self._viewport.get_hadjustment()
94 else:
95 raise AttributeError("mlx.gui.delaycodes.DelayCodeTableBase: property %s is not handled in do_get_property" %
96 (prop.name,))
97
98 def do_set_property(self, prop, value):
99 """Set the value of the adjustment properties defined above.
100
101 The adjustments are forwarded to the viewport."""
102 if prop.name=="vadjustment":
103 self._viewport.set_vadjustment(value)
104 elif prop.name=="hadjustment":
105 self._viewport.set_hadjustment(value)
106 self._treeView.set_hadjustment(value)
107 else:
108 raise AttributeError("mlx.gui.delaycodes.DelayCodeTableBase: property %s is not handled in do_set_property" %
109 (prop.name,))
110
111 def setStyle(self):
112 """Set the style of the event box from the treeview."""
113
114 class Alignment(gtk.Alignment):
115 """An alignment that remembers the width it was given."""
116 def __init__(self, xalign = 0.0, yalign=0.0,
117 xscale = 0.0, yscale = 0.0 ):
118 """Construct the alignment."""
119 super(Alignment, self).__init__(xalign = xalign, yalign = yalign,
120 xscale = xscale, yscale = yscale)
121 self.allocatedWidth = 0
122
123 def do_size_allocate(self, allocation):
124 """Called with the new size allocation."""
125 self.allocatedWidth = allocation.width
126 gtk.Alignment.do_size_allocate(self, allocation)
127
128#------------------------------------------------------------------------------
129
130else: # pygobject
131
132#------------------------------------------------------------------------------
133
134 class DelayCodeTableBase (gtk.VBox):
135 """Base class of the delay code table for PyGtk."""
136
137 __gsignals__ = {
138 "set-scroll-adjustments": (
139 gobject.SIGNAL_RUN_LAST,
140 gobject.TYPE_NONE, (gtk.Adjustment, gtk.Adjustment))
141 }
142
143 @staticmethod
144 def _createViewport():
145 """Create an instance of the viewport class used by this base class."""
146 return gtk.Viewport()
147
148 def __init__(self):
149 """Construct the base class."""
150 super(DelayCodeTableBase, self).__init__()
151 self.set_set_scroll_adjustments_signal("set-scroll-adjustments")
152 self.connect("size-allocate", self._do_size_allocate)
153
154 def do_set_scroll_adjustments(self, hAdjustment, vAdjustment):
155 """Set the adjustments on the viewport."""
156 self._viewport.set_hadjustment(hAdjustment)
157 self._viewport.set_vadjustment(vAdjustment)
158 self._treeView.set_hadjustment(hAdjustment)
159
160 def _do_size_allocate(self, widget, allocation):
161 """Handler of the size-allocate signal.
162
163 Calls allocate_column_sizes()."""
164 self.allocate_column_sizes(allocation)
165
166 def setStyle(self):
167 """Set the style of the event box from the treeview."""
168 if self._treeView is not None:
169 style = self._treeView.rc_get_style()
170 self._eventBox.modify_bg(0, style.bg[2])
171 self._eventBox.modify_fg(0, style.fg[2])
172
173 class Alignment(gtk.Alignment):
174 """An alignment that remembers the width it was given."""
175 def __init__(self, xalign = 0.0, yalign=0.0,
176 xscale = 0.0, yscale = 0.0 ):
177 """Construct the alignment."""
178 super(Alignment, self).__init__(xalign = xalign, yalign = yalign,
179 xscale = xscale, yscale = yscale)
180 self.allocatedWidth = 0
181 self.connect("size-allocate", self._do_size_allocate)
182
183 def _do_size_allocate(self, widget, allocation):
184 """Called with the new size allocation."""
185 self.allocatedWidth = allocation.width
186
187#------------------------------------------------------------------------------
188
189class CheckButton(gtk.CheckButton):
190 """A check button that contains a reference to a row in the delay code
191 data table."""
192 def __init__(self, delayCodeRow):
193 """Construct the check button."""
194 super(CheckButton, self).__init__()
195 self.delayCodeRow = delayCodeRow
196
197#------------------------------------------------------------------------------
198
199# CAPTION = 1
200
201# DELAYCODE = 2
202
203# _data1 = ( lambda row: row[0].strip(),
204# ["Num", "Code", "Title", "Description"],
205# [ (CAPTION, "Others"),
206# (DELAYCODE, (" 6", "OA ", "NO GATES/STAND AVAILABLE",
207# "Due to own airline activity")),
208# (DELAYCODE, ("9", "SG", "SCHEDULED GROUND TIME",
209# "Planned turnaround time less than declared minimum")),
210# (CAPTION, "Passenger and baggage"),
211# (DELAYCODE, ("11", "PD", "LATE CHECK-IN",
212# "Check-in reopened for late passengers")),
213# (DELAYCODE, ("12", "PL", "LATE CHECK-IN",
214# "Check-in not completed by flight closure time")),
215# (DELAYCODE, ("13", "PE", "CHECK-IN ERROR",
216# "Error with passenger or baggage details")) ] )
217
218# _data2 = ( lambda row: row[0].strip(),
219# ["MA", "IATA", "Description"],
220# [ (CAPTION, "Passenger and baggage"),
221# (DELAYCODE, (" 012", "01 ",
222# "Late shipping of parts and/or materials")),
223# (DELAYCODE, (" 111", "11",
224# "Check-in reopened for late passengers")),
225# (DELAYCODE, (" 121", "12",
226# "Check-in not completed by flight closure time")),
227# (DELAYCODE, (" 132", "13",
228# "Error with passenger or baggage details"))
229# ])
230
231#------------------------------------------------------------------------------
232
233class DelayCodeTable(DelayCodeTableBase):
234 """The delay code table."""
235 def __init__(self, info):
236 """Construct the delay code table."""
237 super(DelayCodeTable, self).__init__()
238
239 self._info = info
240
241 self._delayCodeData = None
242
243 self._treeView = gtk.TreeView(gtk.ListStore(str, str))
244 self._treeView.set_rules_hint(True)
245
246 self.pack_start(self._treeView, False, False, 0)
247
248 self._alignments = []
249 self._checkButtons = []
250
251 self._eventBox = gtk.EventBox()
252
253 self._table = None
254
255 self._viewport = self._createViewport()
256 self._viewport.add(self._eventBox)
257 self._viewport.set_shadow_type(SHADOW_NONE)
258
259 self.pack_start(self._viewport, True, True, 0)
260
261 self._previousWidth = 0
262
263 @property
264 def delayCodes(self):
265 """Get a list of the delay codes checked by the user."""
266 codes = []
267
268 if self._delayCodeData is not None:
269 codeExtractor = self._delayCodeData[0]
270 for checkButton in self._checkButtons:
271 if checkButton.get_active():
272 codes.append(codeExtractor(checkButton.delayCodeRow))
273
274 return codes
275
276 @property
277 def hasDelayCode(self):
278 """Determine if there is at least one delay code selected."""
279 if self._delayCodeData is not None:
280 for checkButton in self._checkButtons:
281 if checkButton.get_active():
282 return True
283
284 return False
285
286 def allocate_column_sizes(self, allocation):
287 """Allocate the column sizes."""
288 if allocation.width!=self._previousWidth:
289 self._previousWidth = allocation.width
290 index = 0
291 lastIndex = len(self._alignments) - 1
292 for alignment in self._alignments:
293 column = self._treeView.get_column(index)
294 width = alignment.allocatedWidth
295 width += 8 if (index==0 or index==lastIndex) else 16
296 column.set_fixed_width(width)
297 index += 1
298
299 def setType(self, aircraftType):
300 """Setup the delay code table according to the given aircraft type."""
301 self._delayCodeData = data = getTable(aircraftType)
302 if data is None:
303 return
304
305 columns = self._treeView.get_columns()
306 for column in columns:
307 self._treeView.remove_column(column)
308
309 (_extractor, headers, rows) = data
310 numColumns = len(headers) + 1
311 numRows = len(rows)
312
313 column = gtk.TreeViewColumn("", gtk.CellRendererText())
314 column.set_sizing(TREE_VIEW_COLUMN_FIXED)
315 self._treeView.append_column(column)
316
317 for header in headers:
318 column = gtk.TreeViewColumn(header, gtk.CellRendererText())
319 column.set_sizing(TREE_VIEW_COLUMN_FIXED)
320 self._treeView.append_column(column)
321
322 self._table = gtk.Table(numRows, numColumns)
323 self._table.set_homogeneous(False)
324 self._table.set_col_spacings(16)
325 self._table.set_row_spacings(4)
326 self._eventBox.add(self._table)
327
328 self._alignments = []
329 self._checkButtons = []
330
331 firstDelayCodeRow = True
332 for i in range(0, numRows):
333 (type, elements) = rows[i]
334 if type==CAPTION:
335 alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
336 xscale = 1.0)
337 label = gtk.Label("<b>" + elements + "</b>")
338 label.set_use_markup(True)
339 label.set_alignment(0.0, 0.5)
340 alignment.add(label)
341 self._table.attach(alignment, 1, numColumns, i, i+1,
342 yoptions = FILL)
343 self._table.set_row_spacing(i, 8)
344 elif type==DELAYCODE:
345 checkButton = CheckButton(elements)
346 checkButton.connect("toggled", self._delayCodesChanged)
347 self._checkButtons.append(checkButton)
348 alignment = Alignment(xalign = 0.5, yalign = 0.5, xscale = 1.0)
349 alignment.add(checkButton)
350 self._table.attach(alignment, 0, 1, i, i+1,
351 xoptions = FILL, yoptions = FILL)
352 if firstDelayCodeRow:
353 self._alignments.append(alignment)
354
355 for j in range(0, numColumns-1):
356 label = gtk.Label(elements[j])
357 label.set_alignment(0.0, 0.5)
358 alignment = Alignment(xalign = 0.5, yalign = 0.5,
359 xscale = 1.0)
360 alignment.add(label)
361 xoptions = FILL
362 if j==(numColumns-2): xoptions |= EXPAND
363 self._table.attach(alignment, j+1, j+2, i, i+1,
364 xoptions = xoptions, yoptions = FILL)
365 if firstDelayCodeRow:
366 self._alignments.append(alignment)
367 firstDelayCodeRow = False
368
369 self._previousWidth = 0
370 self.show_all()
371
372 def reset(self):
373 """Reset the delay code table."""
374 columns = self._treeView.get_columns()
375 for column in columns:
376 self._treeView.remove_column(column)
377 if self._table is not None:
378 self._eventBox.remove(self._table)
379 self._table = None
380 self.show_all()
381
382 def activateCode(self, code):
383 """Check the checkbox for the given code."""
384 index = 0
385 for (type, data) in self._delayCodeData[2]:
386 if type==DELAYCODE:
387 if code==data[0].strip():
388 self._checkButtons[index].set_active(True)
389 break
390 index += 1
391
392 def _delayCodesChanged(self, button):
393 """Called when one of the delay codes have changed."""
394 self._info.delayCodesChanged()
395
396#------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.