source: src/mlx/gui/common.py@ 362:f57c0009eddc

Last change on this file since 362:f57c0009eddc was 362:f57c0009eddc, checked in by István Váradi <ivaradi@…>, 11 years ago

Fixed the handling of the tags in the log buffers

File size: 10.7 KB
RevLine 
[28]1
[105]2import mlx.const as _const
[175]3from mlx.i18n import xstr
[105]4
[28]5import os
6
[300]7#-----------------------------------------------------------------------------
8
9## @package mlx.gui.common
10#
11# Common definitions and utilities for the GUI
12#
13# The main purpose of this module is to provide common definitions for things
14# that are named differently in Gtk+ 2 and 3. This way the other parts of the
15# GUI have to check the version in use very rarely. The variable \ref pygobject
16# tells which version is being used. If it is \c True, Gtk+ 3 is used via the
17# PyGObject interface. Otherwise Gtk+ 2 is used, which is the default on
18# Windows or when the \c FORCE_PYGTK environment variable is set.
19#
[302]20# Besides this there are some common utility classes and functions.
[300]21
22#-----------------------------------------------------------------------------
23
[28]24appIndicator = False
25
26if os.name=="nt" or "FORCE_PYGTK" in os.environ:
27 print "Using PyGTK"
28 pygobject = False
29 import pygtk
[29]30 import gtk.gdk as gdk
[28]31 import gtk
32 import gobject
[44]33 import pango
[28]34 try:
35 import appindicator
36 appIndicator = True
37 except Exception, e:
38 pass
[42]39
40 MESSAGETYPE_ERROR = gtk.MESSAGE_ERROR
[76]41 MESSAGETYPE_QUESTION = gtk.MESSAGE_QUESTION
[97]42 MESSAGETYPE_INFO = gtk.MESSAGE_INFO
[175]43
[124]44 RESPONSETYPE_OK = gtk.RESPONSE_OK
[76]45 RESPONSETYPE_YES = gtk.RESPONSE_YES
[124]46 RESPONSETYPE_NO = gtk.RESPONSE_NO
[123]47 RESPONSETYPE_ACCEPT = gtk.RESPONSE_ACCEPT
48 RESPONSETYPE_REJECT = gtk.RESPONSE_REJECT
[149]49 RESPONSETYPE_CANCEL = gtk.RESPONSE_CANCEL
[175]50
[93]51 ACCEL_VISIBLE = gtk.ACCEL_VISIBLE
52 CONTROL_MASK = gdk.CONTROL_MASK
[123]53 DIALOG_MODAL = gtk.DIALOG_MODAL
[127]54 WRAP_WORD = gtk.WRAP_WORD
[132]55 JUSTIFY_CENTER = gtk.JUSTIFY_CENTER
[97]56
[144]57 CONTROL_MASK = gdk.CONTROL_MASK
58 SHIFT_MASK = gdk.SHIFT_MASK
59 BUTTON1_MASK = gdk.BUTTON1_MASK
60
61 SCROLL_UP = gdk.SCROLL_UP
62 SCROLL_DOWN = gdk.SCROLL_DOWN
63
64 SPIN_USER_DEFINED = gtk.SPIN_USER_DEFINED
65
[149]66 FILE_CHOOSER_ACTION_SELECT_FOLDER = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
[151]67 FILE_CHOOSER_ACTION_OPEN = gtk.FILE_CHOOSER_ACTION_OPEN
68 FILE_CHOOSER_ACTION_SAVE = gtk.FILE_CHOOSER_ACTION_SAVE
[149]69
[175]70 SELECTION_MULTIPLE = gtk.SELECTION_MULTIPLE
71
[220]72 SHADOW_IN = gtk.SHADOW_IN
73
74 POLICY_AUTOMATIC = gtk.POLICY_AUTOMATIC
75
[362]76 WEIGHT_NORMAL = pango.WEIGHT_NORMAL
[226]77 WEIGHT_BOLD = pango.WEIGHT_BOLD
78
[246]79 WINDOW_STATE_ICONIFIED = gdk.WINDOW_STATE_ICONIFIED
80 WINDOW_STATE_WITHDRAWN = gdk.WINDOW_STATE_WITHDRAWN
81
[264]82 SORT_ASCENDING = gtk.SORT_ASCENDING
83 SORT_DESCENDING = gtk.SORT_DESCENDING
84
[277]85 EVENT_BUTTON_PRESS = gdk.BUTTON_PRESS
86
[227]87 pixbuf_new_from_file = gdk.pixbuf_new_from_file
88
[97]89 def text2unicode(text):
90 """Convert the given text, returned by a Gtk widget, to Unicode."""
91 return unicode(text)
[276]92
93 def text2str(text):
94 """Convert the given text, returned by xstr to a string."""
95 return str(text)
[28]96else:
97 print "Using PyGObject"
98 pygobject = True
[29]99 from gi.repository import Gdk as gdk
[227]100 from gi.repository import GdkPixbuf as gdkPixbuf
[28]101 from gi.repository import Gtk as gtk
102 from gi.repository import GObject as gobject
103 from gi.repository import AppIndicator3 as appindicator
[44]104 from gi.repository import Pango as pango
[28]105 appIndicator = True
[76]106
[42]107 MESSAGETYPE_ERROR = gtk.MessageType.ERROR
[76]108 MESSAGETYPE_QUESTION = gtk.MessageType.QUESTION
[97]109 MESSAGETYPE_INFO = gtk.MessageType.INFO
[124]110 RESPONSETYPE_OK = gtk.ResponseType.OK
[76]111 RESPONSETYPE_YES = gtk.ResponseType.YES
[124]112 RESPONSETYPE_NO = gtk.ResponseType.NO
[123]113 RESPONSETYPE_ACCEPT = gtk.ResponseType.ACCEPT
114 RESPONSETYPE_REJECT = gtk.ResponseType.REJECT
[149]115 RESPONSETYPE_CANCEL = gtk.ResponseType.CANCEL
[93]116 ACCEL_VISIBLE = gtk.AccelFlags.VISIBLE
117 CONTROL_MASK = gdk.ModifierType.CONTROL_MASK
[123]118 DIALOG_MODAL = gtk.DialogFlags.MODAL
[127]119 WRAP_WORD = gtk.WrapMode.WORD
[132]120 JUSTIFY_CENTER = gtk.Justification.CENTER
[42]121
[144]122 CONTROL_MASK = gdk.ModifierType.CONTROL_MASK
123 SHIFT_MASK = gdk.ModifierType.SHIFT_MASK
124 BUTTON1_MASK = gdk.ModifierType.BUTTON1_MASK
125
126 SCROLL_UP = gdk.ScrollDirection.UP
127 SCROLL_DOWN = gdk.ScrollDirection.DOWN
128
129 SPIN_USER_DEFINED = gtk.SpinType.USER_DEFINED
130
[149]131 FILE_CHOOSER_ACTION_SELECT_FOLDER = gtk.FileChooserAction.SELECT_FOLDER
[151]132 FILE_CHOOSER_ACTION_OPEN = gtk.FileChooserAction.OPEN
133 FILE_CHOOSER_ACTION_SAVE = gtk.FileChooserAction.SAVE
[149]134
[175]135 SELECTION_MULTIPLE = gtk.SelectionMode.MULTIPLE
136
[220]137 SHADOW_IN = gtk.ShadowType.IN
138
139 POLICY_AUTOMATIC = gtk.PolicyType.AUTOMATIC
140
[362]141 WEIGHT_NORMAL = pango.Weight.NORMAL
[226]142 WEIGHT_BOLD = pango.Weight.BOLD
143
[246]144 WINDOW_STATE_ICONIFIED = gdk.WindowState.ICONIFIED
145 WINDOW_STATE_WITHDRAWN = gdk.WindowState.WITHDRAWN
146
[264]147 SORT_ASCENDING = gtk.SortType.ASCENDING
148 SORT_DESCENDING = gtk.SortType.DESCENDING
149
[277]150 EVENT_BUTTON_PRESS = gdk.EventType.BUTTON_PRESS
151
[227]152 pixbuf_new_from_file = gdkPixbuf.Pixbuf.new_from_file
153
[97]154 import codecs
155 _utf8Decoder = codecs.getdecoder("utf-8")
156
157 def text2unicode(str):
158 """Convert the given text, returned by a Gtk widget, to Unicode."""
159 return _utf8Decoder(str)[0]
160
[276]161 def text2str(text):
162 """Convert the given text, returned by xstr to a string."""
163 return _utf8Decoder(text)[0]
164
[28]165import cairo
166
[32]167#------------------------------------------------------------------------------
168
169class FlightStatusHandler(object):
170 """Base class for objects that handle the flight status in some way."""
171 def __init__(self):
172 self._stage = None
173 self._rating = 100
174 self._noGoReason = None
175
176 def resetFlightStatus(self):
177 """Reset the flight status."""
178 self._stage = None
179 self._rating = 100
180 self._noGoReason = None
181 self._updateFlightStatus()
182
183 def setStage(self, stage):
184 """Set the stage of the flight."""
185 if stage!=self._stage:
186 self._stage = stage
187 self._updateFlightStatus()
188
189 def setRating(self, rating):
190 """Set the rating to the given value."""
191 if rating!=self._rating:
192 self._rating = rating
193 if self._noGoReason is None:
194 self._updateFlightStatus()
195
196 def setNoGo(self, reason):
197 """Set a No-Go condition with the given reason."""
198 if self._noGoReason is None:
199 self._noGoReason = reason
200 self._updateFlightStatus()
201
202#------------------------------------------------------------------------------
[84]203
204class IntegerEntry(gtk.Entry):
205 """An entry that allows only either an empty value, or an integer."""
206 def __init__(self, defaultValue = None):
207 """Construct the entry."""
208 gtk.Entry.__init__(self)
209
[86]210 self.set_alignment(1.0)
211
[84]212 self._defaultValue = defaultValue
213 self._currentInteger = defaultValue
214 self._selfSetting = False
215 self._set_text()
216
217 self.connect("changed", self._handle_changed)
218
219 def get_int(self):
220 """Get the integer."""
221 return self._currentInteger
222
[241]223 def reset(self):
224 """Reset the integer."""
225 self.set_int(None)
226
[84]227 def set_int(self, value):
228 """Set the integer."""
229 if value!=self._currentInteger:
230 self._currentInteger = value
231 self.emit("integer-changed", self._currentInteger)
232 self._set_text()
233
234 def _handle_changed(self, widget):
235 """Handle the changed signal."""
236 if self._selfSetting:
237 return
238 text = self.get_text()
239 if text=="":
240 self.set_int(self._defaultValue)
241 else:
242 try:
243 self.set_int(int(text))
244 except:
245 self._set_text()
246
247 def _set_text(self):
248 """Set the text value from the current integer."""
249 self._selfSetting = True
250 self.set_text("" if self._currentInteger is None
251 else str(self._currentInteger))
252 self._selfSetting = False
253
254#------------------------------------------------------------------------------
255
256gobject.signal_new("integer-changed", IntegerEntry, gobject.SIGNAL_RUN_FIRST,
257 None, (object,))
258
259#------------------------------------------------------------------------------
[105]260
[227]261PROGRAM_NAME = "MAVA Logger X"
262
[232]263WINDOW_TITLE_BASE = PROGRAM_NAME + " " + _const.VERSION
[105]264
265#------------------------------------------------------------------------------
[175]266
267# A mapping of aircraft types to their screen names
[191]268aircraftNames = { _const.AIRCRAFT_B736 : xstr("aircraft_b736"),
269 _const.AIRCRAFT_B737 : xstr("aircraft_b737"),
270 _const.AIRCRAFT_B738 : xstr("aircraft_b738"),
271 _const.AIRCRAFT_B738C : xstr("aircraft_b738c"),
272 _const.AIRCRAFT_B733 : xstr("aircraft_b733"),
273 _const.AIRCRAFT_B734 : xstr("aircraft_b734"),
274 _const.AIRCRAFT_B735 : xstr("aircraft_b735"),
275 _const.AIRCRAFT_DH8D : xstr("aircraft_dh8d"),
276 _const.AIRCRAFT_B762 : xstr("aircraft_b762"),
277 _const.AIRCRAFT_B763 : xstr("aircraft_b763"),
278 _const.AIRCRAFT_CRJ2 : xstr("aircraft_crj2"),
279 _const.AIRCRAFT_F70 : xstr("aircraft_f70"),
280 _const.AIRCRAFT_DC3 : xstr("aircraft_dc3"),
281 _const.AIRCRAFT_T134 : xstr("aircraft_t134"),
282 _const.AIRCRAFT_T154 : xstr("aircraft_t154"),
283 _const.AIRCRAFT_YK40 : xstr("aircraft_yk40") }
[175]284
285#------------------------------------------------------------------------------
[221]286
[226]287def formatFlightLogLine(timeStr, line):
[221]288 """Format the given flight log line."""
289 """Format the given line for flight logging."""
290 if timeStr is not None:
291 line = timeStr + ": " + line
292 return line + "\n"
293
294#------------------------------------------------------------------------------
[226]295
296def addFaultTag(buffer):
297 """Add a tag named 'fault' to the given buffer."""
[362]298 buffer.create_tag("fault", foreground="red", weight=WEIGHT_BOLD)
[226]299
300#------------------------------------------------------------------------------
301
302def appendTextBuffer(buffer, text, isFault = False):
303 """Append the given line at the end of the given text buffer.
304
305 If isFault is set, use the tag named 'fault'."""
[345]306 insertTextBuffer(buffer, buffer.get_end_iter(), text, isFault)
[226]307
308#------------------------------------------------------------------------------
[345]309
310def insertTextBuffer(buffer, iter, text, isFault = False):
311 """Insert the given line into the given text buffer at the given iterator.
312
[362]313 If isFault is set, use the tag named 'fault' else use the tag named
314 'normal'."""
315 line = iter.get_line()
316
317 buffer.insert(iter, text)
318
319 iter0 = buffer.get_iter_at_line(line)
320 iter1 = buffer.get_iter_at_line(line+1)
[345]321 if isFault:
[362]322 buffer.apply_tag_by_name("fault", iter0, iter1)
[345]323 else:
[362]324 buffer.remove_all_tags(iter0, iter1)
[345]325
326#------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.