source: src/mlx/gui/pirep.py@ 848:1c5224fd9325

Last change on this file since 848:1c5224fd9325 was 848:1c5224fd9325, checked in by István Váradi <ivaradi@…>, 7 years ago

The OK button of the PIREP editor is renamed Save (re #307).

File size: 52.1 KB
Line 
1
2from common import *
3from dcdata import getTable
4from info import FlightInfo
5from flight import comboModel
6
7from mlx.pirep import PIREP
8from mlx.flight import Flight
9from mlx.const import *
10
11import time
12import re
13
14#------------------------------------------------------------------------------
15
16## @package mlx.gui.pirep
17#
18# The detailed PIREP viewer and editor windows.
19#
20# The \ref PIREPViewer class is a dialog displaying all information found in a
21# PIREP. It consists of three tabs. The Data tab displays the simple,
22# itemizable data. The Comments & defects tab contains the flight comments and
23# defects, while the Log tab contains the flight log collected by the
24# \ref mlx.logger.Logger "logger".
25
26#------------------------------------------------------------------------------
27
28class PIREPViewer(gtk.Dialog):
29 """The dialog for PIREP viewing."""
30 @staticmethod
31 def createFrame(label):
32 """Create a frame with the given label.
33
34 The frame will contain an alignment to properly distance the
35 insides. The alignment will contain a VBox to contain the real
36 contents.
37
38 The function returns a tuple with the following items:
39 - the frame,
40 - the inner VBox."""
41 frame = gtk.Frame(label = label)
42
43 alignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
44 xscale = 1.0, yscale = 1.0)
45 frame.add(alignment)
46 alignment.set_padding(padding_top = 4, padding_bottom = 4,
47 padding_left = 4, padding_right = 4)
48 box = gtk.VBox()
49 alignment.add(box)
50
51 return (frame, box)
52
53 @staticmethod
54 def getLabel(text, extraText = ""):
55 """Get a bold label with the given text."""
56 label = gtk.Label("<b>" + text + "</b>" + extraText)
57 label.set_use_markup(True)
58 label.set_alignment(0.0, 0.5)
59 return label
60
61 @staticmethod
62 def getDataLabel(width = None, xAlignment = 0.0):
63 """Get a bold label with the given text."""
64 label = gtk.Label()
65 if width is not None:
66 label.set_width_chars(width)
67 label.set_alignment(xAlignment, 0.5)
68 return label
69
70 @staticmethod
71 def getTextWindow(heightRequest = 40, editable = False):
72 """Get a scrollable text window.
73
74 Returns a tuple of the following items:
75 - the window,
76 - the text view."""
77 scrolledWindow = gtk.ScrolledWindow()
78 scrolledWindow.set_shadow_type(SHADOW_IN)
79 scrolledWindow.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
80
81 textView = gtk.TextView()
82 textView.set_wrap_mode(WRAP_WORD)
83 textView.set_editable(editable)
84 textView.set_cursor_visible(editable)
85 textView.set_size_request(-1, heightRequest)
86 scrolledWindow.add(textView)
87
88 return (scrolledWindow, textView)
89
90 @staticmethod
91 def tableAttach(table, column, row, labelText, width = None,
92 dataLabelXAlignment = 0.0):
93 """Attach a labeled data to the given column and row of the
94 table.
95
96 If width is given, that will be the width of the data
97 label.
98
99 Returns the data label attached."""
100 dataBox = gtk.HBox()
101 table.attach(dataBox, column, column+1, row, row+1)
102
103 dataLabel = PIREPViewer.addLabeledData(dataBox, labelText,
104 width = width)
105 dataLabel.set_alignment(dataLabelXAlignment, 0.5)
106
107 return dataLabel
108
109 @staticmethod
110 def addLabeledData(hBox, labelText, width = None, dataPadding = 8):
111 """Add a label and a data label to the given HBox.
112
113 Returns the data label."""
114 label = PIREPViewer.getLabel(labelText)
115 hBox.pack_start(label, False, False, 0)
116
117 dataLabel = PIREPViewer.getDataLabel(width = width)
118 hBox.pack_start(dataLabel, False, False, dataPadding)
119
120 return dataLabel
121
122 @staticmethod
123 def addHFiller(hBox, width = 8):
124 """Add a filler to the given horizontal box."""
125 filler = gtk.Alignment(xalign = 0.0, yalign = 0.0,
126 xscale = 1.0, yscale = 1.0)
127 filler.set_size_request(width, -1)
128 hBox.pack_start(filler, False, False, 0)
129
130 @staticmethod
131 def addVFiller(vBox, height = 4):
132 """Add a filler to the given vertical box."""
133 filler = gtk.Alignment(xalign = 0.0, yalign = 0.0,
134 xscale = 1.0, yscale = 1.0)
135 filler.set_size_request(-1, height)
136 vBox.pack_start(filler, False, False, 0)
137
138 @staticmethod
139 def timestamp2text(label, timestamp):
140 """Convert the given timestamp into a text containing the hour
141 and minute in UTC and put that text into the given label."""
142 tm = time.gmtime(timestamp)
143 label.set_text("%02d:%02d" % (tm.tm_hour, tm.tm_min))
144
145 def __init__(self, gui):
146 """Construct the PIREP viewer."""
147 super(PIREPViewer, self).__init__(title = WINDOW_TITLE_BASE +
148 " - " +
149 xstr("pirepView_title"),
150 parent = gui.mainWindow)
151
152 self.set_resizable(False)
153
154 self._gui = gui
155
156 contentArea = self.get_content_area()
157
158 self._notebook = gtk.Notebook()
159 contentArea.pack_start(self._notebook, False, False, 4)
160
161 dataTab = self._buildDataTab()
162 label = gtk.Label(xstr("pirepView_tab_data"))
163 label.set_use_underline(True)
164 label.set_tooltip_text(xstr("pirepView_tab_data_tooltip"))
165 self._notebook.append_page(dataTab, label)
166
167 commentsTab = self._buildCommentsTab()
168 label = gtk.Label(xstr("pirepView_tab_comments"))
169 label.set_use_underline(True)
170 label.set_tooltip_text(xstr("pirepView_tab_comments_tooltip"))
171 self._notebook.append_page(commentsTab, label)
172
173 logTab = self._buildLogTab()
174 label = gtk.Label(xstr("pirepView_tab_log"))
175 label.set_use_underline(True)
176 label.set_tooltip_text(xstr("pirepView_tab_log_tooltip"))
177 self._notebook.append_page(logTab, label)
178
179 self._okButton = self.add_button(xstr("button_ok"), RESPONSETYPE_OK)
180 self._okButton.set_can_default(True)
181
182 def setPIREP(self, pirep):
183 """Setup the data in the dialog from the given PIREP."""
184 bookedFlight = pirep.bookedFlight
185
186 self._callsign.set_text(bookedFlight.callsign)
187 self._tailNumber.set_text(bookedFlight.tailNumber)
188 aircraftType = xstr("aircraft_" + icaoCodes[bookedFlight.aircraftType].lower())
189 self._aircraftType.set_text(aircraftType)
190
191 self._departureICAO.set_text(bookedFlight.departureICAO)
192 self._departureTime.set_text("%02d:%02d" % \
193 (bookedFlight.departureTime.hour,
194 bookedFlight.departureTime.minute))
195
196 self._arrivalICAO.set_text(bookedFlight.arrivalICAO)
197 self._arrivalTime.set_text("%02d:%02d" % \
198 (bookedFlight.arrivalTime.hour,
199 bookedFlight.arrivalTime.minute))
200
201 self._numPassengers.set_text(str(bookedFlight.numPassengers))
202 self._numCrew.set_text(str(bookedFlight.numCrew))
203 self._bagWeight.set_text(str(bookedFlight.bagWeight))
204 self._cargoWeight.set_text(str(bookedFlight.cargoWeight))
205 self._mailWeight.set_text(str(bookedFlight.mailWeight))
206
207 self._route.get_buffer().set_text(bookedFlight.route)
208
209 self._filedCruiseLevel.set_text("FL" + str(pirep.filedCruiseAltitude/100))
210
211 if pirep.cruiseAltitude != pirep.filedCruiseAltitude:
212 self._modifiedCruiseLevel.set_text("FL" + str(pirep.cruiseAltitude/100))
213 else:
214 self._modifiedCruiseLevel.set_text("-")
215
216 self._userRoute.get_buffer().set_text(pirep.route)
217
218 self._departureMETAR.get_buffer().set_text(pirep.departureMETAR)
219
220 self._arrivalMETAR.get_buffer().set_text(pirep.arrivalMETAR)
221 self._departureRunway.set_text(pirep.departureRunway)
222 self._sid.set_text(pirep.sid)
223
224 self._star.set_text("-" if pirep.star is None else pirep.star)
225 self._transition.set_text("-" if pirep.transition is None else pirep.transition)
226 self._approachType.set_text(pirep.approachType)
227 self._arrivalRunway.set_text(pirep.arrivalRunway)
228
229 PIREPViewer.timestamp2text(self._blockTimeStart, pirep.blockTimeStart)
230 PIREPViewer.timestamp2text(self._blockTimeEnd, pirep.blockTimeEnd)
231 PIREPViewer.timestamp2text(self._flightTimeStart, pirep.flightTimeStart)
232 PIREPViewer.timestamp2text(self._flightTimeEnd, pirep.flightTimeEnd)
233
234 self._flownDistance.set_text("%.1f" % (pirep.flownDistance,))
235 self._fuelUsed.set_text("%.0f" % (pirep.fuelUsed,))
236
237 rating = pirep.rating
238 if rating<0:
239 self._rating.set_markup('<b><span foreground="red">NO GO</span></b>')
240 else:
241 self._rating.set_text("%.1f %%" % (rating,))
242
243 self._flownNumCrew.set_text("%d" % (pirep.numCrew,))
244 self._flownNumPassengers.set_text("%d" % (pirep.numPassengers,))
245 self._flownBagWeight.set_text("%.0f" % (pirep.bagWeight,))
246 self._flownCargoWeight.set_text("%.0f" % (pirep.cargoWeight,))
247 self._flownMailWeight.set_text("%.0f" % (pirep.mailWeight,))
248 self._flightType.set_text(xstr("flighttype_" +
249 flightType2string(pirep.flightType)))
250 self._online.set_text(xstr("pirepView_" +
251 ("yes" if pirep.online else "no")))
252
253 delayCodes = ""
254 for code in pirep.delayCodes:
255 if delayCodes: delayCodes += ", "
256 delayCodes += code
257
258 self._delayCodes.get_buffer().set_text(delayCodes)
259
260 self._comments.get_buffer().set_text(pirep.comments)
261 self._flightDefects.get_buffer().set_text(pirep.flightDefects)
262
263 logBuffer = self._log.get_buffer()
264 logBuffer.set_text("")
265 lineIndex = 0
266 for (timeStr, line) in pirep.logLines:
267 isFault = lineIndex in pirep.faultLineIndexes
268 appendTextBuffer(logBuffer,
269 formatFlightLogLine(timeStr, line),
270 isFault = isFault)
271 lineIndex += 1
272
273 self._notebook.set_current_page(0)
274 self._okButton.grab_default()
275
276 def _buildDataTab(self):
277 """Build the data tab of the viewer."""
278 table = gtk.Table(1, 2)
279 table.set_row_spacings(4)
280 table.set_col_spacings(16)
281 table.set_homogeneous(True)
282
283 box1 = gtk.VBox()
284 table.attach(box1, 0, 1, 0, 1)
285
286 box2 = gtk.VBox()
287 table.attach(box2, 1, 2, 0, 1)
288
289 flightFrame = self._buildFlightFrame()
290 box1.pack_start(flightFrame, False, False, 4)
291
292 routeFrame = self._buildRouteFrame()
293 box1.pack_start(routeFrame, False, False, 4)
294
295 departureFrame = self._buildDepartureFrame()
296 box2.pack_start(departureFrame, True, True, 4)
297
298 arrivalFrame = self._buildArrivalFrame()
299 box2.pack_start(arrivalFrame, True, True, 4)
300
301 statisticsFrame = self._buildStatisticsFrame()
302 box2.pack_start(statisticsFrame, False, False, 4)
303
304 miscellaneousFrame = self._buildMiscellaneousFrame()
305 box1.pack_start(miscellaneousFrame, False, False, 4)
306
307 return table
308
309 def _buildFlightFrame(self):
310 """Build the frame for the flight data."""
311
312 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight"))
313
314 dataBox = gtk.HBox()
315 mainBox.pack_start(dataBox, False, False, 0)
316
317 self._callsign = \
318 PIREPViewer.addLabeledData(dataBox,
319 xstr("pirepView_callsign"),
320 width = 8)
321
322 self._tailNumber = \
323 PIREPViewer.addLabeledData(dataBox,
324 xstr("pirepView_tailNumber"),
325 width = 7)
326
327 PIREPViewer.addVFiller(mainBox)
328
329 dataBox = gtk.HBox()
330 mainBox.pack_start(dataBox, False, False, 0)
331
332 self._aircraftType = \
333 PIREPViewer.addLabeledData(dataBox,
334 xstr("pirepView_aircraftType"),
335 width = 25)
336
337 PIREPViewer.addVFiller(mainBox)
338
339 table = gtk.Table(3, 2)
340 mainBox.pack_start(table, False, False, 0)
341 table.set_row_spacings(4)
342 table.set_col_spacings(8)
343
344 self._departureICAO = \
345 PIREPViewer.tableAttach(table, 0, 0,
346 xstr("pirepView_departure"),
347 width = 5)
348
349 self._departureTime = \
350 PIREPViewer.tableAttach(table, 1, 0,
351 xstr("pirepView_departure_time"),
352 width = 6)
353
354 self._arrivalICAO = \
355 PIREPViewer.tableAttach(table, 0, 1,
356 xstr("pirepView_arrival"),
357 width = 5)
358
359 self._arrivalTime = \
360 PIREPViewer.tableAttach(table, 1, 1,
361 xstr("pirepView_arrival_time"),
362 width = 6)
363
364 table = gtk.Table(3, 2)
365 mainBox.pack_start(table, False, False, 0)
366 table.set_row_spacings(4)
367 table.set_col_spacings(8)
368
369 self._numPassengers = \
370 PIREPViewer.tableAttach(table, 0, 0,
371 xstr("pirepView_numPassengers"),
372 width = 4)
373
374 self._numCrew = \
375 PIREPViewer.tableAttach(table, 1, 0,
376 xstr("pirepView_numCrew"),
377 width = 3)
378
379 self._bagWeight = \
380 PIREPViewer.tableAttach(table, 0, 1,
381 xstr("pirepView_bagWeight"),
382 width = 5)
383
384 self._cargoWeight = \
385 PIREPViewer.tableAttach(table, 1, 1,
386 xstr("pirepView_cargoWeight"),
387 width = 5)
388
389 self._mailWeight = \
390 PIREPViewer.tableAttach(table, 2, 1,
391 xstr("pirepView_mailWeight"),
392 width = 5)
393
394 PIREPViewer.addVFiller(mainBox)
395
396 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")),
397 False, False, 0)
398
399 (routeWindow, self._route) = PIREPViewer.getTextWindow()
400 mainBox.pack_start(routeWindow, False, False, 0)
401
402 return frame
403
404 def _buildRouteFrame(self):
405 """Build the frame for the user-specified route and flight
406 level."""
407
408 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route"))
409
410 levelBox = gtk.HBox()
411 mainBox.pack_start(levelBox, False, False, 0)
412
413 self._filedCruiseLevel = \
414 PIREPViewer.addLabeledData(levelBox,
415 xstr("pirepView_filedCruiseLevel"),
416 width = 6)
417
418 self._modifiedCruiseLevel = \
419 PIREPViewer.addLabeledData(levelBox,
420 xstr("pirepView_modifiedCruiseLevel"),
421 width = 6)
422
423 PIREPViewer.addVFiller(mainBox)
424
425 (routeWindow, self._userRoute) = PIREPViewer.getTextWindow()
426 mainBox.pack_start(routeWindow, False, False, 0)
427
428 return frame
429
430 def _buildDepartureFrame(self):
431 """Build the frame for the departure data."""
432 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_departure"))
433
434 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
435 False, False, 0)
436 (metarWindow, self._departureMETAR) = \
437 PIREPViewer.getTextWindow(heightRequest = -1)
438 mainBox.pack_start(metarWindow, True, True, 0)
439
440 PIREPViewer.addVFiller(mainBox)
441
442 dataBox = gtk.HBox()
443 mainBox.pack_start(dataBox, False, False, 0)
444
445 self._departureRunway = \
446 PIREPViewer.addLabeledData(dataBox,
447 xstr("pirepView_runway"),
448 width = 5)
449
450 self._sid = \
451 PIREPViewer.addLabeledData(dataBox,
452 xstr("pirepView_sid"),
453 width = 12)
454
455 return frame
456
457 def _buildArrivalFrame(self):
458 """Build the frame for the arrival data."""
459 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_arrival"))
460
461 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
462 False, False, 0)
463 (metarWindow, self._arrivalMETAR) = \
464 PIREPViewer.getTextWindow(heightRequest = -1)
465 mainBox.pack_start(metarWindow, True, True, 0)
466
467 PIREPViewer.addVFiller(mainBox)
468
469 table = gtk.Table(2, 2)
470 mainBox.pack_start(table, False, False, 0)
471 table.set_row_spacings(4)
472 table.set_col_spacings(8)
473
474 self._star = \
475 PIREPViewer.tableAttach(table, 0, 0,
476 xstr("pirepView_star"),
477 width = 12)
478
479 self._transition = \
480 PIREPViewer.tableAttach(table, 1, 0,
481 xstr("pirepView_transition"),
482 width = 12)
483
484 self._approachType = \
485 PIREPViewer.tableAttach(table, 0, 1,
486 xstr("pirepView_approachType"),
487 width = 7)
488
489 self._arrivalRunway = \
490 PIREPViewer.tableAttach(table, 1, 1,
491 xstr("pirepView_runway"),
492 width = 5)
493
494 return frame
495
496 def _buildStatisticsFrame(self):
497 """Build the frame for the statistics data."""
498 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_statistics"))
499
500 table = gtk.Table(4, 2)
501 mainBox.pack_start(table, False, False, 0)
502 table.set_row_spacings(4)
503 table.set_col_spacings(8)
504 table.set_homogeneous(False)
505
506 self._blockTimeStart = \
507 PIREPViewer.tableAttach(table, 0, 0,
508 xstr("pirepView_blockTimeStart"),
509 width = 6)
510
511 self._blockTimeEnd = \
512 PIREPViewer.tableAttach(table, 1, 0,
513 xstr("pirepView_blockTimeEnd"),
514 width = 8)
515
516 self._flightTimeStart = \
517 PIREPViewer.tableAttach(table, 0, 1,
518 xstr("pirepView_flightTimeStart"),
519 width = 6)
520
521 self._flightTimeEnd = \
522 PIREPViewer.tableAttach(table, 1, 1,
523 xstr("pirepView_flightTimeEnd"),
524 width = 6)
525
526 self._flownDistance = \
527 PIREPViewer.tableAttach(table, 0, 2,
528 xstr("pirepView_flownDistance"),
529 width = 8)
530
531 self._fuelUsed = \
532 PIREPViewer.tableAttach(table, 1, 2,
533 xstr("pirepView_fuelUsed"),
534 width = 6)
535
536 self._rating = \
537 PIREPViewer.tableAttach(table, 0, 3,
538 xstr("pirepView_rating"),
539 width = 7)
540 return frame
541
542 def _buildMiscellaneousFrame(self):
543 """Build the frame for the miscellaneous data."""
544 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous"))
545
546 table = gtk.Table(3, 2)
547 mainBox.pack_start(table, False, False, 0)
548 table.set_row_spacings(4)
549 table.set_col_spacings(8)
550
551 self._flownNumPassengers = \
552 PIREPViewer.tableAttach(table, 0, 0,
553 xstr("pirepView_numPassengers"),
554 width = 4)
555
556 self._flownNumCrew = \
557 PIREPViewer.tableAttach(table, 1, 0,
558 xstr("pirepView_numCrew"),
559 width = 3)
560
561 self._flownBagWeight = \
562 PIREPViewer.tableAttach(table, 0, 1,
563 xstr("pirepView_bagWeight"),
564 width = 5)
565
566 self._flownCargoWeight = \
567 PIREPViewer.tableAttach(table, 1, 1,
568 xstr("pirepView_cargoWeight"),
569 width = 6)
570
571 self._flownMailWeight = \
572 PIREPViewer.tableAttach(table, 2, 1,
573 xstr("pirepView_mailWeight"),
574 width = 5)
575
576 self._flightType = \
577 PIREPViewer.tableAttach(table, 0, 2,
578 xstr("pirepView_flightType"),
579 width = 15)
580
581 self._online = \
582 PIREPViewer.tableAttach(table, 1, 2,
583 xstr("pirepView_online"),
584 width = 5)
585
586 PIREPViewer.addVFiller(mainBox)
587
588 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")),
589 False, False, 0)
590
591 (textWindow, self._delayCodes) = PIREPViewer.getTextWindow()
592 mainBox.pack_start(textWindow, False, False, 0)
593
594 return frame
595
596 def _buildCommentsTab(self):
597 """Build the tab with the comments and flight defects."""
598 table = gtk.Table(2, 1)
599 table.set_col_spacings(16)
600
601 (frame, commentsBox) = \
602 PIREPViewer.createFrame(xstr("pirepView_comments"))
603 table.attach(frame, 0, 1, 0, 1)
604
605 (commentsWindow, self._comments) = \
606 PIREPViewer.getTextWindow(heightRequest = -1)
607 commentsBox.pack_start(commentsWindow, True, True, 0)
608
609 (frame, flightDefectsBox) = \
610 PIREPViewer.createFrame(xstr("pirepView_flightDefects"))
611 table.attach(frame, 1, 2, 0, 1)
612
613 (flightDefectsWindow, self._flightDefects) = \
614 PIREPViewer.getTextWindow(heightRequest = -1)
615 flightDefectsBox.pack_start(flightDefectsWindow, True, True, 0)
616
617 return table
618
619 def _buildLogTab(self):
620 """Build the log tab."""
621 mainBox = gtk.VBox()
622
623 (logWindow, self._log) = PIREPViewer.getTextWindow(heightRequest = -1)
624 addFaultTag(self._log.get_buffer())
625 mainBox.pack_start(logWindow, True, True, 0)
626
627 return mainBox
628
629#------------------------------------------------------------------------------
630
631class PIREPEditor(gtk.Dialog):
632 """A PIREP editor dialog."""
633 _delayCodeRE = re.compile("([0-9]{2,3})( \([^\)]*\))")
634
635 @staticmethod
636 def tableAttachWidget(table, column, row, labelText, widget):
637 """Attach the given widget with the given label to the given table.
638
639 The label will got to cell (column, row), the widget to cell
640 (column+1, row)."""
641 label = gtk.Label("<b>" + labelText + "</b>")
642 label.set_use_markup(True)
643 alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
644 xscale = 0.0, yscale = 0.0)
645 alignment.add(label)
646 table.attach(alignment, column, column + 1, row, row + 1)
647
648 table.attach(widget, column + 1, column + 2, row, row + 1)
649
650 @staticmethod
651 def tableAttachSpinButton(table, column, row, labelText, maxValue,
652 minValue = 0, stepIncrement = 1,
653 pageIncrement = 10, numeric = True,
654 width = 3):
655 """Attach a spin button with the given label to the given table.
656
657 The label will got to cell (column, row), the spin button to cell
658 (column+1, row)."""
659 button = gtk.SpinButton()
660 button.set_range(min = minValue, max = maxValue)
661 button.set_increments(step = stepIncrement, page = pageIncrement)
662 button.set_numeric(True)
663 button.set_width_chars(width)
664 button.set_alignment(1.0)
665
666 PIREPEditor.tableAttachWidget(table, column, row, labelText, button)
667
668 return button
669
670 @staticmethod
671 def tableAttachTimeEntry(table, column, row, labelText):
672 """Attach a time entry widget with the given label to the given table.
673
674 The label will got to cell (column, row), the spin button to cell
675 (column+1, row)."""
676 entry = TimeEntry()
677 entry.set_width_chars(5)
678 entry.set_alignment(1.0)
679
680 PIREPEditor.tableAttachWidget(table, column, row, labelText, entry)
681
682 return entry
683
684 def __init__(self, gui):
685 """Construct the PIREP viewer."""
686 super(PIREPEditor, self).__init__(title = WINDOW_TITLE_BASE +
687 " - " +
688 xstr("pirepEdit_title"),
689 parent = gui.mainWindow)
690
691 self.set_resizable(False)
692
693 self._gui = gui
694
695 self._pirep = None
696
697 contentArea = self.get_content_area()
698
699 self._notebook = gtk.Notebook()
700 contentArea.pack_start(self._notebook, False, False, 4)
701
702 dataTab = self._buildDataTab()
703 label = gtk.Label(xstr("pirepView_tab_data"))
704 label.set_use_underline(True)
705 label.set_tooltip_text(xstr("pirepView_tab_data_tooltip"))
706 self._notebook.append_page(dataTab, label)
707
708 self._flightInfo = self._buildCommentsTab()
709 label = gtk.Label(xstr("pirepView_tab_comments"))
710 label.set_use_underline(True)
711 label.set_tooltip_text(xstr("pirepView_tab_comments_tooltip"))
712 self._notebook.append_page(self._flightInfo, label)
713
714 logTab = self._buildLogTab()
715 label = gtk.Label(xstr("pirepView_tab_log"))
716 label.set_use_underline(True)
717 label.set_tooltip_text(xstr("pirepView_tab_log_tooltip"))
718 self._notebook.append_page(logTab, label)
719
720 self.add_button(xstr("button_cancel"), RESPONSETYPE_CANCEL)
721
722 self._okButton = self.add_button(xstr("button_save"), RESPONSETYPE_OK)
723 self._okButton.set_can_default(True)
724
725 def setPIREP(self, pirep):
726 """Setup the data in the dialog from the given PIREP."""
727 self._pirep = pirep
728
729 bookedFlight = pirep.bookedFlight
730
731 self._callsign.set_text(bookedFlight.callsign)
732 self._tailNumber.set_text(bookedFlight.tailNumber)
733 aircraftType = xstr("aircraft_" + icaoCodes[bookedFlight.aircraftType].lower())
734 self._aircraftType.set_text(aircraftType)
735
736 self._departureICAO.set_text(bookedFlight.departureICAO)
737 self._departureTime.set_text("%02d:%02d" % \
738 (bookedFlight.departureTime.hour,
739 bookedFlight.departureTime.minute))
740
741 self._arrivalICAO.set_text(bookedFlight.arrivalICAO)
742 self._arrivalTime.set_text("%02d:%02d" % \
743 (bookedFlight.arrivalTime.hour,
744 bookedFlight.arrivalTime.minute))
745
746 self._numPassengers.set_text(str(bookedFlight.numPassengers))
747 self._numCrew.set_text(str(bookedFlight.numCrew))
748 self._bagWeight.set_text(str(bookedFlight.bagWeight))
749 self._cargoWeight.set_text(str(bookedFlight.cargoWeight))
750 self._mailWeight.set_text(str(bookedFlight.mailWeight))
751
752 self._route.get_buffer().set_text(bookedFlight.route)
753
754 self._filedCruiseLevel.set_value(pirep.filedCruiseAltitude/100)
755 self._modifiedCruiseLevel.set_value(pirep.cruiseAltitude/100)
756
757 self._userRoute.get_buffer().set_text(pirep.route)
758
759 self._departureMETAR.get_buffer().set_text(pirep.departureMETAR)
760
761 self._arrivalMETAR.get_buffer().set_text(pirep.arrivalMETAR)
762 self._departureRunway.set_text(pirep.departureRunway)
763 self._sid.get_child().set_text(pirep.sid)
764
765 if not pirep.star:
766 self._star.set_active(0)
767 else:
768 self._star.get_child().set_text(pirep.star)
769
770 if not pirep.transition:
771 self._transition.set_active(0)
772 else:
773 self._transition.get_child().set_text(pirep.transition)
774 self._approachType.set_text(pirep.approachType)
775 self._arrivalRunway.set_text(pirep.arrivalRunway)
776
777 self._blockTimeStart.setTimestamp(pirep.blockTimeStart)
778 self._blockTimeEnd.setTimestamp(pirep.blockTimeEnd)
779 self._flightTimeStart.setTimestamp(pirep.flightTimeStart)
780 self._flightTimeEnd.setTimestamp(pirep.flightTimeEnd)
781
782 self._flownDistance.set_text("%.1f" % (pirep.flownDistance,))
783 self._fuelUsed.set_value(int(pirep.fuelUsed))
784
785 rating = pirep.rating
786 if rating<0:
787 self._rating.set_markup('<b><span foreground="red">NO GO</span></b>')
788 else:
789 self._rating.set_text("%.1f %%" % (rating,))
790
791 self._flownNumCrew.set_value(pirep.numCrew)
792 self._flownNumPassengers.set_value(pirep.numPassengers)
793 self._flownBagWeight.set_value(pirep.bagWeight)
794 self._flownCargoWeight.set_value(pirep.cargoWeight)
795 self._flownMailWeight.set_value(pirep.mailWeight)
796 self._flightType.set_active(flightType2index(pirep.flightType))
797 self._online.set_active(pirep.online)
798
799 self._flightInfo.reset()
800 self._flightInfo.enable(bookedFlight.aircraftType)
801
802 delayCodes = ""
803 for code in pirep.delayCodes:
804 if delayCodes: delayCodes += ", "
805 delayCodes += code
806 m = PIREPEditor._delayCodeRE.match(code)
807 if m:
808 self._flightInfo.activateDelayCode(m.group(1))
809
810 self._delayCodes.get_buffer().set_text(delayCodes)
811
812 self._flightInfo.comments = pirep.comments
813 if pirep.flightDefects.find("<br/></b>")!=-1:
814 flightDefects = pirep.flightDefects.split("<br/></b>")
815 caption = flightDefects[0]
816 index = 0
817 for defect in flightDefects[1:]:
818 if defect.find("<b>")!=-1:
819 (explanation, nextCaption) = defect.split("<b>")
820 else:
821 explanation = defect
822 nextCaption = None
823 self._flightInfo.addFault(index, caption)
824 self._flightInfo.setExplanation(index, explanation)
825 index += 1
826 caption = nextCaption
827
828 # self._comments.get_buffer().set_text(pirep.comments)
829 # self._flightDefects.get_buffer().set_text(pirep.flightDefects)
830
831 logBuffer = self._log.get_buffer()
832 logBuffer.set_text("")
833 lineIndex = 0
834 for (timeStr, line) in pirep.logLines:
835 isFault = lineIndex in pirep.faultLineIndexes
836 appendTextBuffer(logBuffer,
837 formatFlightLogLine(timeStr, line),
838 isFault = isFault)
839 lineIndex += 1
840
841 self._notebook.set_current_page(0)
842 self._okButton.grab_default()
843
844 self._updateButtons()
845
846 def delayCodesChanged(self):
847 """Called when the delay codes have changed."""
848 self._updateButtons()
849
850 def commentsChanged(self):
851 """Called when the comments have changed."""
852 self._updateButtons()
853
854 def faultExplanationsChanged(self):
855 """Called when the fault explanations have changed."""
856 self._updateButtons()
857
858 def _buildDataTab(self):
859 """Build the data tab of the viewer."""
860 table = gtk.Table(1, 2)
861 table.set_row_spacings(4)
862 table.set_col_spacings(16)
863 table.set_homogeneous(True)
864
865 box1 = gtk.VBox()
866 table.attach(box1, 0, 1, 0, 1)
867
868 box2 = gtk.VBox()
869 table.attach(box2, 1, 2, 0, 1)
870
871 flightFrame = self._buildFlightFrame()
872 box1.pack_start(flightFrame, False, False, 4)
873
874 routeFrame = self._buildRouteFrame()
875 box1.pack_start(routeFrame, False, False, 4)
876
877 departureFrame = self._buildDepartureFrame()
878 box2.pack_start(departureFrame, True, True, 4)
879
880 arrivalFrame = self._buildArrivalFrame()
881 box2.pack_start(arrivalFrame, True, True, 4)
882
883 statisticsFrame = self._buildStatisticsFrame()
884 box2.pack_start(statisticsFrame, False, False, 4)
885
886 miscellaneousFrame = self._buildMiscellaneousFrame()
887 box1.pack_start(miscellaneousFrame, False, False, 4)
888
889 return table
890
891 def _buildFlightFrame(self):
892 """Build the frame for the flight data."""
893
894 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight"))
895
896 dataBox = gtk.HBox()
897 mainBox.pack_start(dataBox, False, False, 0)
898
899 self._callsign = \
900 PIREPViewer.addLabeledData(dataBox,
901 xstr("pirepView_callsign"),
902 width = 8)
903
904 self._tailNumber = \
905 PIREPViewer.addLabeledData(dataBox,
906 xstr("pirepView_tailNumber"),
907 width = 7)
908
909 PIREPViewer.addVFiller(mainBox)
910
911 dataBox = gtk.HBox()
912 mainBox.pack_start(dataBox, False, False, 0)
913
914 self._aircraftType = \
915 PIREPViewer.addLabeledData(dataBox,
916 xstr("pirepView_aircraftType"),
917 width = 25)
918
919 PIREPViewer.addVFiller(mainBox)
920
921 table = gtk.Table(3, 2)
922 mainBox.pack_start(table, False, False, 0)
923 table.set_row_spacings(4)
924 table.set_col_spacings(8)
925
926 self._departureICAO = \
927 PIREPViewer.tableAttach(table, 0, 0,
928 xstr("pirepView_departure"),
929 width = 5)
930
931 self._departureTime = \
932 PIREPViewer.tableAttach(table, 1, 0,
933 xstr("pirepView_departure_time"),
934 width = 6)
935
936 self._arrivalICAO = \
937 PIREPViewer.tableAttach(table, 0, 1,
938 xstr("pirepView_arrival"),
939 width = 5)
940
941 self._arrivalTime = \
942 PIREPViewer.tableAttach(table, 1, 1,
943 xstr("pirepView_arrival_time"),
944 width = 6)
945
946 table = gtk.Table(3, 2)
947 mainBox.pack_start(table, False, False, 0)
948 table.set_row_spacings(4)
949 table.set_col_spacings(8)
950
951 self._numPassengers = \
952 PIREPViewer.tableAttach(table, 0, 0,
953 xstr("pirepView_numPassengers"),
954 width = 4)
955 self._numCrew = \
956 PIREPViewer.tableAttach(table, 1, 0,
957 xstr("pirepView_numCrew"),
958 width = 3)
959
960 self._bagWeight = \
961 PIREPViewer.tableAttach(table, 0, 1,
962 xstr("pirepView_bagWeight"),
963 width = 5)
964
965 self._cargoWeight = \
966 PIREPViewer.tableAttach(table, 1, 1,
967 xstr("pirepView_cargoWeight"),
968 width = 5)
969
970 self._mailWeight = \
971 PIREPViewer.tableAttach(table, 2, 1,
972 xstr("pirepView_mailWeight"),
973 width = 5)
974
975 PIREPViewer.addVFiller(mainBox)
976
977 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")),
978 False, False, 0)
979
980 (routeWindow, self._route) = PIREPViewer.getTextWindow()
981 mainBox.pack_start(routeWindow, False, False, 0)
982
983 return frame
984
985 def _buildRouteFrame(self):
986 """Build the frame for the user-specified route and flight
987 level."""
988
989 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route"))
990
991 levelBox = gtk.HBox()
992 mainBox.pack_start(levelBox, False, False, 0)
993
994 label = PIREPViewer.getLabel(xstr("pirepView_filedCruiseLevel"),
995 xstr("pirepEdit_FL"))
996 levelBox.pack_start(label, False, False, 0)
997
998 self._filedCruiseLevel = gtk.SpinButton()
999 self._filedCruiseLevel.set_increments(step = 10, page = 100)
1000 self._filedCruiseLevel.set_range(min = 0, max = 500)
1001 self._filedCruiseLevel.set_tooltip_text(xstr("route_level_tooltip"))
1002 self._filedCruiseLevel.set_numeric(True)
1003 self._filedCruiseLevel.connect("value-changed", self._updateButtons)
1004
1005 levelBox.pack_start(self._filedCruiseLevel, False, False, 0)
1006
1007 PIREPViewer.addHFiller(levelBox)
1008
1009 label = PIREPViewer.getLabel(xstr("pirepView_modifiedCruiseLevel"),
1010 xstr("pirepEdit_FL"))
1011 levelBox.pack_start(label, False, False, 0)
1012
1013 self._modifiedCruiseLevel = gtk.SpinButton()
1014 self._modifiedCruiseLevel.set_increments(step = 10, page = 100)
1015 self._modifiedCruiseLevel.set_range(min = 0, max = 500)
1016 self._modifiedCruiseLevel.set_tooltip_text(xstr("pirepEdit_modified_route_level_tooltip"))
1017 self._modifiedCruiseLevel.set_numeric(True)
1018 self._modifiedCruiseLevel.connect("value-changed", self._updateButtons)
1019
1020 levelBox.pack_start(self._modifiedCruiseLevel, False, False, 0)
1021
1022 PIREPViewer.addVFiller(mainBox)
1023
1024 (routeWindow, self._userRoute) = \
1025 PIREPViewer.getTextWindow(editable = True)
1026 mainBox.pack_start(routeWindow, False, False, 0)
1027 self._userRoute.get_buffer().connect("changed", self._updateButtons)
1028 self._userRoute.set_tooltip_text(xstr("route_route_tooltip"))
1029
1030 return frame
1031
1032 def _buildDepartureFrame(self):
1033 """Build the frame for the departure data."""
1034 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_departure"))
1035
1036 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
1037 False, False, 0)
1038 (metarWindow, self._departureMETAR) = \
1039 PIREPViewer.getTextWindow(heightRequest = -1,
1040 editable = True)
1041 self._departureMETAR.get_buffer().connect("changed", self._updateButtons)
1042 self._departureMETAR.set_tooltip_text(xstr("takeoff_metar_tooltip"))
1043 mainBox.pack_start(metarWindow, True, True, 0)
1044
1045 PIREPViewer.addVFiller(mainBox)
1046
1047 dataBox = gtk.HBox()
1048 mainBox.pack_start(dataBox, False, False, 0)
1049
1050 label = gtk.Label("<b>" + xstr("pirepView_runway") + "</b>")
1051 label.set_use_markup(True)
1052 dataBox.pack_start(label, False, False, 0)
1053
1054 # FIXME: quite the same as the runway entry boxes in the wizard
1055 self._departureRunway = gtk.Entry()
1056 self._departureRunway.set_width_chars(5)
1057 self._departureRunway.set_tooltip_text(xstr("takeoff_runway_tooltip"))
1058 self._departureRunway.connect("changed", self._upperChanged)
1059 dataBox.pack_start(self._departureRunway, False, False, 8)
1060
1061 label = gtk.Label("<b>" + xstr("pirepView_sid") + "</b>")
1062 label.set_use_markup(True)
1063 dataBox.pack_start(label, False, False, 0)
1064
1065 # FIXME: quite the same as the SID combo box in
1066 # the flight wizard
1067 if pygobject:
1068 self._sid = gtk.ComboBox.new_with_model_and_entry(comboModel)
1069 else:
1070 self._sid = gtk.ComboBoxEntry(comboModel)
1071
1072 self._sid.set_entry_text_column(0)
1073 self._sid.get_child().set_width_chars(10)
1074 self._sid.set_tooltip_text(xstr("takeoff_sid_tooltip"))
1075 self._sid.connect("changed", self._upperChangedComboBox)
1076
1077 dataBox.pack_start(self._sid, False, False, 8)
1078
1079 return frame
1080
1081 def _buildArrivalFrame(self):
1082 """Build the frame for the arrival data."""
1083 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_arrival"))
1084
1085 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
1086 False, False, 0)
1087 (metarWindow, self._arrivalMETAR) = \
1088 PIREPViewer.getTextWindow(heightRequest = -1,
1089 editable = True)
1090 self._arrivalMETAR.get_buffer().connect("changed", self._updateButtons)
1091 self._arrivalMETAR.set_tooltip_text(xstr("landing_metar_tooltip"))
1092 mainBox.pack_start(metarWindow, True, True, 0)
1093
1094 PIREPViewer.addVFiller(mainBox)
1095
1096 table = gtk.Table(2, 4)
1097 mainBox.pack_start(table, False, False, 0)
1098 table.set_row_spacings(4)
1099 table.set_col_spacings(8)
1100
1101 # FIXME: quite the same as in the wizard
1102 if pygobject:
1103 self._star = gtk.ComboBox.new_with_model_and_entry(comboModel)
1104 else:
1105 self._star = gtk.ComboBoxEntry(comboModel)
1106
1107 self._star.set_entry_text_column(0)
1108 self._star.get_child().set_width_chars(10)
1109 self._star.set_tooltip_text(xstr("landing_star_tooltip"))
1110 self._star.connect("changed", self._upperChangedComboBox)
1111
1112 PIREPEditor.tableAttachWidget(table, 0, 0,
1113 xstr("pirepView_star"),
1114 self._star)
1115
1116 # FIXME: quite the same as in the wizard
1117 if pygobject:
1118 self._transition = gtk.ComboBox.new_with_model_and_entry(comboModel)
1119 else:
1120 self._transition = gtk.ComboBoxEntry(comboModel)
1121
1122 self._transition.set_entry_text_column(0)
1123 self._transition.get_child().set_width_chars(10)
1124 self._transition.set_tooltip_text(xstr("landing_transition_tooltip"))
1125 self._transition.connect("changed", self._upperChangedComboBox)
1126
1127 PIREPEditor.tableAttachWidget(table, 2, 0,
1128 xstr("pirepView_transition"),
1129 self._transition)
1130
1131
1132 # FIXME: quite the same as in the wizard
1133 self._approachType = gtk.Entry()
1134 self._approachType.set_width_chars(10)
1135 self._approachType.set_tooltip_text(xstr("landing_approach_tooltip"))
1136 self._approachType.connect("changed", self._upperChanged)
1137
1138 PIREPEditor.tableAttachWidget(table, 0, 1,
1139 xstr("pirepView_approachType"),
1140 self._approachType)
1141
1142 # FIXME: quite the same as in the wizard
1143 self._arrivalRunway = gtk.Entry()
1144 self._arrivalRunway.set_width_chars(10)
1145 self._arrivalRunway.set_tooltip_text(xstr("landing_runway_tooltip"))
1146 self._arrivalRunway.connect("changed", self._upperChanged)
1147
1148 PIREPEditor.tableAttachWidget(table, 2, 1,
1149 xstr("pirepView_runway"),
1150 self._arrivalRunway)
1151
1152 return frame
1153
1154 def _buildStatisticsFrame(self):
1155 """Build the frame for the statistics data."""
1156 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_statistics"))
1157
1158 table = gtk.Table(4, 4)
1159 mainBox.pack_start(table, False, False, 0)
1160 table.set_row_spacings(4)
1161 table.set_col_spacings(8)
1162 table.set_homogeneous(False)
1163
1164 self._blockTimeStart = \
1165 PIREPEditor.tableAttachTimeEntry(table, 0, 0,
1166 xstr("pirepView_blockTimeStart"))
1167 self._blockTimeStart.connect("changed", self._updateButtons)
1168 self._blockTimeStart.set_tooltip_text(xstr("pirepEdit_block_time_start_tooltip"))
1169
1170 self._blockTimeEnd = \
1171 PIREPEditor.tableAttachTimeEntry(table, 2, 0,
1172 xstr("pirepView_blockTimeEnd"))
1173 self._blockTimeEnd.connect("changed", self._updateButtons)
1174 self._blockTimeEnd.set_tooltip_text(xstr("pirepEdit_block_time_end_tooltip"))
1175
1176 self._flightTimeStart = \
1177 PIREPEditor.tableAttachTimeEntry(table, 0, 1,
1178 xstr("pirepView_flightTimeStart"))
1179 self._flightTimeStart.connect("changed", self._updateButtons)
1180 self._flightTimeStart.set_tooltip_text(xstr("pirepEdit_flight_time_start_tooltip"))
1181
1182 self._flightTimeEnd = \
1183 PIREPEditor.tableAttachTimeEntry(table, 2, 1,
1184 xstr("pirepView_flightTimeEnd"))
1185 self._flightTimeEnd.connect("changed", self._updateButtons)
1186 self._flightTimeEnd.set_tooltip_text(xstr("pirepEdit_flight_time_end_tooltip"))
1187
1188 self._flownDistance = PIREPViewer.getDataLabel(width = 3)
1189 PIREPEditor.tableAttachWidget(table, 0, 2,
1190 xstr("pirepView_flownDistance"),
1191 self._flownDistance)
1192
1193 self._fuelUsed = \
1194 PIREPEditor.tableAttachSpinButton(table, 2, 2,
1195 xstr("pirepView_fuelUsed"),
1196 1000000)
1197 self._fuelUsed.connect("value-changed", self._updateButtons)
1198 self._fuelUsed.set_tooltip_text(xstr("pirepEdit_fuel_used_tooltip"))
1199
1200 self._rating = PIREPViewer.getDataLabel(width = 3)
1201 PIREPEditor.tableAttachWidget(table, 0, 3,
1202 xstr("pirepView_rating"),
1203 self._rating)
1204 return frame
1205
1206 def _buildMiscellaneousFrame(self):
1207 """Build the frame for the miscellaneous data."""
1208 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous"))
1209
1210 table = gtk.Table(6, 2)
1211 mainBox.pack_start(table, False, False, 0)
1212 table.set_row_spacings(4)
1213 table.set_col_spacings(8)
1214 table.set_homogeneous(False)
1215
1216 self._flownNumPassengers = \
1217 PIREPEditor.tableAttachSpinButton(table, 0, 0,
1218 xstr("pirepView_numPassengers"),
1219 300)
1220 self._flownNumPassengers.connect("value-changed", self._updateButtons)
1221 self._flownNumPassengers.set_tooltip_text(xstr("payload_pax_tooltip"))
1222
1223 self._flownNumCrew = \
1224 PIREPEditor.tableAttachSpinButton(table, 2, 0,
1225 xstr("pirepView_numCrew"),
1226 10)
1227 self._flownNumCrew.connect("value-changed", self._updateButtons)
1228 self._flownNumCrew.set_tooltip_text(xstr("payload_crew_tooltip"))
1229
1230 self._flownBagWeight = \
1231 PIREPEditor.tableAttachSpinButton(table, 0, 1,
1232 xstr("pirepView_bagWeight"),
1233 100000, width = 6)
1234 self._flownBagWeight.set_tooltip_text(xstr("payload_bag_tooltip"))
1235
1236 self._flownCargoWeight = \
1237 PIREPEditor.tableAttachSpinButton(table, 2, 1,
1238 xstr("pirepView_cargoWeight"),
1239 100000, width = 6)
1240 self._flownCargoWeight.set_tooltip_text(xstr("payload_cargo_tooltip"))
1241
1242 self._flownMailWeight = \
1243 PIREPEditor.tableAttachSpinButton(table, 4, 1,
1244 xstr("pirepView_mailWeight"),
1245 100000, width = 6)
1246 self._flownMailWeight.set_tooltip_text(xstr("payload_mail_tooltip"))
1247
1248 self._flightType = createFlightTypeComboBox()
1249 PIREPEditor.tableAttachWidget(table, 0, 2,
1250 xstr("pirepView_flightType"),
1251 self._flightType)
1252 self._flightType.set_tooltip_text(xstr("pirepEdit_flight_type_tooltip"))
1253
1254 self._online = gtk.CheckButton(xstr("pirepEdit_online"))
1255 table.attach(self._online, 2, 3, 2, 3)
1256 self._online.set_tooltip_text(xstr("pirepEdit_online_tooltip"))
1257
1258 PIREPViewer.addVFiller(mainBox)
1259
1260 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")),
1261 False, False, 0)
1262
1263 (textWindow, self._delayCodes) = PIREPViewer.getTextWindow()
1264 mainBox.pack_start(textWindow, False, False, 0)
1265 self._delayCodes.set_tooltip_text(xstr("pirepEdit_delayCodes_tooltip"))
1266
1267 return frame
1268
1269 def _buildCommentsTab(self):
1270 """Build the tab with the comments and flight defects."""
1271 return FlightInfo(self._gui, callbackObject = self)
1272
1273 def _buildLogTab(self):
1274 """Build the log tab."""
1275 mainBox = gtk.VBox()
1276
1277 (logWindow, self._log) = PIREPViewer.getTextWindow(heightRequest = -1)
1278 addFaultTag(self._log.get_buffer())
1279 mainBox.pack_start(logWindow, True, True, 0)
1280
1281 return mainBox
1282
1283 def _upperChanged(self, entry, arg = None):
1284 """Called when the value of some entry widget has changed and the value
1285 should be converted to uppercase."""
1286 entry.set_text(entry.get_text().upper())
1287 self._updateButtons()
1288 #self._valueChanged(entry, arg)
1289
1290 def _upperChangedComboBox(self, comboBox):
1291 """Called for combo box widgets that must be converted to uppercase."""
1292 entry = comboBox.get_child()
1293 if comboBox.get_active()==-1:
1294 entry.set_text(entry.get_text().upper())
1295 self._updateButtons()
1296 #self._valueChanged(entry)
1297
1298 def _updateButtons(self, *kwargs):
1299 """Update the activity state of the buttons."""
1300 pirep = self._pirep
1301 bookedFlight = pirep.bookedFlight
1302
1303 departureMinutes = \
1304 bookedFlight.departureTime.hour*60 + bookedFlight.departureTime.minute
1305 departureDifference = abs(Flight.getMinutesDifference(self._blockTimeStart.minutes,
1306 departureMinutes))
1307 flightStartDifference = \
1308 Flight.getMinutesDifference(self._flightTimeStart.minutes,
1309 self._blockTimeStart.minutes)
1310 arrivalMinutes = \
1311 bookedFlight.arrivalTime.hour*60 + bookedFlight.arrivalTime.minute
1312 arrivalDifference = abs(Flight.getMinutesDifference(self._blockTimeEnd.minutes,
1313 arrivalMinutes))
1314 flightEndDifference = \
1315 Flight.getMinutesDifference(self._blockTimeEnd.minutes,
1316 self._flightTimeEnd.minutes)
1317
1318 timesOK = self._flightInfo.hasComments or \
1319 self._flightInfo.hasDelayCode or \
1320 (departureDifference<=Flight.TIME_ERROR_DIFFERENCE and
1321 arrivalDifference<=Flight.TIME_ERROR_DIFFERENCE and
1322 flightStartDifference>=0 and flightStartDifference<30 and
1323 flightEndDifference>=0 and flightEndDifference<30)
1324
1325 text = self._sid.get_child().get_text()
1326 sid = text if self._sid.get_active()!=0 and text and text!="N/A" \
1327 else None
1328
1329 text = self._star.get_child().get_text()
1330 star = text if self._star.get_active()!=0 and text and text!="N/A" \
1331 else None
1332
1333 text = self._transition.get_child().get_text()
1334 transition = text if self._transition.get_active()!=0 \
1335 and text and text!="N/A" else None
1336
1337
1338 buffer = self._userRoute.get_buffer()
1339 route = buffer.get_text(buffer.get_start_iter(),
1340 buffer.get_end_iter(), True)
1341
1342 self._okButton.set_sensitive(timesOK and
1343 self._flightInfo.faultsFullyExplained and
1344 self._flownNumPassengers.get_value_as_int()>0 and
1345 self._flownNumCrew.get_value_as_int()>2 and
1346 self._fuelUsed.get_value_as_int()>0 and
1347 self._departureRunway.get_text_length()>0 and
1348 self._arrivalRunway.get_text_length()>0 and
1349 self._departureMETAR.get_buffer().get_char_count()>0 and
1350 self._arrivalMETAR.get_buffer().get_char_count()>0 and
1351 self._filedCruiseLevel.get_value_as_int()>=50 and
1352 self._modifiedCruiseLevel.get_value_as_int()>=50 and
1353 sid is not None and (star is not None or
1354 transition is not None) and route!="" and
1355 self._approachType.get_text()!="")
1356
1357#------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.