source: src/mlx/gui/pirep.py@ 221:2126271cea84

Last change on this file since 221:2126271cea84 was 221:2126271cea84, checked in by István Váradi <ivaradi@…>, 12 years ago

Implemented the PIREP viewer tabs for the comments and the log

File size: 20.6 KB
Line 
1# Module for the detailed PIREP viewer
2
3#------------------------------------------------------------------------------
4
5from common import *
6
7from mlx.const import *
8
9import time
10
11#------------------------------------------------------------------------------
12
13class PIREPViewer(gtk.Dialog):
14 """The dialog for PIREP viewing."""
15 @staticmethod
16 def createFrame(label):
17 """Create a frame with the given label.
18
19 The frame will contain an alignment to properly distance the
20 insides. The alignment will contain a VBox to contain the real
21 contents.
22
23 The function returns a tuple with the following items:
24 - the frame,
25 - the inner VBox."""
26 frame = gtk.Frame(label = label)
27
28 alignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
29 xscale = 1.0, yscale = 1.0)
30 frame.add(alignment)
31 alignment.set_padding(padding_top = 4, padding_bottom = 4,
32 padding_left = 4, padding_right = 4)
33 box = gtk.VBox()
34 alignment.add(box)
35
36 return (frame, box)
37
38 @staticmethod
39 def getLabel(text):
40 """Get a bold label with the given text."""
41 label = gtk.Label("<b>" + text + "</b>")
42 label.set_use_markup(True)
43 label.set_alignment(0.0, 0.5)
44 return label
45
46 @staticmethod
47 def getDataLabel(width = None, xAlignment = 0.0):
48 """Get a bold label with the given text."""
49 label = gtk.Label()
50 if width is not None:
51 label.set_width_chars(width)
52 label.set_alignment(xAlignment, 0.5)
53 return label
54
55 @staticmethod
56 def getTextWindow(heightRequest = 40):
57 """Get a scrollable text window.
58
59 Returns a tuple of the following items:
60 - the window,
61 - the text view."""
62 scrolledWindow = gtk.ScrolledWindow()
63 scrolledWindow.set_shadow_type(SHADOW_IN)
64 scrolledWindow.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
65
66 textView = gtk.TextView()
67 textView.set_wrap_mode(WRAP_WORD)
68 textView.set_editable(False)
69 textView.set_cursor_visible(False)
70 textView.set_size_request(-1, heightRequest)
71 scrolledWindow.add(textView)
72
73 return (scrolledWindow, textView)
74
75 @staticmethod
76 def tableAttach(table, column, row, labelText, width = None,
77 dataLabelXAlignment = 0.0):
78 """Attach a labeled data to the given column and row of the
79 table.
80
81 If width is given, that will be the width of the data
82 label.
83
84 Returns the data label attached."""
85 dataBox = gtk.HBox()
86 table.attach(dataBox, column, column+1, row, row+1)
87
88 dataLabel = PIREPViewer.addLabeledData(dataBox, labelText,
89 width = width)
90 dataLabel.set_alignment(dataLabelXAlignment, 0.5)
91
92 return dataLabel
93
94 @staticmethod
95 def addLabeledData(hBox, labelText, width = None, dataPadding = 8):
96 """Add a label and a data label to the given HBox.
97
98 Returnsd the data label."""
99 label = PIREPViewer.getLabel(labelText)
100 hBox.pack_start(label, False, False, 0)
101
102 dataLabel = PIREPViewer.getDataLabel(width = width)
103 hBox.pack_start(dataLabel, False, False, dataPadding)
104
105 return dataLabel
106
107 @staticmethod
108 def addVFiller(vBox, height = 4):
109 """Add a filler eventbox to the given vertical box."""
110 filler = gtk.EventBox()
111 filler.set_size_request(-1, height)
112 vBox.pack_start(filler, False, False, 0)
113
114 @staticmethod
115 def timestamp2text(label, timestamp):
116 """Convert the given timestamp into a text containing the hour
117 and minute in UTC and put that text into the given label."""
118 tm = time.gmtime(timestamp)
119 label.set_text("%02d:%02d" % (tm.tm_hour, tm.tm_min))
120
121 def __init__(self, gui):
122 """Construct the PIREP viewer."""
123 super(PIREPViewer, self).__init__(title = WINDOW_TITLE_BASE +
124 " - " +
125 xstr("pirepView_title"),
126 parent = gui.mainWindow)
127
128 self.set_resizable(False)
129
130 self._gui = gui
131
132 contentArea = self.get_content_area()
133
134 self._notebook = gtk.Notebook()
135 contentArea.pack_start(self._notebook, False, False, 4)
136
137 dataTab = self._buildDataTab()
138 label = gtk.Label(xstr("pirepView_tab_data"))
139 label.set_use_underline(True)
140 label.set_tooltip_text(xstr("pirepView_tab_data_tooltip"))
141 self._notebook.append_page(dataTab, label)
142
143 commentsTab = self._buildCommentsTab()
144 label = gtk.Label(xstr("pirepView_tab_comments"))
145 label.set_use_underline(True)
146 label.set_tooltip_text(xstr("pirepView_tab_comments_tooltip"))
147 self._notebook.append_page(commentsTab, label)
148
149 logTab = self._buildLogTab()
150 label = gtk.Label(xstr("pirepView_tab_log"))
151 label.set_use_underline(True)
152 label.set_tooltip_text(xstr("pirepView_tab_log_tooltip"))
153 self._notebook.append_page(logTab, label)
154
155 def setPIREP(self, pirep):
156 """Setup the data in the dialog from the given PIREP."""
157 bookedFlight = pirep.bookedFlight
158
159 self._callsign.set_text(bookedFlight.callsign)
160 self._tailNumber.set_text(bookedFlight.tailNumber)
161 aircraftType = xstr("aircraft_" + icaoCodes[bookedFlight.aircraftType].lower())
162 self._aircraftType.set_text(aircraftType)
163
164 self._departureICAO.set_text(bookedFlight.departureICAO)
165 self._departureTime.set_text("%02d:%02d" % \
166 (bookedFlight.departureTime.hour,
167 bookedFlight.departureTime.minute))
168
169 self._arrivalICAO.set_text(bookedFlight.arrivalICAO)
170 self._arrivalTime.set_text("%02d:%02d" % \
171 (bookedFlight.arrivalTime.hour,
172 bookedFlight.arrivalTime.minute))
173
174 self._numPassengers.set_text(str(bookedFlight.numPassengers))
175 self._numCrew.set_text(str(bookedFlight.numCrew))
176 self._bagWeight.set_text(str(bookedFlight.bagWeight))
177 self._cargoWeight.set_text(str(bookedFlight.cargoWeight))
178 self._mailWeight.set_text(str(bookedFlight.mailWeight))
179
180 self._route.get_buffer().set_text(bookedFlight.route)
181
182 self._filedCruiseLevel.set_text("FL" + str(pirep.filedCruiseAltitude/100))
183
184 if pirep.cruiseAltitude != pirep.filedCruiseAltitude:
185 self._modifiedCruiseLevel.set_text("FL" + str(pirep.cruiseAltitude/100))
186 else:
187 self._modifiedCruiseLevel.set_text("-")
188
189 self._userRoute.get_buffer().set_text(pirep.route)
190
191 self._departureMETAR.get_buffer().set_text(pirep.departureMETAR)
192
193 self._arrivalMETAR.get_buffer().set_text(pirep.arrivalMETAR)
194 self._departureRunway.set_text(pirep.departureRunway)
195 self._sid.set_text(pirep.sid)
196
197 self._star.set_text("-" if pirep.star is None else pirep.star)
198 self._transition.set_text("-" if pirep.transition is None else pirep.transition)
199 self._approachType.set_text(pirep.approachType)
200 self._arrivalRunway.set_text(pirep.arrivalRunway)
201
202 PIREPViewer.timestamp2text(self._blockTimeStart, pirep.blockTimeStart)
203 PIREPViewer.timestamp2text(self._blockTimeEnd, pirep.blockTimeEnd)
204 PIREPViewer.timestamp2text(self._flightTimeStart, pirep.flightTimeStart)
205 PIREPViewer.timestamp2text(self._flightTimeEnd, pirep.flightTimeEnd)
206
207 self._flownDistance.set_text("%.1f" % (pirep.flownDistance,))
208 self._fuelUsed.set_text("%.0f" % (pirep.fuelUsed,))
209
210 rating = pirep.rating
211 if rating<0:
212 self._rating.set_markup('<b><span foreground="red">NO GO</span></b>')
213 else:
214 self._rating.set_text("%.1f %%" % (rating,))
215
216 self._flightType.set_text(xstr("flighttype_" +
217 flightType2string(pirep.flightType)))
218 self._online.set_text(xstr("pirepView_" +
219 ("yes" if pirep.online else "no")))
220
221 delayCodes = ""
222 for code in pirep.delayCodes:
223 if delayCodes: delayCodes += ", "
224 delayCodes += PIREP.delayCodes[code]
225
226 self._delayCodes.get_buffer().set_text(delayCodes)
227
228 self._comments.get_buffer().set_text(pirep.comments)
229 self._flightDefects.get_buffer().set_text(pirep.flightDefects)
230
231 logBuffer = self._log.get_buffer()
232 logBuffer.set_text("")
233 for (timeStr, line) in pirep.logLines:
234 logBuffer.insert(logBuffer.get_end_iter(),
235 formatFlightLogLine(timeStr, line))
236
237 self._notebook.set_current_page(0)
238
239 def _buildDataTab(self):
240 """Build the data tab of the viewer."""
241 table = gtk.Table(1, 2)
242 table.set_row_spacings(4)
243 table.set_col_spacings(16)
244 table.set_homogeneous(True)
245
246 box1 = gtk.VBox()
247 table.attach(box1, 0, 1, 0, 1)
248
249 box2 = gtk.VBox()
250 table.attach(box2, 1, 2, 0, 1)
251
252 flightFrame = self._buildFlightFrame()
253 box1.pack_start(flightFrame, False, False, 4)
254
255 routeFrame = self._buildRouteFrame()
256 box1.pack_start(routeFrame, False, False, 4)
257
258 departureFrame = self._buildDepartureFrame()
259 box2.pack_start(departureFrame, True, True, 4)
260
261 arrivalFrame = self._buildArrivalFrame()
262 box2.pack_start(arrivalFrame, True, True, 4)
263
264 statisticsFrame = self._buildStatisticsFrame()
265 box2.pack_start(statisticsFrame, False, False, 4)
266
267 miscellaneousFrame = self._buildMiscellaneousFrame()
268 box1.pack_start(miscellaneousFrame, False, False, 4)
269
270 return table
271
272 def _buildFlightFrame(self):
273 """Build the frame for the flight data."""
274
275 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight"))
276
277 dataBox = gtk.HBox()
278 mainBox.pack_start(dataBox, False, False, 0)
279
280 self._callsign = \
281 PIREPViewer.addLabeledData(dataBox,
282 xstr("pirepView_callsign"),
283 width = 8)
284
285 self._tailNumber = \
286 PIREPViewer.addLabeledData(dataBox,
287 xstr("pirepView_tailNumber"),
288 width = 7)
289
290 PIREPViewer.addVFiller(mainBox)
291
292 dataBox = gtk.HBox()
293 mainBox.pack_start(dataBox, False, False, 0)
294
295 self._aircraftType = \
296 PIREPViewer.addLabeledData(dataBox,
297 xstr("pirepView_aircraftType"),
298 width = 25)
299
300 PIREPViewer.addVFiller(mainBox)
301
302 table = gtk.Table(3, 2)
303 mainBox.pack_start(table, False, False, 0)
304 table.set_row_spacings(4)
305 table.set_col_spacings(8)
306
307 self._departureICAO = \
308 PIREPViewer.tableAttach(table, 0, 0,
309 xstr("pirepView_departure"),
310 width = 5)
311
312 self._departureTime = \
313 PIREPViewer.tableAttach(table, 1, 0,
314 xstr("pirepView_departure_time"),
315 width = 6)
316
317 self._arrivalICAO = \
318 PIREPViewer.tableAttach(table, 0, 1,
319 xstr("pirepView_arrival"),
320 width = 5)
321
322 self._arrivalTime = \
323 PIREPViewer.tableAttach(table, 1, 1,
324 xstr("pirepView_arrival_time"),
325 width = 6)
326
327 PIREPViewer.addVFiller(mainBox)
328
329 table = gtk.Table(3, 2)
330 mainBox.pack_start(table, False, False, 0)
331 table.set_row_spacings(4)
332 table.set_col_spacings(8)
333
334 self._numPassengers = \
335 PIREPViewer.tableAttach(table, 0, 0,
336 xstr("pirepView_numPassengers"),
337 width = 4)
338
339 self._numCrew = \
340 PIREPViewer.tableAttach(table, 1, 0,
341 xstr("pirepView_numCrew"),
342 width = 3)
343
344 self._bagWeight = \
345 PIREPViewer.tableAttach(table, 0, 1,
346 xstr("pirepView_bagWeight"),
347 width = 5)
348
349 self._cargoWeight = \
350 PIREPViewer.tableAttach(table, 1, 1,
351 xstr("pirepView_cargoWeight"),
352 width = 5)
353
354 self._mailWeight = \
355 PIREPViewer.tableAttach(table, 2, 1,
356 xstr("pirepView_mailWeight"),
357 width = 5)
358
359 PIREPViewer.addVFiller(mainBox)
360
361 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")),
362 False, False, 0)
363
364 (routeWindow, self._route) = PIREPViewer.getTextWindow()
365 mainBox.pack_start(routeWindow, False, False, 0)
366
367 return frame
368
369 def _buildRouteFrame(self):
370 """Build the frame for the user-specified route and flight
371 level."""
372
373 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route"))
374
375 levelBox = gtk.HBox()
376 mainBox.pack_start(levelBox, False, False, 0)
377
378 self._filedCruiseLevel = \
379 PIREPViewer.addLabeledData(levelBox,
380 xstr("pirepView_filedCruiseLevel"),
381 width = 6)
382
383 self._modifiedCruiseLevel = \
384 PIREPViewer.addLabeledData(levelBox,
385 xstr("pirepView_modifiedCruiseLevel"),
386 width = 6)
387
388 PIREPViewer.addVFiller(mainBox)
389
390 (routeWindow, self._userRoute) = PIREPViewer.getTextWindow()
391 mainBox.pack_start(routeWindow, False, False, 0)
392
393 return frame
394
395 def _buildDepartureFrame(self):
396 """Build the frame for the departure data."""
397 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_departure"))
398
399 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
400 False, False, 0)
401 (metarWindow, self._departureMETAR) = \
402 PIREPViewer.getTextWindow(heightRequest = -1)
403 mainBox.pack_start(metarWindow, True, True, 0)
404
405 PIREPViewer.addVFiller(mainBox)
406
407 dataBox = gtk.HBox()
408 mainBox.pack_start(dataBox, False, False, 0)
409
410 self._departureRunway = \
411 PIREPViewer.addLabeledData(dataBox,
412 xstr("pirepView_runway"),
413 width = 5)
414
415 self._sid = \
416 PIREPViewer.addLabeledData(dataBox,
417 xstr("pirepView_sid"),
418 width = 12)
419
420 return frame
421
422 def _buildArrivalFrame(self):
423 """Build the frame for the arrival data."""
424 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_arrival"))
425
426 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
427 False, False, 0)
428 (metarWindow, self._arrivalMETAR) = \
429 PIREPViewer.getTextWindow(heightRequest = -1)
430 mainBox.pack_start(metarWindow, True, True, 0)
431
432 PIREPViewer.addVFiller(mainBox)
433
434 table = gtk.Table(2, 2)
435 mainBox.pack_start(table, False, False, 0)
436 table.set_row_spacings(4)
437 table.set_col_spacings(8)
438
439 self._star = \
440 PIREPViewer.tableAttach(table, 0, 0,
441 xstr("pirepView_star"),
442 width = 12)
443
444 self._transition = \
445 PIREPViewer.tableAttach(table, 1, 0,
446 xstr("pirepView_transition"),
447 width = 12)
448
449 self._approachType = \
450 PIREPViewer.tableAttach(table, 0, 1,
451 xstr("pirepView_approachType"),
452 width = 7)
453
454 self._arrivalRunway = \
455 PIREPViewer.tableAttach(table, 1, 1,
456 xstr("pirepView_runway"),
457 width = 5)
458
459 return frame
460
461 def _buildStatisticsFrame(self):
462 """Build the frame for the statistics data."""
463 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_statistics"))
464
465 table = gtk.Table(4, 2)
466 mainBox.pack_start(table, False, False, 0)
467 table.set_row_spacings(4)
468 table.set_col_spacings(8)
469 table.set_homogeneous(False)
470
471 self._blockTimeStart = \
472 PIREPViewer.tableAttach(table, 0, 0,
473 xstr("pirepView_blockTimeStart"),
474 width = 6)
475
476 self._blockTimeEnd = \
477 PIREPViewer.tableAttach(table, 1, 0,
478 xstr("pirepView_blockTimeEnd"),
479 width = 8)
480
481 self._flightTimeStart = \
482 PIREPViewer.tableAttach(table, 0, 1,
483 xstr("pirepView_flightTimeStart"),
484 width = 6)
485
486 self._flightTimeEnd = \
487 PIREPViewer.tableAttach(table, 1, 1,
488 xstr("pirepView_flightTimeEnd"),
489 width = 6)
490
491 self._flownDistance = \
492 PIREPViewer.tableAttach(table, 0, 2,
493 xstr("pirepView_flownDistance"),
494 width = 8)
495
496 self._fuelUsed = \
497 PIREPViewer.tableAttach(table, 1, 2,
498 xstr("pirepView_fuelUsed"),
499 width = 6)
500
501 self._rating = \
502 PIREPViewer.tableAttach(table, 0, 3,
503 xstr("pirepView_rating"),
504 width = 7)
505 return frame
506
507 def _buildMiscellaneousFrame(self):
508 """Build the frame for the miscellaneous data."""
509 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous"))
510
511 dataBox = gtk.HBox()
512 mainBox.pack_start(dataBox, False, False, 0)
513
514 self._flightType = \
515 PIREPViewer.addLabeledData(dataBox,
516 xstr("pirepView_flightType"),
517 width = 10)
518
519 self._online = \
520 PIREPViewer.addLabeledData(dataBox,
521 xstr("pirepView_online"),
522 width = 5)
523
524 PIREPViewer.addVFiller(mainBox)
525
526 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")),
527 False, False, 0)
528
529 (textWindow, self._delayCodes) = PIREPViewer.getTextWindow()
530 mainBox.pack_start(textWindow, False, False, 0)
531
532 return frame
533
534 def _buildCommentsTab(self):
535 """Build the tab with the comments and flight defects."""
536 table = gtk.Table(2, 1)
537 table.set_col_spacings(16)
538
539 (frame, commentsBox) = \
540 PIREPViewer.createFrame(xstr("pirepView_comments"))
541 table.attach(frame, 0, 1, 0, 1)
542
543 (commentsWindow, self._comments) = \
544 PIREPViewer.getTextWindow(heightRequest = -1)
545 commentsBox.pack_start(commentsWindow, True, True, 0)
546
547 (frame, flightDefectsBox) = \
548 PIREPViewer.createFrame(xstr("pirepView_flightDefects"))
549 table.attach(frame, 1, 2, 0, 1)
550
551 (flightDefectsWindow, self._flightDefects) = \
552 PIREPViewer.getTextWindow(heightRequest = -1)
553 flightDefectsBox.pack_start(flightDefectsWindow, True, True, 0)
554
555 return table
556
557 def _buildLogTab(self):
558 """Build the log tab."""
559 mainBox = gtk.VBox()
560
561 (logWindow, self._log) = PIREPViewer.getTextWindow(heightRequest = -1)
562 mainBox.pack_start(logWindow, True, True, 0)
563
564 return mainBox
565
566#------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.