source: src/mlx/gui/common.py@ 603:6cf5eff2a6d7

Last change on this file since 603:6cf5eff2a6d7 was 575:a54baa5b89c3, checked in by István Váradi <ivaradi@…>, 9 years ago

Extracted some of the common imports into a non-GUI-specific module

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