source: src/mlx/gui/pirep.py@ 224:6269b46d6740

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

Added an OK button to the PIREP viewer.

File size: 20.9 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 self._okButton = self.add_button(xstr("button_ok"), RESPONSETYPE_OK)
156 self._okButton.set_can_default(True)
157
158 def setPIREP(self, pirep):
159 """Setup the data in the dialog from the given PIREP."""
160 bookedFlight = pirep.bookedFlight
161
162 self._callsign.set_text(bookedFlight.callsign)
163 self._tailNumber.set_text(bookedFlight.tailNumber)
164 aircraftType = xstr("aircraft_" + icaoCodes[bookedFlight.aircraftType].lower())
165 self._aircraftType.set_text(aircraftType)
166
167 self._departureICAO.set_text(bookedFlight.departureICAO)
168 self._departureTime.set_text("%02d:%02d" % \
169 (bookedFlight.departureTime.hour,
170 bookedFlight.departureTime.minute))
171
172 self._arrivalICAO.set_text(bookedFlight.arrivalICAO)
173 self._arrivalTime.set_text("%02d:%02d" % \
174 (bookedFlight.arrivalTime.hour,
175 bookedFlight.arrivalTime.minute))
176
177 self._numPassengers.set_text(str(bookedFlight.numPassengers))
178 self._numCrew.set_text(str(bookedFlight.numCrew))
179 self._bagWeight.set_text(str(bookedFlight.bagWeight))
180 self._cargoWeight.set_text(str(bookedFlight.cargoWeight))
181 self._mailWeight.set_text(str(bookedFlight.mailWeight))
182
183 self._route.get_buffer().set_text(bookedFlight.route)
184
185 self._filedCruiseLevel.set_text("FL" + str(pirep.filedCruiseAltitude/100))
186
187 if pirep.cruiseAltitude != pirep.filedCruiseAltitude:
188 self._modifiedCruiseLevel.set_text("FL" + str(pirep.cruiseAltitude/100))
189 else:
190 self._modifiedCruiseLevel.set_text("-")
191
192 self._userRoute.get_buffer().set_text(pirep.route)
193
194 self._departureMETAR.get_buffer().set_text(pirep.departureMETAR)
195
196 self._arrivalMETAR.get_buffer().set_text(pirep.arrivalMETAR)
197 self._departureRunway.set_text(pirep.departureRunway)
198 self._sid.set_text(pirep.sid)
199
200 self._star.set_text("-" if pirep.star is None else pirep.star)
201 self._transition.set_text("-" if pirep.transition is None else pirep.transition)
202 self._approachType.set_text(pirep.approachType)
203 self._arrivalRunway.set_text(pirep.arrivalRunway)
204
205 PIREPViewer.timestamp2text(self._blockTimeStart, pirep.blockTimeStart)
206 PIREPViewer.timestamp2text(self._blockTimeEnd, pirep.blockTimeEnd)
207 PIREPViewer.timestamp2text(self._flightTimeStart, pirep.flightTimeStart)
208 PIREPViewer.timestamp2text(self._flightTimeEnd, pirep.flightTimeEnd)
209
210 self._flownDistance.set_text("%.1f" % (pirep.flownDistance,))
211 self._fuelUsed.set_text("%.0f" % (pirep.fuelUsed,))
212
213 rating = pirep.rating
214 if rating<0:
215 self._rating.set_markup('<b><span foreground="red">NO GO</span></b>')
216 else:
217 self._rating.set_text("%.1f %%" % (rating,))
218
219 self._flownCargoWeight.set_text("%.0f" % (pirep.cargoWeight,))
220 self._flightType.set_text(xstr("flighttype_" +
221 flightType2string(pirep.flightType)))
222 self._online.set_text(xstr("pirepView_" +
223 ("yes" if pirep.online else "no")))
224
225 delayCodes = ""
226 for code in pirep.delayCodes:
227 if delayCodes: delayCodes += ", "
228 delayCodes += PIREP.delayCodes[code]
229
230 self._delayCodes.get_buffer().set_text(delayCodes)
231
232 self._comments.get_buffer().set_text(pirep.comments)
233 self._flightDefects.get_buffer().set_text(pirep.flightDefects)
234
235 logBuffer = self._log.get_buffer()
236 logBuffer.set_text("")
237 for (timeStr, line) in pirep.logLines:
238 logBuffer.insert(logBuffer.get_end_iter(),
239 formatFlightLogLine(timeStr, line))
240
241 self._notebook.set_current_page(0)
242 self._okButton.grab_default()
243
244 def _buildDataTab(self):
245 """Build the data tab of the viewer."""
246 table = gtk.Table(1, 2)
247 table.set_row_spacings(4)
248 table.set_col_spacings(16)
249 table.set_homogeneous(True)
250
251 box1 = gtk.VBox()
252 table.attach(box1, 0, 1, 0, 1)
253
254 box2 = gtk.VBox()
255 table.attach(box2, 1, 2, 0, 1)
256
257 flightFrame = self._buildFlightFrame()
258 box1.pack_start(flightFrame, False, False, 4)
259
260 routeFrame = self._buildRouteFrame()
261 box1.pack_start(routeFrame, False, False, 4)
262
263 departureFrame = self._buildDepartureFrame()
264 box2.pack_start(departureFrame, True, True, 4)
265
266 arrivalFrame = self._buildArrivalFrame()
267 box2.pack_start(arrivalFrame, True, True, 4)
268
269 statisticsFrame = self._buildStatisticsFrame()
270 box2.pack_start(statisticsFrame, False, False, 4)
271
272 miscellaneousFrame = self._buildMiscellaneousFrame()
273 box1.pack_start(miscellaneousFrame, False, False, 4)
274
275 return table
276
277 def _buildFlightFrame(self):
278 """Build the frame for the flight data."""
279
280 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight"))
281
282 dataBox = gtk.HBox()
283 mainBox.pack_start(dataBox, False, False, 0)
284
285 self._callsign = \
286 PIREPViewer.addLabeledData(dataBox,
287 xstr("pirepView_callsign"),
288 width = 8)
289
290 self._tailNumber = \
291 PIREPViewer.addLabeledData(dataBox,
292 xstr("pirepView_tailNumber"),
293 width = 7)
294
295 PIREPViewer.addVFiller(mainBox)
296
297 dataBox = gtk.HBox()
298 mainBox.pack_start(dataBox, False, False, 0)
299
300 self._aircraftType = \
301 PIREPViewer.addLabeledData(dataBox,
302 xstr("pirepView_aircraftType"),
303 width = 25)
304
305 PIREPViewer.addVFiller(mainBox)
306
307 table = gtk.Table(3, 2)
308 mainBox.pack_start(table, False, False, 0)
309 table.set_row_spacings(4)
310 table.set_col_spacings(8)
311
312 self._departureICAO = \
313 PIREPViewer.tableAttach(table, 0, 0,
314 xstr("pirepView_departure"),
315 width = 5)
316
317 self._departureTime = \
318 PIREPViewer.tableAttach(table, 1, 0,
319 xstr("pirepView_departure_time"),
320 width = 6)
321
322 self._arrivalICAO = \
323 PIREPViewer.tableAttach(table, 0, 1,
324 xstr("pirepView_arrival"),
325 width = 5)
326
327 self._arrivalTime = \
328 PIREPViewer.tableAttach(table, 1, 1,
329 xstr("pirepView_arrival_time"),
330 width = 6)
331
332 table = gtk.Table(3, 2)
333 mainBox.pack_start(table, False, False, 0)
334 table.set_row_spacings(4)
335 table.set_col_spacings(8)
336
337 self._numPassengers = \
338 PIREPViewer.tableAttach(table, 0, 0,
339 xstr("pirepView_numPassengers"),
340 width = 4)
341
342 self._numCrew = \
343 PIREPViewer.tableAttach(table, 1, 0,
344 xstr("pirepView_numCrew"),
345 width = 3)
346
347 self._bagWeight = \
348 PIREPViewer.tableAttach(table, 0, 1,
349 xstr("pirepView_bagWeight"),
350 width = 5)
351
352 self._cargoWeight = \
353 PIREPViewer.tableAttach(table, 1, 1,
354 xstr("pirepView_cargoWeight"),
355 width = 5)
356
357 self._mailWeight = \
358 PIREPViewer.tableAttach(table, 2, 1,
359 xstr("pirepView_mailWeight"),
360 width = 5)
361
362 PIREPViewer.addVFiller(mainBox)
363
364 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")),
365 False, False, 0)
366
367 (routeWindow, self._route) = PIREPViewer.getTextWindow()
368 mainBox.pack_start(routeWindow, False, False, 0)
369
370 return frame
371
372 def _buildRouteFrame(self):
373 """Build the frame for the user-specified route and flight
374 level."""
375
376 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route"))
377
378 levelBox = gtk.HBox()
379 mainBox.pack_start(levelBox, False, False, 0)
380
381 self._filedCruiseLevel = \
382 PIREPViewer.addLabeledData(levelBox,
383 xstr("pirepView_filedCruiseLevel"),
384 width = 6)
385
386 self._modifiedCruiseLevel = \
387 PIREPViewer.addLabeledData(levelBox,
388 xstr("pirepView_modifiedCruiseLevel"),
389 width = 6)
390
391 PIREPViewer.addVFiller(mainBox)
392
393 (routeWindow, self._userRoute) = PIREPViewer.getTextWindow()
394 mainBox.pack_start(routeWindow, False, False, 0)
395
396 return frame
397
398 def _buildDepartureFrame(self):
399 """Build the frame for the departure data."""
400 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_departure"))
401
402 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
403 False, False, 0)
404 (metarWindow, self._departureMETAR) = \
405 PIREPViewer.getTextWindow(heightRequest = -1)
406 mainBox.pack_start(metarWindow, True, True, 0)
407
408 PIREPViewer.addVFiller(mainBox)
409
410 dataBox = gtk.HBox()
411 mainBox.pack_start(dataBox, False, False, 0)
412
413 self._departureRunway = \
414 PIREPViewer.addLabeledData(dataBox,
415 xstr("pirepView_runway"),
416 width = 5)
417
418 self._sid = \
419 PIREPViewer.addLabeledData(dataBox,
420 xstr("pirepView_sid"),
421 width = 12)
422
423 return frame
424
425 def _buildArrivalFrame(self):
426 """Build the frame for the arrival data."""
427 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_arrival"))
428
429 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
430 False, False, 0)
431 (metarWindow, self._arrivalMETAR) = \
432 PIREPViewer.getTextWindow(heightRequest = -1)
433 mainBox.pack_start(metarWindow, True, True, 0)
434
435 PIREPViewer.addVFiller(mainBox)
436
437 table = gtk.Table(2, 2)
438 mainBox.pack_start(table, False, False, 0)
439 table.set_row_spacings(4)
440 table.set_col_spacings(8)
441
442 self._star = \
443 PIREPViewer.tableAttach(table, 0, 0,
444 xstr("pirepView_star"),
445 width = 12)
446
447 self._transition = \
448 PIREPViewer.tableAttach(table, 1, 0,
449 xstr("pirepView_transition"),
450 width = 12)
451
452 self._approachType = \
453 PIREPViewer.tableAttach(table, 0, 1,
454 xstr("pirepView_approachType"),
455 width = 7)
456
457 self._arrivalRunway = \
458 PIREPViewer.tableAttach(table, 1, 1,
459 xstr("pirepView_runway"),
460 width = 5)
461
462 return frame
463
464 def _buildStatisticsFrame(self):
465 """Build the frame for the statistics data."""
466 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_statistics"))
467
468 table = gtk.Table(4, 2)
469 mainBox.pack_start(table, False, False, 0)
470 table.set_row_spacings(4)
471 table.set_col_spacings(8)
472 table.set_homogeneous(False)
473
474 self._blockTimeStart = \
475 PIREPViewer.tableAttach(table, 0, 0,
476 xstr("pirepView_blockTimeStart"),
477 width = 6)
478
479 self._blockTimeEnd = \
480 PIREPViewer.tableAttach(table, 1, 0,
481 xstr("pirepView_blockTimeEnd"),
482 width = 8)
483
484 self._flightTimeStart = \
485 PIREPViewer.tableAttach(table, 0, 1,
486 xstr("pirepView_flightTimeStart"),
487 width = 6)
488
489 self._flightTimeEnd = \
490 PIREPViewer.tableAttach(table, 1, 1,
491 xstr("pirepView_flightTimeEnd"),
492 width = 6)
493
494 self._flownDistance = \
495 PIREPViewer.tableAttach(table, 0, 2,
496 xstr("pirepView_flownDistance"),
497 width = 8)
498
499 self._fuelUsed = \
500 PIREPViewer.tableAttach(table, 1, 2,
501 xstr("pirepView_fuelUsed"),
502 width = 6)
503
504 self._rating = \
505 PIREPViewer.tableAttach(table, 0, 3,
506 xstr("pirepView_rating"),
507 width = 7)
508 return frame
509
510 def _buildMiscellaneousFrame(self):
511 """Build the frame for the miscellaneous data."""
512 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous"))
513
514 dataBox = gtk.HBox()
515 mainBox.pack_start(dataBox, False, False, 0)
516
517 self._flownCargoWeight = \
518 PIREPViewer.addLabeledData(dataBox,
519 xstr("pirepView_cargoWeight"),
520 width = 6)
521
522 self._flightType = \
523 PIREPViewer.addLabeledData(dataBox,
524 xstr("pirepView_flightType"),
525 width = 10)
526
527 self._online = \
528 PIREPViewer.addLabeledData(dataBox,
529 xstr("pirepView_online"),
530 width = 5)
531
532 PIREPViewer.addVFiller(mainBox)
533
534 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")),
535 False, False, 0)
536
537 (textWindow, self._delayCodes) = PIREPViewer.getTextWindow()
538 mainBox.pack_start(textWindow, False, False, 0)
539
540 return frame
541
542 def _buildCommentsTab(self):
543 """Build the tab with the comments and flight defects."""
544 table = gtk.Table(2, 1)
545 table.set_col_spacings(16)
546
547 (frame, commentsBox) = \
548 PIREPViewer.createFrame(xstr("pirepView_comments"))
549 table.attach(frame, 0, 1, 0, 1)
550
551 (commentsWindow, self._comments) = \
552 PIREPViewer.getTextWindow(heightRequest = -1)
553 commentsBox.pack_start(commentsWindow, True, True, 0)
554
555 (frame, flightDefectsBox) = \
556 PIREPViewer.createFrame(xstr("pirepView_flightDefects"))
557 table.attach(frame, 1, 2, 0, 1)
558
559 (flightDefectsWindow, self._flightDefects) = \
560 PIREPViewer.getTextWindow(heightRequest = -1)
561 flightDefectsBox.pack_start(flightDefectsWindow, True, True, 0)
562
563 return table
564
565 def _buildLogTab(self):
566 """Build the log tab."""
567 mainBox = gtk.VBox()
568
569 (logWindow, self._log) = PIREPViewer.getTextWindow(heightRequest = -1)
570 mainBox.pack_start(logWindow, True, True, 0)
571
572 return mainBox
573
574#------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.