source: src/mlx/gui/common.py@ 383:fcb9932b14ee

Last change on this file since 383:fcb9932b14ee was 373:cf2b6b8a3973, checked in by István Váradi <ivaradi@…>, 12 years ago

Added support for a secondary instance (#157)

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