source: src/mlx/gui/common.py@ 730:9057b28f0c84

cef
Last change on this file since 730:9057b28f0c84 was 730:9057b28f0c84, checked in by István Váradi <ivaradi@…>, 8 years ago

Updated the manual

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