source: src/mlx/gui/pirep.py@ 853:28eb49544c0f

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

PIREP modifications can be saved (re #307)

File size: 54.9 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_NONE)
723 self._okButton.connect("clicked", self._okClicked)
724 self._okButton.set_can_default(True)
725 self._modified = False
726 self._toSave = False
727
728 def setPIREP(self, pirep):
729 """Setup the data in the dialog from the given PIREP."""
730 self._pirep = pirep
731
732 bookedFlight = pirep.bookedFlight
733
734 self._callsign.set_text(bookedFlight.callsign)
735 self._tailNumber.set_text(bookedFlight.tailNumber)
736 aircraftType = xstr("aircraft_" + icaoCodes[bookedFlight.aircraftType].lower())
737 self._aircraftType.set_text(aircraftType)
738
739 self._departureICAO.set_text(bookedFlight.departureICAO)
740 self._departureTime.set_text("%02d:%02d" % \
741 (bookedFlight.departureTime.hour,
742 bookedFlight.departureTime.minute))
743
744 self._arrivalICAO.set_text(bookedFlight.arrivalICAO)
745 self._arrivalTime.set_text("%02d:%02d" % \
746 (bookedFlight.arrivalTime.hour,
747 bookedFlight.arrivalTime.minute))
748
749 self._numPassengers.set_text(str(bookedFlight.numPassengers))
750 self._numCrew.set_text(str(bookedFlight.numCrew))
751 self._bagWeight.set_text(str(bookedFlight.bagWeight))
752 self._cargoWeight.set_text(str(bookedFlight.cargoWeight))
753 self._mailWeight.set_text(str(bookedFlight.mailWeight))
754
755 self._route.get_buffer().set_text(bookedFlight.route)
756
757 self._filedCruiseLevel.set_value(pirep.filedCruiseAltitude/100)
758 self._modifiedCruiseLevel.set_value(pirep.cruiseAltitude/100)
759
760 self._userRoute.get_buffer().set_text(pirep.route)
761
762 self._departureMETAR.get_buffer().set_text(pirep.departureMETAR)
763
764 self._arrivalMETAR.get_buffer().set_text(pirep.arrivalMETAR)
765 self._departureRunway.set_text(pirep.departureRunway)
766 self._sid.get_child().set_text(pirep.sid)
767
768 if not pirep.star:
769 self._star.set_active(0)
770 else:
771 self._star.get_child().set_text(pirep.star)
772
773 if not pirep.transition:
774 self._transition.set_active(0)
775 else:
776 self._transition.get_child().set_text(pirep.transition)
777 self._approachType.set_text(pirep.approachType)
778 self._arrivalRunway.set_text(pirep.arrivalRunway)
779
780 self._blockTimeStart.setTimestamp(pirep.blockTimeStart)
781 self._blockTimeEnd.setTimestamp(pirep.blockTimeEnd)
782 self._flightTimeStart.setTimestamp(pirep.flightTimeStart)
783 self._flightTimeEnd.setTimestamp(pirep.flightTimeEnd)
784
785 self._flownDistance.set_text("%.1f" % (pirep.flownDistance,))
786 self._fuelUsed.set_value(int(pirep.fuelUsed))
787
788 rating = pirep.rating
789 if rating<0:
790 self._rating.set_markup('<b><span foreground="red">NO GO</span></b>')
791 else:
792 self._rating.set_text("%.1f %%" % (rating,))
793
794 self._flownNumCrew.set_value(pirep.numCrew)
795 self._flownNumPassengers.set_value(pirep.numPassengers)
796 self._flownBagWeight.set_value(pirep.bagWeight)
797 self._flownCargoWeight.set_value(pirep.cargoWeight)
798 self._flownMailWeight.set_value(pirep.mailWeight)
799 self._flightType.set_active(flightType2index(pirep.flightType))
800 self._online.set_active(pirep.online)
801
802 self._flightInfo.reset()
803 self._flightInfo.enable(bookedFlight.aircraftType)
804
805 delayCodes = ""
806 for code in pirep.delayCodes:
807 if delayCodes: delayCodes += ", "
808 delayCodes += code
809 m = PIREPEditor._delayCodeRE.match(code)
810 if m:
811 self._flightInfo.activateDelayCode(m.group(1))
812
813 self._delayCodes.get_buffer().set_text(delayCodes)
814
815 self._flightInfo.comments = pirep.comments
816 if pirep.flightDefects.find("<br/></b>")!=-1:
817 flightDefects = pirep.flightDefects.split("<br/></b>")
818 caption = flightDefects[0]
819 index = 0
820 for defect in flightDefects[1:]:
821 if defect.find("<b>")!=-1:
822 (explanation, nextCaption) = defect.split("<b>")
823 else:
824 explanation = defect
825 nextCaption = None
826 self._flightInfo.addFault(index, caption)
827 self._flightInfo.setExplanation(index, explanation)
828 index += 1
829 caption = nextCaption
830
831 # self._comments.get_buffer().set_text(pirep.comments)
832 # self._flightDefects.get_buffer().set_text(pirep.flightDefects)
833
834 logBuffer = self._log.get_buffer()
835 logBuffer.set_text("")
836 lineIndex = 0
837 for (timeStr, line) in pirep.logLines:
838 isFault = lineIndex in pirep.faultLineIndexes
839 appendTextBuffer(logBuffer,
840 formatFlightLogLine(timeStr, line),
841 isFault = isFault)
842 lineIndex += 1
843
844 self._notebook.set_current_page(0)
845 self._okButton.grab_default()
846
847 self._modified = False
848 self._updateButtons()
849 self._modified = True
850 self._toSave = False
851
852 def delayCodesChanged(self):
853 """Called when the delay codes have changed."""
854 self._updateButtons()
855
856 def commentsChanged(self):
857 """Called when the comments have changed."""
858 self._updateButtons()
859
860 def faultExplanationsChanged(self):
861 """Called when the fault explanations have changed."""
862 self._updateButtons()
863
864 def _buildDataTab(self):
865 """Build the data tab of the viewer."""
866 table = gtk.Table(1, 2)
867 table.set_row_spacings(4)
868 table.set_col_spacings(16)
869 table.set_homogeneous(True)
870
871 box1 = gtk.VBox()
872 table.attach(box1, 0, 1, 0, 1)
873
874 box2 = gtk.VBox()
875 table.attach(box2, 1, 2, 0, 1)
876
877 flightFrame = self._buildFlightFrame()
878 box1.pack_start(flightFrame, False, False, 4)
879
880 routeFrame = self._buildRouteFrame()
881 box1.pack_start(routeFrame, False, False, 4)
882
883 departureFrame = self._buildDepartureFrame()
884 box2.pack_start(departureFrame, True, True, 4)
885
886 arrivalFrame = self._buildArrivalFrame()
887 box2.pack_start(arrivalFrame, True, True, 4)
888
889 statisticsFrame = self._buildStatisticsFrame()
890 box2.pack_start(statisticsFrame, False, False, 4)
891
892 miscellaneousFrame = self._buildMiscellaneousFrame()
893 box1.pack_start(miscellaneousFrame, False, False, 4)
894
895 return table
896
897 def _buildFlightFrame(self):
898 """Build the frame for the flight data."""
899
900 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight"))
901
902 dataBox = gtk.HBox()
903 mainBox.pack_start(dataBox, False, False, 0)
904
905 self._callsign = \
906 PIREPViewer.addLabeledData(dataBox,
907 xstr("pirepView_callsign"),
908 width = 8)
909
910 self._tailNumber = \
911 PIREPViewer.addLabeledData(dataBox,
912 xstr("pirepView_tailNumber"),
913 width = 7)
914
915 PIREPViewer.addVFiller(mainBox)
916
917 dataBox = gtk.HBox()
918 mainBox.pack_start(dataBox, False, False, 0)
919
920 self._aircraftType = \
921 PIREPViewer.addLabeledData(dataBox,
922 xstr("pirepView_aircraftType"),
923 width = 25)
924
925 PIREPViewer.addVFiller(mainBox)
926
927 table = gtk.Table(3, 2)
928 mainBox.pack_start(table, False, False, 0)
929 table.set_row_spacings(4)
930 table.set_col_spacings(8)
931
932 self._departureICAO = \
933 PIREPViewer.tableAttach(table, 0, 0,
934 xstr("pirepView_departure"),
935 width = 5)
936
937 self._departureTime = \
938 PIREPViewer.tableAttach(table, 1, 0,
939 xstr("pirepView_departure_time"),
940 width = 6)
941
942 self._arrivalICAO = \
943 PIREPViewer.tableAttach(table, 0, 1,
944 xstr("pirepView_arrival"),
945 width = 5)
946
947 self._arrivalTime = \
948 PIREPViewer.tableAttach(table, 1, 1,
949 xstr("pirepView_arrival_time"),
950 width = 6)
951
952 table = gtk.Table(3, 2)
953 mainBox.pack_start(table, False, False, 0)
954 table.set_row_spacings(4)
955 table.set_col_spacings(8)
956
957 self._numPassengers = \
958 PIREPViewer.tableAttach(table, 0, 0,
959 xstr("pirepView_numPassengers"),
960 width = 4)
961 self._numCrew = \
962 PIREPViewer.tableAttach(table, 1, 0,
963 xstr("pirepView_numCrew"),
964 width = 3)
965
966 self._bagWeight = \
967 PIREPViewer.tableAttach(table, 0, 1,
968 xstr("pirepView_bagWeight"),
969 width = 5)
970
971 self._cargoWeight = \
972 PIREPViewer.tableAttach(table, 1, 1,
973 xstr("pirepView_cargoWeight"),
974 width = 5)
975
976 self._mailWeight = \
977 PIREPViewer.tableAttach(table, 2, 1,
978 xstr("pirepView_mailWeight"),
979 width = 5)
980
981 PIREPViewer.addVFiller(mainBox)
982
983 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")),
984 False, False, 0)
985
986 (routeWindow, self._route) = PIREPViewer.getTextWindow()
987 mainBox.pack_start(routeWindow, False, False, 0)
988
989 return frame
990
991 def _buildRouteFrame(self):
992 """Build the frame for the user-specified route and flight
993 level."""
994
995 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route"))
996
997 levelBox = gtk.HBox()
998 mainBox.pack_start(levelBox, False, False, 0)
999
1000 label = PIREPViewer.getLabel(xstr("pirepView_filedCruiseLevel"),
1001 xstr("pirepEdit_FL"))
1002 levelBox.pack_start(label, False, False, 0)
1003
1004 self._filedCruiseLevel = gtk.SpinButton()
1005 self._filedCruiseLevel.set_increments(step = 10, page = 100)
1006 self._filedCruiseLevel.set_range(min = 0, max = 500)
1007 self._filedCruiseLevel.set_tooltip_text(xstr("route_level_tooltip"))
1008 self._filedCruiseLevel.set_numeric(True)
1009 self._filedCruiseLevel.connect("value-changed", self._updateButtons)
1010
1011 levelBox.pack_start(self._filedCruiseLevel, False, False, 0)
1012
1013 PIREPViewer.addHFiller(levelBox)
1014
1015 label = PIREPViewer.getLabel(xstr("pirepView_modifiedCruiseLevel"),
1016 xstr("pirepEdit_FL"))
1017 levelBox.pack_start(label, False, False, 0)
1018
1019 self._modifiedCruiseLevel = gtk.SpinButton()
1020 self._modifiedCruiseLevel.set_increments(step = 10, page = 100)
1021 self._modifiedCruiseLevel.set_range(min = 0, max = 500)
1022 self._modifiedCruiseLevel.set_tooltip_text(xstr("pirepEdit_modified_route_level_tooltip"))
1023 self._modifiedCruiseLevel.set_numeric(True)
1024 self._modifiedCruiseLevel.connect("value-changed", self._updateButtons)
1025
1026 levelBox.pack_start(self._modifiedCruiseLevel, False, False, 0)
1027
1028 PIREPViewer.addVFiller(mainBox)
1029
1030 (routeWindow, self._userRoute) = \
1031 PIREPViewer.getTextWindow(editable = True)
1032 mainBox.pack_start(routeWindow, False, False, 0)
1033 self._userRoute.get_buffer().connect("changed", self._updateButtons)
1034 self._userRoute.set_tooltip_text(xstr("route_route_tooltip"))
1035
1036 return frame
1037
1038 def _buildDepartureFrame(self):
1039 """Build the frame for the departure data."""
1040 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_departure"))
1041
1042 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
1043 False, False, 0)
1044 (metarWindow, self._departureMETAR) = \
1045 PIREPViewer.getTextWindow(heightRequest = -1,
1046 editable = True)
1047 self._departureMETAR.get_buffer().connect("changed", self._updateButtons)
1048 self._departureMETAR.set_tooltip_text(xstr("takeoff_metar_tooltip"))
1049 mainBox.pack_start(metarWindow, True, True, 0)
1050
1051 PIREPViewer.addVFiller(mainBox)
1052
1053 dataBox = gtk.HBox()
1054 mainBox.pack_start(dataBox, False, False, 0)
1055
1056 label = gtk.Label("<b>" + xstr("pirepView_runway") + "</b>")
1057 label.set_use_markup(True)
1058 dataBox.pack_start(label, False, False, 0)
1059
1060 # FIXME: quite the same as the runway entry boxes in the wizard
1061 self._departureRunway = gtk.Entry()
1062 self._departureRunway.set_width_chars(5)
1063 self._departureRunway.set_tooltip_text(xstr("takeoff_runway_tooltip"))
1064 self._departureRunway.connect("changed", self._upperChanged)
1065 dataBox.pack_start(self._departureRunway, False, False, 8)
1066
1067 label = gtk.Label("<b>" + xstr("pirepView_sid") + "</b>")
1068 label.set_use_markup(True)
1069 dataBox.pack_start(label, False, False, 0)
1070
1071 # FIXME: quite the same as the SID combo box in
1072 # the flight wizard
1073 if pygobject:
1074 self._sid = gtk.ComboBox.new_with_model_and_entry(comboModel)
1075 else:
1076 self._sid = gtk.ComboBoxEntry(comboModel)
1077
1078 self._sid.set_entry_text_column(0)
1079 self._sid.get_child().set_width_chars(10)
1080 self._sid.set_tooltip_text(xstr("takeoff_sid_tooltip"))
1081 self._sid.connect("changed", self._upperChangedComboBox)
1082
1083 dataBox.pack_start(self._sid, False, False, 8)
1084
1085 return frame
1086
1087 def _buildArrivalFrame(self):
1088 """Build the frame for the arrival data."""
1089 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_arrival"))
1090
1091 mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
1092 False, False, 0)
1093 (metarWindow, self._arrivalMETAR) = \
1094 PIREPViewer.getTextWindow(heightRequest = -1,
1095 editable = True)
1096 self._arrivalMETAR.get_buffer().connect("changed", self._updateButtons)
1097 self._arrivalMETAR.set_tooltip_text(xstr("landing_metar_tooltip"))
1098 mainBox.pack_start(metarWindow, True, True, 0)
1099
1100 PIREPViewer.addVFiller(mainBox)
1101
1102 table = gtk.Table(2, 4)
1103 mainBox.pack_start(table, False, False, 0)
1104 table.set_row_spacings(4)
1105 table.set_col_spacings(8)
1106
1107 # FIXME: quite the same as in the wizard
1108 if pygobject:
1109 self._star = gtk.ComboBox.new_with_model_and_entry(comboModel)
1110 else:
1111 self._star = gtk.ComboBoxEntry(comboModel)
1112
1113 self._star.set_entry_text_column(0)
1114 self._star.get_child().set_width_chars(10)
1115 self._star.set_tooltip_text(xstr("landing_star_tooltip"))
1116 self._star.connect("changed", self._upperChangedComboBox)
1117
1118 PIREPEditor.tableAttachWidget(table, 0, 0,
1119 xstr("pirepView_star"),
1120 self._star)
1121
1122 # FIXME: quite the same as in the wizard
1123 if pygobject:
1124 self._transition = gtk.ComboBox.new_with_model_and_entry(comboModel)
1125 else:
1126 self._transition = gtk.ComboBoxEntry(comboModel)
1127
1128 self._transition.set_entry_text_column(0)
1129 self._transition.get_child().set_width_chars(10)
1130 self._transition.set_tooltip_text(xstr("landing_transition_tooltip"))
1131 self._transition.connect("changed", self._upperChangedComboBox)
1132
1133 PIREPEditor.tableAttachWidget(table, 2, 0,
1134 xstr("pirepView_transition"),
1135 self._transition)
1136
1137
1138 # FIXME: quite the same as in the wizard
1139 self._approachType = gtk.Entry()
1140 self._approachType.set_width_chars(10)
1141 self._approachType.set_tooltip_text(xstr("landing_approach_tooltip"))
1142 self._approachType.connect("changed", self._upperChanged)
1143
1144 PIREPEditor.tableAttachWidget(table, 0, 1,
1145 xstr("pirepView_approachType"),
1146 self._approachType)
1147
1148 # FIXME: quite the same as in the wizard
1149 self._arrivalRunway = gtk.Entry()
1150 self._arrivalRunway.set_width_chars(10)
1151 self._arrivalRunway.set_tooltip_text(xstr("landing_runway_tooltip"))
1152 self._arrivalRunway.connect("changed", self._upperChanged)
1153
1154 PIREPEditor.tableAttachWidget(table, 2, 1,
1155 xstr("pirepView_runway"),
1156 self._arrivalRunway)
1157
1158 return frame
1159
1160 def _buildStatisticsFrame(self):
1161 """Build the frame for the statistics data."""
1162 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_statistics"))
1163
1164 table = gtk.Table(4, 4)
1165 mainBox.pack_start(table, False, False, 0)
1166 table.set_row_spacings(4)
1167 table.set_col_spacings(8)
1168 table.set_homogeneous(False)
1169
1170 self._blockTimeStart = \
1171 PIREPEditor.tableAttachTimeEntry(table, 0, 0,
1172 xstr("pirepView_blockTimeStart"))
1173 self._blockTimeStart.connect("changed", self._updateButtons)
1174 self._blockTimeStart.set_tooltip_text(xstr("pirepEdit_block_time_start_tooltip"))
1175
1176 self._blockTimeEnd = \
1177 PIREPEditor.tableAttachTimeEntry(table, 2, 0,
1178 xstr("pirepView_blockTimeEnd"))
1179 self._blockTimeEnd.connect("changed", self._updateButtons)
1180 self._blockTimeEnd.set_tooltip_text(xstr("pirepEdit_block_time_end_tooltip"))
1181
1182 self._flightTimeStart = \
1183 PIREPEditor.tableAttachTimeEntry(table, 0, 1,
1184 xstr("pirepView_flightTimeStart"))
1185 self._flightTimeStart.connect("changed", self._updateButtons)
1186 self._flightTimeStart.set_tooltip_text(xstr("pirepEdit_flight_time_start_tooltip"))
1187
1188 self._flightTimeEnd = \
1189 PIREPEditor.tableAttachTimeEntry(table, 2, 1,
1190 xstr("pirepView_flightTimeEnd"))
1191 self._flightTimeEnd.connect("changed", self._updateButtons)
1192 self._flightTimeEnd.set_tooltip_text(xstr("pirepEdit_flight_time_end_tooltip"))
1193
1194 self._flownDistance = PIREPViewer.getDataLabel(width = 3)
1195 PIREPEditor.tableAttachWidget(table, 0, 2,
1196 xstr("pirepView_flownDistance"),
1197 self._flownDistance)
1198
1199 self._fuelUsed = \
1200 PIREPEditor.tableAttachSpinButton(table, 2, 2,
1201 xstr("pirepView_fuelUsed"),
1202 1000000)
1203 self._fuelUsed.connect("value-changed", self._updateButtons)
1204 self._fuelUsed.set_tooltip_text(xstr("pirepEdit_fuel_used_tooltip"))
1205
1206 self._rating = PIREPViewer.getDataLabel(width = 3)
1207 PIREPEditor.tableAttachWidget(table, 0, 3,
1208 xstr("pirepView_rating"),
1209 self._rating)
1210 return frame
1211
1212 def _buildMiscellaneousFrame(self):
1213 """Build the frame for the miscellaneous data."""
1214 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous"))
1215
1216 table = gtk.Table(6, 2)
1217 mainBox.pack_start(table, False, False, 0)
1218 table.set_row_spacings(4)
1219 table.set_col_spacings(8)
1220 table.set_homogeneous(False)
1221
1222 self._flownNumPassengers = \
1223 PIREPEditor.tableAttachSpinButton(table, 0, 0,
1224 xstr("pirepView_numPassengers"),
1225 300)
1226 self._flownNumPassengers.connect("value-changed", self._updateButtons)
1227 self._flownNumPassengers.set_tooltip_text(xstr("payload_pax_tooltip"))
1228
1229 self._flownNumCrew = \
1230 PIREPEditor.tableAttachSpinButton(table, 2, 0,
1231 xstr("pirepView_numCrew"),
1232 10)
1233 self._flownNumCrew.connect("value-changed", self._updateButtons)
1234 self._flownNumCrew.set_tooltip_text(xstr("payload_crew_tooltip"))
1235
1236 self._flownBagWeight = \
1237 PIREPEditor.tableAttachSpinButton(table, 0, 1,
1238 xstr("pirepView_bagWeight"),
1239 100000, width = 6)
1240 self._flownBagWeight.connect("value-changed", self._updateButtons)
1241 self._flownBagWeight.set_tooltip_text(xstr("payload_bag_tooltip"))
1242
1243 self._flownCargoWeight = \
1244 PIREPEditor.tableAttachSpinButton(table, 2, 1,
1245 xstr("pirepView_cargoWeight"),
1246 100000, width = 6)
1247 self._flownCargoWeight.connect("value-changed", self._updateButtons)
1248 self._flownCargoWeight.set_tooltip_text(xstr("payload_cargo_tooltip"))
1249
1250 self._flownMailWeight = \
1251 PIREPEditor.tableAttachSpinButton(table, 4, 1,
1252 xstr("pirepView_mailWeight"),
1253 100000, width = 6)
1254 self._flownMailWeight.connect("value-changed", self._updateButtons)
1255 self._flownMailWeight.set_tooltip_text(xstr("payload_mail_tooltip"))
1256
1257 self._flightType = createFlightTypeComboBox()
1258 PIREPEditor.tableAttachWidget(table, 0, 2,
1259 xstr("pirepView_flightType"),
1260 self._flightType)
1261 self._flightType.connect("changed", self._updateButtons)
1262 self._flightType.set_tooltip_text(xstr("pirepEdit_flight_type_tooltip"))
1263
1264 self._online = gtk.CheckButton(xstr("pirepEdit_online"))
1265 table.attach(self._online, 2, 3, 2, 3)
1266 self._online.connect("toggled", self._updateButtons)
1267 self._online.set_tooltip_text(xstr("pirepEdit_online_tooltip"))
1268
1269 PIREPViewer.addVFiller(mainBox)
1270
1271 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")),
1272 False, False, 0)
1273
1274 (textWindow, self._delayCodes) = PIREPViewer.getTextWindow()
1275 mainBox.pack_start(textWindow, False, False, 0)
1276 self._delayCodes.set_tooltip_text(xstr("pirepEdit_delayCodes_tooltip"))
1277
1278 return frame
1279
1280 def _buildCommentsTab(self):
1281 """Build the tab with the comments and flight defects."""
1282 return FlightInfo(self._gui, callbackObject = self)
1283
1284 def _buildLogTab(self):
1285 """Build the log tab."""
1286 mainBox = gtk.VBox()
1287
1288 (logWindow, self._log) = PIREPViewer.getTextWindow(heightRequest = -1)
1289 addFaultTag(self._log.get_buffer())
1290 mainBox.pack_start(logWindow, True, True, 0)
1291
1292 return mainBox
1293
1294 def _upperChanged(self, entry, arg = None):
1295 """Called when the value of some entry widget has changed and the value
1296 should be converted to uppercase."""
1297 entry.set_text(entry.get_text().upper())
1298 self._updateButtons()
1299 #self._valueChanged(entry, arg)
1300
1301 def _upperChangedComboBox(self, comboBox):
1302 """Called for combo box widgets that must be converted to uppercase."""
1303 entry = comboBox.get_child()
1304 if comboBox.get_active()==-1:
1305 entry.set_text(entry.get_text().upper())
1306 self._updateButtons()
1307 #self._valueChanged(entry)
1308
1309 def _updateButtons(self, *kwargs):
1310 """Update the activity state of the buttons."""
1311 pirep = self._pirep
1312 bookedFlight = pirep.bookedFlight
1313
1314 departureMinutes = \
1315 bookedFlight.departureTime.hour*60 + bookedFlight.departureTime.minute
1316 departureDifference = abs(Flight.getMinutesDifference(self._blockTimeStart.minutes,
1317 departureMinutes))
1318 flightStartDifference = \
1319 Flight.getMinutesDifference(self._flightTimeStart.minutes,
1320 self._blockTimeStart.minutes)
1321 arrivalMinutes = \
1322 bookedFlight.arrivalTime.hour*60 + bookedFlight.arrivalTime.minute
1323 arrivalDifference = abs(Flight.getMinutesDifference(self._blockTimeEnd.minutes,
1324 arrivalMinutes))
1325 flightEndDifference = \
1326 Flight.getMinutesDifference(self._blockTimeEnd.minutes,
1327 self._flightTimeEnd.minutes)
1328
1329 timesOK = self._flightInfo.hasComments or \
1330 self._flightInfo.hasDelayCode or \
1331 (departureDifference<=Flight.TIME_ERROR_DIFFERENCE and
1332 arrivalDifference<=Flight.TIME_ERROR_DIFFERENCE and
1333 flightStartDifference>=0 and flightStartDifference<30 and
1334 flightEndDifference>=0 and flightEndDifference<30)
1335
1336 text = self._sid.get_child().get_text()
1337 sid = text if self._sid.get_active()!=0 and text and text!="N/A" \
1338 else None
1339
1340 text = self._star.get_child().get_text()
1341 star = text if self._star.get_active()!=0 and text and text!="N/A" \
1342 else None
1343
1344 text = self._transition.get_child().get_text()
1345 transition = text if self._transition.get_active()!=0 \
1346 and text and text!="N/A" else None
1347
1348
1349 buffer = self._userRoute.get_buffer()
1350 route = buffer.get_text(buffer.get_start_iter(),
1351 buffer.get_end_iter(), True)
1352
1353 self._okButton.set_sensitive(self._modified and timesOK and
1354 self._flightInfo.faultsFullyExplained and
1355 self._flownNumPassengers.get_value_as_int()>0 and
1356 self._flownNumCrew.get_value_as_int()>2 and
1357 self._fuelUsed.get_value_as_int()>0 and
1358 self._departureRunway.get_text_length()>0 and
1359 self._arrivalRunway.get_text_length()>0 and
1360 self._departureMETAR.get_buffer().get_char_count()>0 and
1361 self._arrivalMETAR.get_buffer().get_char_count()>0 and
1362 self._filedCruiseLevel.get_value_as_int()>=50 and
1363 self._modifiedCruiseLevel.get_value_as_int()>=50 and
1364 sid is not None and (star is not None or
1365 transition is not None) and route!="" and
1366 self._approachType.get_text()!="")
1367
1368 def _okClicked(self, button):
1369 """Called when the OK button has been clicked.
1370
1371 The PIREP is updated from the data in the window."""
1372 if not askYesNo(xstr("pirepEdit_save_question"), parent = self):
1373 self.response(RESPONSETYPE_CANCEL)
1374
1375 pirep = self._pirep
1376
1377 pirep.filedCruiseAltitude = \
1378 self._filedCruiseLevel.get_value_as_int() * 100
1379 pirep.cruiseAltitude = \
1380 self._modifiedCruiseLevel.get_value_as_int() * 100
1381
1382 pirep.route = getTextViewText(self._userRoute)
1383
1384 pirep.departureMETAR = getTextViewText(self._departureMETAR)
1385 pirep.departureRunway = self._departureRunway.get_text()
1386 pirep.sid = self._sid.get_child().get_text()
1387
1388 pirep.arrivalMETAR = getTextViewText(self._arrivalMETAR)
1389 pirep.star = None if self._star.get_active()==0 \
1390 else self._star.get_child().get_text()
1391 pirep.transition = None if self._transition.get_active()==0 \
1392 else self._transition.get_child().get_text()
1393 pirep.approachType = self._approachType.get_text()
1394 pirep.arrivalRunway = self._arrivalRunway.get_text()
1395
1396 pirep.blockTimeStart = \
1397 self._blockTimeStart.getTimestampFrom(pirep.blockTimeStart)
1398 pirep.blockTimeEnd = \
1399 self._blockTimeEnd.getTimestampFrom(pirep.blockTimeEnd)
1400 pirep.flightTimeStart = \
1401 self._flightTimeStart.getTimestampFrom(pirep.flightTimeStart)
1402 pirep.flightTimeEnd = \
1403 self._flightTimeEnd.getTimestampFrom(pirep.flightTimeEnd)
1404
1405 pirep.fuelUsed = self._fuelUsed.get_value()
1406
1407 pirep.numCrew = self._flownNumCrew.get_value()
1408 pirep.numPassengers = self._flownNumPassengers.get_value()
1409 pirep.bagWeight = self._flownBagWeight.get_value()
1410 pirep.cargoWeight = self._flownCargoWeight.get_value()
1411 pirep.mailWeight = self._flownMailWeight.get_value()
1412
1413 pirep.flightType = flightTypes[self._flightType.get_active()]
1414 pirep.online = self._online.get_active()
1415
1416 pirep.delayCodes = self._flightInfo.delayCodes
1417 pirep.comments = self._flightInfo.comments
1418 pirep.flightDefects = self._flightInfo.faultsAndExplanations
1419
1420 self.response(RESPONSETYPE_OK)
1421
1422
1423#------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.