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
RevLine 
[220]1
2from common import *
[845]3from dcdata import getTable
4from info import FlightInfo
5from flight import comboModel
[220]6
[236]7from mlx.pirep import PIREP
[846]8from mlx.flight import Flight
[220]9from mlx.const import *
10
11import time
[845]12import re
[220]13
14#------------------------------------------------------------------------------
15
[300]16## @package mlx.gui.pirep
17#
[845]18# The detailed PIREP viewer and editor windows.
[300]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
[220]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
[831]36 contents.
[220]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)
[831]50
[220]51 return (frame, box)
52
53 @staticmethod
[845]54 def getLabel(text, extraText = ""):
[220]55 """Get a bold label with the given text."""
[845]56 label = gtk.Label("<b>" + text + "</b>" + extraText)
[220]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
[845]71 def getTextWindow(heightRequest = 40, editable = False):
[220]72 """Get a scrollable text window.
[831]73
[220]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)
[845]83 textView.set_editable(editable)
84 textView.set_cursor_visible(editable)
[220]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
[831]94 table.
95
[220]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)
[831]102
[220]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.
[831]112
[845]113 Returns the data label."""
[220]114 label = PIREPViewer.getLabel(labelText)
115 hBox.pack_start(label, False, False, 0)
[831]116
[220]117 dataLabel = PIREPViewer.getDataLabel(width = width)
118 hBox.pack_start(dataLabel, False, False, dataPadding)
119
120 return dataLabel
121
122 @staticmethod
[845]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
[220]131 def addVFiller(vBox, height = 4):
[238]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)
[220]135 filler.set_size_request(-1, height)
136 vBox.pack_start(filler, False, False, 0)
[831]137
[220]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)
[831]151
[220]152 self.set_resizable(False)
153
154 self._gui = gui
[831]155
[220]156 contentArea = self.get_content_area()
[221]157
158 self._notebook = gtk.Notebook()
159 contentArea.pack_start(self._notebook, False, False, 4)
[831]160
[220]161 dataTab = self._buildDataTab()
[221]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)
[831]166
[221]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)
[831]172
[221]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)
[224]178
179 self._okButton = self.add_button(xstr("button_ok"), RESPONSETYPE_OK)
180 self._okButton.set_can_default(True)
[831]181
[220]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)
[831]190
[220]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))
[831]206
[220]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)
[831]233
[220]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
[303]243 self._flownNumCrew.set_text("%d" % (pirep.numCrew,))
244 self._flownNumPassengers.set_text("%d" % (pirep.numPassengers,))
245 self._flownBagWeight.set_text("%.0f" % (pirep.bagWeight,))
[223]246 self._flownCargoWeight.set_text("%.0f" % (pirep.cargoWeight,))
[303]247 self._flownMailWeight.set_text("%.0f" % (pirep.mailWeight,))
[831]248 self._flightType.set_text(xstr("flighttype_" +
[220]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 += ", "
[437]256 delayCodes += code
[831]257
258 self._delayCodes.get_buffer().set_text(delayCodes)
[221]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("")
[225]265 lineIndex = 0
[221]266 for (timeStr, line) in pirep.logLines:
[225]267 isFault = lineIndex in pirep.faultLineIndexes
[226]268 appendTextBuffer(logBuffer,
269 formatFlightLogLine(timeStr, line),
270 isFault = isFault)
[225]271 lineIndex += 1
[221]272
273 self._notebook.set_current_page(0)
[224]274 self._okButton.grab_default()
[220]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)
[831]285
[220]286 box2 = gtk.VBox()
287 table.attach(box2, 1, 2, 0, 1)
[831]288
[220]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."""
[831]311
[220]312 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight"))
[831]313
[220]314 dataBox = gtk.HBox()
315 mainBox.pack_start(dataBox, False, False, 0)
[831]316
[220]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)
[831]342 table.set_col_spacings(8)
[220]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)
[831]367 table.set_col_spacings(8)
[220]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 = \
[831]380 PIREPViewer.tableAttach(table, 0, 1,
[220]381 xstr("pirepView_bagWeight"),
382 width = 5)
383
384 self._cargoWeight = \
[831]385 PIREPViewer.tableAttach(table, 1, 1,
[220]386 xstr("pirepView_cargoWeight"),
387 width = 5)
388
389 self._mailWeight = \
[831]390 PIREPViewer.tableAttach(table, 2, 1,
[220]391 xstr("pirepView_mailWeight"),
392 width = 5)
[831]393
[220]394 PIREPViewer.addVFiller(mainBox)
395
396 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")),
397 False, False, 0)
[831]398
[220]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."""
[831]407
[220]408 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route"))
409
410 levelBox = gtk.HBox()
411 mainBox.pack_start(levelBox, False, False, 0)
[831]412
[220]413 self._filedCruiseLevel = \
[831]414 PIREPViewer.addLabeledData(levelBox,
[220]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):
[831]431 """Build the frame for the departure data."""
[220]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)
[831]444
[220]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
[831]456
[220]457 def _buildArrivalFrame(self):
[831]458 """Build the frame for the arrival data."""
[220]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)
[831]472 table.set_col_spacings(8)
[220]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)
[831]483
[220]484 self._approachType = \
485 PIREPViewer.tableAttach(table, 0, 1,
486 xstr("pirepView_approachType"),
487 width = 7)
[831]488
[220]489 self._arrivalRunway = \
[831]490 PIREPViewer.tableAttach(table, 1, 1,
[220]491 xstr("pirepView_runway"),
492 width = 5)
[831]493
[220]494 return frame
495
496 def _buildStatisticsFrame(self):
[831]497 """Build the frame for the statistics data."""
[220]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)
[221]504 table.set_homogeneous(False)
[831]505
[220]506 self._blockTimeStart = \
507 PIREPViewer.tableAttach(table, 0, 0,
508 xstr("pirepView_blockTimeStart"),
509 width = 6)
[831]510
[220]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)
[831]520
[220]521 self._flightTimeEnd = \
[831]522 PIREPViewer.tableAttach(table, 1, 1,
[220]523 xstr("pirepView_flightTimeEnd"),
524 width = 6)
525
526 self._flownDistance = \
527 PIREPViewer.tableAttach(table, 0, 2,
528 xstr("pirepView_flownDistance"),
529 width = 8)
[831]530
[220]531 self._fuelUsed = \
532 PIREPViewer.tableAttach(table, 1, 2,
533 xstr("pirepView_fuelUsed"),
534 width = 6)
[831]535
[220]536 self._rating = \
537 PIREPViewer.tableAttach(table, 0, 3,
538 xstr("pirepView_rating"),
539 width = 7)
540 return frame
541
542 def _buildMiscellaneousFrame(self):
[831]543 """Build the frame for the miscellaneous data."""
[220]544 (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous"))
[303]545
546 table = gtk.Table(3, 2)
547 mainBox.pack_start(table, False, False, 0)
548 table.set_row_spacings(4)
[831]549 table.set_col_spacings(8)
550
[303]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
[223]566 self._flownCargoWeight = \
[303]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)
[223]575
[220]576 self._flightType = \
[303]577 PIREPViewer.tableAttach(table, 0, 2,
578 xstr("pirepView_flightType"),
579 width = 15)
[831]580
[220]581 self._online = \
[303]582 PIREPViewer.tableAttach(table, 1, 2,
583 xstr("pirepView_online"),
584 width = 5)
[220]585
586 PIREPViewer.addVFiller(mainBox)
587
588 mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")),
589 False, False, 0)
[831]590
[220]591 (textWindow, self._delayCodes) = PIREPViewer.getTextWindow()
592 mainBox.pack_start(textWindow, False, False, 0)
593
[831]594 return frame
[220]595
[221]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)
[831]616
[221]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)
[226]624 addFaultTag(self._log.get_buffer())
[221]625 mainBox.pack_start(logWindow, True, True, 0)
[831]626
[221]627 return mainBox
[831]628
[220]629#------------------------------------------------------------------------------
[845]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
[846]695 self._pirep = None
696
[845]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
[846]720 self.add_button(xstr("button_cancel"), RESPONSETYPE_CANCEL)
721
[848]722 self._okButton = self.add_button(xstr("button_save"), RESPONSETYPE_OK)
[845]723 self._okButton.set_can_default(True)
724
725 def setPIREP(self, pirep):
726 """Setup the data in the dialog from the given PIREP."""
[846]727 self._pirep = pirep
728
[845]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
[846]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
[845]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)
[847]1001 self._filedCruiseLevel.set_tooltip_text(xstr("route_level_tooltip"))
[845]1002 self._filedCruiseLevel.set_numeric(True)
[846]1003 self._filedCruiseLevel.connect("value-changed", self._updateButtons)
[845]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)
[847]1016 self._modifiedCruiseLevel.set_tooltip_text(xstr("pirepEdit_modified_route_level_tooltip"))
[845]1017 self._modifiedCruiseLevel.set_numeric(True)
[846]1018 self._modifiedCruiseLevel.connect("value-changed", self._updateButtons)
[845]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)
[846]1027 self._userRoute.get_buffer().connect("changed", self._updateButtons)
[847]1028 self._userRoute.set_tooltip_text(xstr("route_route_tooltip"))
[845]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)
[846]1041 self._departureMETAR.get_buffer().connect("changed", self._updateButtons)
[847]1042 self._departureMETAR.set_tooltip_text(xstr("takeoff_metar_tooltip"))
[845]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)
[846]1090 self._arrivalMETAR.get_buffer().connect("changed", self._updateButtons)
[847]1091 self._arrivalMETAR.set_tooltip_text(xstr("landing_metar_tooltip"))
[845]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"))
[846]1167 self._blockTimeStart.connect("changed", self._updateButtons)
[847]1168 self._blockTimeStart.set_tooltip_text(xstr("pirepEdit_block_time_start_tooltip"))
[845]1169
1170 self._blockTimeEnd = \
1171 PIREPEditor.tableAttachTimeEntry(table, 2, 0,
1172 xstr("pirepView_blockTimeEnd"))
[846]1173 self._blockTimeEnd.connect("changed", self._updateButtons)
[847]1174 self._blockTimeEnd.set_tooltip_text(xstr("pirepEdit_block_time_end_tooltip"))
[845]1175
1176 self._flightTimeStart = \
1177 PIREPEditor.tableAttachTimeEntry(table, 0, 1,
1178 xstr("pirepView_flightTimeStart"))
[846]1179 self._flightTimeStart.connect("changed", self._updateButtons)
[847]1180 self._flightTimeStart.set_tooltip_text(xstr("pirepEdit_flight_time_start_tooltip"))
[845]1181
1182 self._flightTimeEnd = \
1183 PIREPEditor.tableAttachTimeEntry(table, 2, 1,
1184 xstr("pirepView_flightTimeEnd"))
[846]1185 self._flightTimeEnd.connect("changed", self._updateButtons)
[847]1186 self._flightTimeEnd.set_tooltip_text(xstr("pirepEdit_flight_time_end_tooltip"))
[845]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)
[846]1197 self._fuelUsed.connect("value-changed", self._updateButtons)
[847]1198 self._fuelUsed.set_tooltip_text(xstr("pirepEdit_fuel_used_tooltip"))
[845]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)
[846]1220 self._flownNumPassengers.connect("value-changed", self._updateButtons)
[847]1221 self._flownNumPassengers.set_tooltip_text(xstr("payload_pax_tooltip"))
[845]1222
1223 self._flownNumCrew = \
1224 PIREPEditor.tableAttachSpinButton(table, 2, 0,
1225 xstr("pirepView_numCrew"),
1226 10)
[846]1227 self._flownNumCrew.connect("value-changed", self._updateButtons)
[847]1228 self._flownNumCrew.set_tooltip_text(xstr("payload_crew_tooltip"))
[845]1229
1230 self._flownBagWeight = \
1231 PIREPEditor.tableAttachSpinButton(table, 0, 1,
1232 xstr("pirepView_bagWeight"),
1233 100000, width = 6)
[847]1234 self._flownBagWeight.set_tooltip_text(xstr("payload_bag_tooltip"))
[845]1235
1236 self._flownCargoWeight = \
1237 PIREPEditor.tableAttachSpinButton(table, 2, 1,
1238 xstr("pirepView_cargoWeight"),
1239 100000, width = 6)
[847]1240 self._flownCargoWeight.set_tooltip_text(xstr("payload_cargo_tooltip"))
[845]1241
1242 self._flownMailWeight = \
1243 PIREPEditor.tableAttachSpinButton(table, 4, 1,
1244 xstr("pirepView_mailWeight"),
1245 100000, width = 6)
[847]1246 self._flownMailWeight.set_tooltip_text(xstr("payload_mail_tooltip"))
[845]1247
1248 self._flightType = createFlightTypeComboBox()
1249 PIREPEditor.tableAttachWidget(table, 0, 2,
1250 xstr("pirepView_flightType"),
1251 self._flightType)
[847]1252 self._flightType.set_tooltip_text(xstr("pirepEdit_flight_type_tooltip"))
[845]1253
[847]1254 self._online = gtk.CheckButton(xstr("pirepEdit_online"))
[845]1255 table.attach(self._online, 2, 3, 2, 3)
[847]1256 self._online.set_tooltip_text(xstr("pirepEdit_online_tooltip"))
[845]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)
[847]1265 self._delayCodes.set_tooltip_text(xstr("pirepEdit_delayCodes_tooltip"))
[845]1266
1267 return frame
1268
1269 def _buildCommentsTab(self):
1270 """Build the tab with the comments and flight defects."""
[846]1271 return FlightInfo(self._gui, callbackObject = self)
[845]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())
[846]1287 self._updateButtons()
[845]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())
[846]1295 self._updateButtons()
[845]1296 #self._valueChanged(entry)
1297
[846]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
[845]1357#------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.