def __init__(self, handle): ''' Init canvas, toolbars, etc. The toolbars are in sensor_toolbar.py and toolbar_side.py The audio controls are in audiograb.py The rendering happens in drawwaveform.py Logging is in journal.py ''' activity.Activity.__init__(self, handle) self.mode_images = {} self.mode_images['sound'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'media-audio.svg'), 45, 45) self.mode_images['resistance'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'resistance.svg'), 45, 45) self.mode_images['voltage'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'voltage.svg'), 45, 45) self.icon_colors = self.get_icon_colors_from_sugar() self.stroke_color, self.fill_color = self.icon_colors.split(',') self.nick = self.get_nick_from_sugar() self.CONTEXT = '' self.adjustmentf = None # Freq. slider control self.new_recording = False self.session_id = 0 self.read_metadata() self._active = True self._dsobject = None self.connect('notify::active', self._notify_active_cb) self.connect('destroy', self.on_quit) self.data_logger = DataLogger(self) self.hw = _get_hardware() log.debug('running on %s hardware' % (self.hw)) self.wave = DrawWaveform(self) if self.hw == XO15: self.audiograb = AudioGrab_XO15(self.wave.new_buffer, self) elif self.hw == XO175: self.audiograb = AudioGrab_XO175(self.wave.new_buffer, self) elif self.hw == XO4: self.audiograb = AudioGrab_XO4(self.wave.new_buffer, self) elif self.hw == XO1: self.audiograb = AudioGrab_XO1(self.wave.new_buffer, self) else: self.audiograb = AudioGrab_Unknown(self.wave.new_buffer, self) # no sharing self.max_participants = 1 box3 = gtk.HBox(False, 0) box3.pack_start(self.wave, True, True, 0) # We need event boxes in order to set the background color. side_eventboxes = [] self.side_toolbars = [] for i in range(self.audiograb.channels): side_eventboxes.append(gtk.EventBox()) side_eventboxes[i].modify_bg( gtk.STATE_NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) self.side_toolbars.append(SideToolbar(self, channel=i)) side_eventboxes[i].add(self.side_toolbars[i].box1) box3.pack_start(side_eventboxes[i], False, True, 0) event_box = gtk.EventBox() self.text_box = gtk.Label() self.text_box.set_justify(gtk.JUSTIFY_LEFT) alist = pango.AttrList() alist.insert(pango.AttrForeground(65535, 65535, 65535, 0, -1)) self.text_box.set_attributes(alist) event_box.add(self.text_box) event_box.modify_bg(gtk.STATE_NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) box1 = gtk.VBox(False, 0) box1.pack_start(box3, True, True, 0) box1.pack_start(event_box, False, True, 0) self.set_canvas(box1) toolbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() self.sensor_toolbar = SensorToolbar(self, self.audiograb.channels) #Added by Lego # Turn on bobot Server log.debug('Starting Server...') self.bobot = subprocess.Popen(['python', 'pybot_server.py'], cwd='./pybot') log.debug("Start : %s" % time.ctime()) time.sleep(bobot_delay_start) log.debug("Started : %s" % time.ctime()) self.lego_toolbar = LegoToolbar(self, self.audiograb.channels) #Lego end # Added by Butia self.butia_toolbar = ButiaToolbar(self, self.audiograb.channels) #Butia end #Added by Arduino self.arduino_toolbar = ArduinoToolbar(self, self.audiograb.channels) #Arduino end self.tuning_toolbar = TuningToolbar(self) self.new_instrument_toolbar = InstrumentToolbar(self) self._extras_toolbar = gtk.Toolbar() self.control_toolbar = gtk.Toolbar() sensor_button = ToolbarButton(label=_('Sensors'), page=self.sensor_toolbar, icon_name='sensor-tools') toolbox.toolbar.insert(sensor_button, -1) #Added by Lego sensor_button.connect('clicked', self._sensor_toolbar_cb) #Lego end sensor_button.show() lego_button = ToolbarButton(label=_('Lego'), page=self.lego_toolbar, icon_name='LEGO-tools') toolbox.toolbar.insert(lego_button, -1) lego_button.connect('clicked', self._lego_toolbar_cb) lego_button.show() #Lego end #Added by Butia sensor_button.connect('clicked', self._sensor_toolbar_cb) #Butia end sensor_button.show() #Added by Butia butia_button = ToolbarButton(label=_('Butia'), page=self.butia_toolbar, icon_name='butia-tools') toolbox.toolbar.insert(butia_button, -1) butia_button.connect('clicked', self._butia_toolbar_cb) butia_button.show() #Butia end #Added by Arduino sensor_button.connect('clicked', self._sensor_toolbar_cb) #Arduino end sensor_button.show() #Added by Arduino arduino_button = ToolbarButton(label=_('Arduino'), page=self.arduino_toolbar, icon_name='arduino-tools') toolbox.toolbar.insert(arduino_button, -1) arduino_button.connect('clicked', self._arduino_toolbar_cb) arduino_button.show() #Arduino end tuning_button = ToolbarButton( # TRANS: Tuning insruments label=_('Tuning'), page=self.tuning_toolbar, icon_name='tuning-tools') toolbox.toolbar.insert(tuning_button, -1) tuning_button.show() new_instrument_button = ToolbarButton(label=_('Add instrument'), page=self.new_instrument_toolbar, icon_name='view-source') toolbox.toolbar.insert(new_instrument_button, -1) new_instrument_button.show() #Added by butia self.butia_toolbar.show() #Butia end self._extras_button = ToolbarButton(page=self._extras_toolbar, icon_name='domain-time') toolbox.toolbar.insert(self._extras_button, -1) self._extras_toolbar_item = gtk.ToolItem() self._extras_toolbar.insert(self._extras_toolbar_item, -1) self._extras_button.hide() self.sensor_toolbar.show() self._extra_tools = gtk.HBox() # Set up Frequency-domain Button self.freq = ToolButton('domain-time') self.freq.set_tooltip(_('Time Base')) self.freq.connect('clicked', self.timefreq_control) self.freq.show() self._extra_tools.add(self.freq) self.sensor_toolbar.add_frequency_slider(self._extra_tools) self._extra_item = gtk.ToolItem() self._extra_item.add(self._extra_tools) self._extra_tools.show() toolbox.toolbar.insert(self._extra_item, -1) self._extra_item.show() self._pause = ToolButton('media-playback-pause') self._pause.set_tooltip(_('Freeze the display')) self._pause.connect('clicked', self._pause_play_cb) self._pause.show() toolbox.toolbar.insert(self._pause, -1) self._capture = ToolButton('image-saveoff') self._capture.set_tooltip(_('Capture sample now')) self._capture.connect('clicked', self._capture_cb) self._capture.show() toolbox.toolbar.insert(self._capture, -1) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbox.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) stop_button.props.accelerator = _('<Ctrl>Q') toolbox.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbox(toolbox) sensor_button.set_expanded(True) toolbox.show() self.sensor_toolbar.update_page_size() self.show_all() self._first = True # Always start in 'sound' mode. self.sensor_toolbar.set_mode('sound') self.sensor_toolbar.set_sound_context() self.sensor_toolbar.set_show_hide_windows() self.wave.set_active(True) self.wave.set_context_on() gtk.gdk.screen_get_default().connect('size-changed', self._configure_cb) self._configure_cb(None)
class MeasureActivity(activity.Activity): ''' Oscilloscope Sugar activity ''' def __init__(self, handle): ''' Init canvas, toolbars, etc. The toolbars are in sensor_toolbar.py and toolbar_side.py The audio controls are in audiograb.py The rendering happens in drawwaveform.py Logging is in journal.py ''' activity.Activity.__init__(self, handle) self.mode_images = {} self.mode_images['sound'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'media-audio.svg'), 45, 45) self.mode_images['resistance'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'resistance.svg'), 45, 45) self.mode_images['voltage'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'voltage.svg'), 45, 45) self.icon_colors = self.get_icon_colors_from_sugar() self.stroke_color, self.fill_color = self.icon_colors.split(',') self.nick = self.get_nick_from_sugar() self.CONTEXT = '' self.adjustmentf = None # Freq. slider control self.new_recording = False self.session_id = 0 self.read_metadata() self._active = True self._dsobject = None self.connect('notify::active', self._notify_active_cb) self.connect('destroy', self.on_quit) self.data_logger = DataLogger(self) self.hw = _get_hardware() log.debug('running on %s hardware' % (self.hw)) self.wave = DrawWaveform(self) if self.hw == XO15: self.audiograb = AudioGrab_XO15(self.wave.new_buffer, self) elif self.hw == XO175: self.audiograb = AudioGrab_XO175(self.wave.new_buffer, self) elif self.hw == XO4: self.audiograb = AudioGrab_XO4(self.wave.new_buffer, self) elif self.hw == XO1: self.audiograb = AudioGrab_XO1(self.wave.new_buffer, self) else: self.audiograb = AudioGrab_Unknown(self.wave.new_buffer, self) # no sharing self.max_participants = 1 box3 = gtk.HBox(False, 0) box3.pack_start(self.wave, True, True, 0) # We need event boxes in order to set the background color. side_eventboxes = [] self.side_toolbars = [] for i in range(self.audiograb.channels): side_eventboxes.append(gtk.EventBox()) side_eventboxes[i].modify_bg( gtk.STATE_NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) self.side_toolbars.append(SideToolbar(self, channel=i)) side_eventboxes[i].add(self.side_toolbars[i].box1) box3.pack_start(side_eventboxes[i], False, True, 0) event_box = gtk.EventBox() self.text_box = gtk.Label() self.text_box.set_justify(gtk.JUSTIFY_LEFT) alist = pango.AttrList() alist.insert(pango.AttrForeground(65535, 65535, 65535, 0, -1)) self.text_box.set_attributes(alist) event_box.add(self.text_box) event_box.modify_bg(gtk.STATE_NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) box1 = gtk.VBox(False, 0) box1.pack_start(box3, True, True, 0) box1.pack_start(event_box, False, True, 0) self.set_canvas(box1) toolbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() self.sensor_toolbar = SensorToolbar(self, self.audiograb.channels) #Added by Lego # Turn on bobot Server log.debug('Starting Server...') self.bobot = subprocess.Popen(['python', 'pybot_server.py'], cwd='./pybot') log.debug("Start : %s" % time.ctime()) time.sleep(bobot_delay_start) log.debug("Started : %s" % time.ctime()) self.lego_toolbar = LegoToolbar(self, self.audiograb.channels) #Lego end # Added by Butia self.butia_toolbar = ButiaToolbar(self, self.audiograb.channels) #Butia end #Added by Arduino self.arduino_toolbar = ArduinoToolbar(self, self.audiograb.channels) #Arduino end self.tuning_toolbar = TuningToolbar(self) self.new_instrument_toolbar = InstrumentToolbar(self) self._extras_toolbar = gtk.Toolbar() self.control_toolbar = gtk.Toolbar() sensor_button = ToolbarButton(label=_('Sensors'), page=self.sensor_toolbar, icon_name='sensor-tools') toolbox.toolbar.insert(sensor_button, -1) #Added by Lego sensor_button.connect('clicked', self._sensor_toolbar_cb) #Lego end sensor_button.show() lego_button = ToolbarButton(label=_('Lego'), page=self.lego_toolbar, icon_name='LEGO-tools') toolbox.toolbar.insert(lego_button, -1) lego_button.connect('clicked', self._lego_toolbar_cb) lego_button.show() #Lego end #Added by Butia sensor_button.connect('clicked', self._sensor_toolbar_cb) #Butia end sensor_button.show() #Added by Butia butia_button = ToolbarButton(label=_('Butia'), page=self.butia_toolbar, icon_name='butia-tools') toolbox.toolbar.insert(butia_button, -1) butia_button.connect('clicked', self._butia_toolbar_cb) butia_button.show() #Butia end #Added by Arduino sensor_button.connect('clicked', self._sensor_toolbar_cb) #Arduino end sensor_button.show() #Added by Arduino arduino_button = ToolbarButton(label=_('Arduino'), page=self.arduino_toolbar, icon_name='arduino-tools') toolbox.toolbar.insert(arduino_button, -1) arduino_button.connect('clicked', self._arduino_toolbar_cb) arduino_button.show() #Arduino end tuning_button = ToolbarButton( # TRANS: Tuning insruments label=_('Tuning'), page=self.tuning_toolbar, icon_name='tuning-tools') toolbox.toolbar.insert(tuning_button, -1) tuning_button.show() new_instrument_button = ToolbarButton(label=_('Add instrument'), page=self.new_instrument_toolbar, icon_name='view-source') toolbox.toolbar.insert(new_instrument_button, -1) new_instrument_button.show() #Added by butia self.butia_toolbar.show() #Butia end self._extras_button = ToolbarButton(page=self._extras_toolbar, icon_name='domain-time') toolbox.toolbar.insert(self._extras_button, -1) self._extras_toolbar_item = gtk.ToolItem() self._extras_toolbar.insert(self._extras_toolbar_item, -1) self._extras_button.hide() self.sensor_toolbar.show() self._extra_tools = gtk.HBox() # Set up Frequency-domain Button self.freq = ToolButton('domain-time') self.freq.set_tooltip(_('Time Base')) self.freq.connect('clicked', self.timefreq_control) self.freq.show() self._extra_tools.add(self.freq) self.sensor_toolbar.add_frequency_slider(self._extra_tools) self._extra_item = gtk.ToolItem() self._extra_item.add(self._extra_tools) self._extra_tools.show() toolbox.toolbar.insert(self._extra_item, -1) self._extra_item.show() self._pause = ToolButton('media-playback-pause') self._pause.set_tooltip(_('Freeze the display')) self._pause.connect('clicked', self._pause_play_cb) self._pause.show() toolbox.toolbar.insert(self._pause, -1) self._capture = ToolButton('image-saveoff') self._capture.set_tooltip(_('Capture sample now')) self._capture.connect('clicked', self._capture_cb) self._capture.show() toolbox.toolbar.insert(self._capture, -1) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbox.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) stop_button.props.accelerator = _('<Ctrl>Q') toolbox.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbox(toolbox) sensor_button.set_expanded(True) toolbox.show() self.sensor_toolbar.update_page_size() self.show_all() self._first = True # Always start in 'sound' mode. self.sensor_toolbar.set_mode('sound') self.sensor_toolbar.set_sound_context() self.sensor_toolbar.set_show_hide_windows() self.wave.set_active(True) self.wave.set_context_on() gtk.gdk.screen_get_default().connect('size-changed', self._configure_cb) self._configure_cb(None) def _configure_cb(self, event): ''' Screen size has changed, so check to see if the toolbar elements still fit.''' self.width = gtk.gdk.screen_width() if self.width < style.GRID_CELL_SIZE * 14: self._extras_button.show() if self._extra_tools in self._extra_item: self._extra_item.remove(self._extra_tools) if not self._extra_tools in self._extras_toolbar_item: self._extras_toolbar_item.add(self._extra_tools) self._extras_toolbar_item.show() self.sensor_toolbar.log_label.hide() self.sensor_toolbar.trigger_label.hide() else: self._extras_button.hide() if self._extra_tools in self._extras_toolbar_item: self._extras_toolbar_item.remove(self._extra_tools) if not self._extra_tools in self._extra_item: self._extra_item.add(self._extra_tools) if self._extras_button.is_expanded(): self._extras_button.set_expanded(False) self._extras_toolbar_item.hide() self.sensor_toolbar.log_label.show() self.sensor_toolbar.trigger_label.show() self._extra_tools.show() #Added by Lego def _sensor_toolbar_cb(self, button=None): '''Callback al hacer clic en sensor toolbar''' log.debug('Click en sensor toolbar') self.sensor_toolbar.set_mode('sound') self.sensor_toolbar.set_sound_context() self.sensor_toolbar.set_show_hide_windows() self.limpiar_canales() self.CONTEXT = 'sound' #Added by Lego def _lego_toolbar_cb(self, button=None): '''Callback al hacer clic en lego toolbar''' log.debug('Click en lego toolbar') self.audiograb.stop_grabbing() self.limpiar_canales() log.debug('CONTEXTO ANTERIOR: %s' % self.CONTEXT) self.CONTEXT = 'lego' self.sensor_toolbar.update_string_for_textbox() #Added by Butia def _butia_toolbar_cb(self, button=None): '''Callback al hacer clic en butia toolbar''' log.debug('Click en butia toolbar') self.audiograb.stop_grabbing() self.limpiar_canales() log.debug('CONTEXTO ANTERIOR: %s' % self.CONTEXT) self.CONTEXT = 'butia' self.sensor_toolbar.update_string_for_textbox() #Added by Arduino def _arduino_toolbar_cb(self, button=None): '''Callback al hacer clic en arduino toolbar''' log.debug('Click en arduino toolbar') self.audiograb.stop_grabbing() self.limpiar_canales() log.debug('CONTEXTO ANTERIOR: %s' % self.CONTEXT) log.debug('***** ARDUINO CONTEXT ******') self.CONTEXT = 'arduino' self.sensor_toolbar.update_string_for_textbox() #Added by lego def limpiar_canales(self): for i in range(self.audiograb.channels): self.wave.ringbuffer[i] = RingBuffer1d(self.wave.max_samples, dtype='int16') self.wave.new_buffer([0], i) def on_quit(self, data=None): '''Clean up, close journal on quit''' self.audiograb.on_activity_quit() def _notify_active_cb(self, widget, pspec): ''' Callback to handle starting/pausing capture when active/idle ''' if self._first: log.debug('_notify_active_cb: start grabbing') self.audiograb.start_grabbing() self._first = False elif not self.props.active: log.debug('_notify_active_cb: pause grabbing') self.audiograb.pause_grabbing() elif self.props.active: log.debug('_notify_active_cb: resume grabbing') self.audiograb.resume_grabbing() self._active = self.props.active self.wave.set_active(self._active) def read_metadata(self): ''' Any saved instruments? ''' for data in self.metadata.keys(): if data[0] == PREFIX: # instrument log.debug('found an instrument: %s' % (data[1:])) instrument = data[1:] log.debug(self.metadata[data]) INSTRUMENT_DICT[instrument] = [] for note in self.metadata[data].split(' '): INSTRUMENT_DICT[instrument].append(float(note)) def write_file(self, file_path): ''' Write data to journal, if there is any data to write ''' # Check to see if there are any new instruments to save if hasattr(self, 'new_instrument_toolbar'): for i, instrument in enumerate( self.new_instrument_toolbar.new_instruments): log.debug('saving %s' % (instrument)) notes = '' for i, note in enumerate(INSTRUMENT_DICT[instrument]): notes += '%0.3f' % note if i < len(INSTRUMENT_DICT[instrument]) - 1: notes += ' ' self.metadata['%s%s' % (PREFIX, instrument)] = notes # FIXME: Don't use ""s around data if hasattr(self, 'data_logger') and \ self.new_recording and \ len(self.data_logger.data_buffer) > 0: # Append new data to Journal entry fd = open(file_path, 'ab') writer = csv.writer(fd) # Also output to a separate file as a workaround to Ticket 2127 # (the assumption being that this file will be opened by the user) tmp_data_file = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'], 'instance', 'sensor_data' + '.csv') log.debug('saving sensor data to %s' % (tmp_data_file)) if self._dsobject is None: # first time, so create fd2 = open(tmp_data_file, 'wb') else: # we've been here before, so append fd2 = open(tmp_data_file, 'ab') writer2 = csv.writer(fd2) # Pop data off start of buffer until it is empty for i in range(len(self.data_logger.data_buffer)): datum = self.data_logger.data_buffer.pop(0) writer.writerow([datum]) writer2.writerow([datum]) fd.close() fd2.close() # Set the proper mimetype self.metadata['mime_type'] = 'text/csv' if os.path.exists(tmp_data_file): if self._dsobject is None: self._dsobject = datastore.create() self._dsobject.metadata['title'] = _('Measure Log') self._dsobject.metadata['icon-color'] = self.icon_colors self._dsobject.metadata['mime_type'] = 'text/csv' self._dsobject.set_file_path(tmp_data_file) datastore.write(self._dsobject) # remove(tmp_data_file) def read_file(self, file_path): ''' Read csv data from journal on start ''' reader = csv.reader(open(file_path, "rb")) # Count the number of sessions. for row in reader: if len(row) > 0: if row[0].find(_('Session')) != -1: # log.debug('found a previously recorded session') self.session_id += 1 elif row[0].find('abiword') != -1: # File has been opened by Write cannot be read by Measure # See Ticket 2127 log.error('File was opened by Write: Measure cannot read') self.data_logger.data_buffer = [] return self.data_logger.data_buffer.append(row[0]) if self.session_id == 0: # log.debug('setting data_logger buffer to []') self.data_logger.data_buffer = [] def _pause_play_cb(self, button=None): ''' Callback for Pause Button ''' if self.audiograb.get_freeze_the_display(): self.audiograb.set_freeze_the_display(False) self._pause.set_icon('media-playback-start') self._pause.set_tooltip(_('Unfreeze the display')) self._pause.show() else: self.audiograb.set_freeze_the_display(True) self._pause.set_icon('media-playback-pause') self._pause.set_tooltip(_('Freeze the display')) self._pause.show() return False def _capture_cb(self, button=None): ''' Callback for screen capture ''' if self.CONTEXT == 'butia': self.butia_toolbar.take_screenshot() self.audiograb.take_screenshot() def timefreq_control(self, button=None): ''' Callback for Freq. Button ''' # Turn off logging when switching modes if self.audiograb.we_are_logging: self.sensor_toolbar.record_control_cb() #Added by Lego self.lego_toolbar.set_sound_context() #Lego end #Added by Butia self.butia_toolbar.set_sound_context() #Butia end #Added by Arduino self.arduino_toolbar.set_sound_context() #Arduino end if self.wave.get_fft_mode(): self.wave.set_fft_mode(False) self.freq.set_icon('domain-time') self.freq.set_tooltip(_('Time Base')) else: self.wave.set_fft_mode(True) self.freq.set_icon('domain-freq') self.freq.set_tooltip(_('Frequency Base')) # Turn off triggering in Frequencey Base self.sensor_toolbar.trigger_none.set_active(True) self.wave.set_trigger(self.wave.TRIGGER_NONE) # Turn off invert in Frequencey Base for i in range(self.audiograb.channels): if self.wave.get_invert_state(channel=i): self.side_toolbars[i].invert_control_cb() self.sensor_toolbar.update_string_for_textbox() return False def get_icon_colors_from_sugar(self): ''' Returns the icon colors from the Sugar profile ''' return profile.get_color().to_string() def get_nick_from_sugar(self): ''' Returns nick from Sugar ''' return profile.get_nick_name()
def __init__(self, handle): """ Init canvas, toolbars, etc. The toolbars are in toolbar_top.py and toolbar_side.py The audio controls are in audiograb.py The rendering happens in drawwaveform.py Logging (Journal interactions) are in journal.py """ activity.Activity.__init__(self, handle) try: tmp_dir = path.join(activity.get_activity_root(), "data") except AttributeError: # Early versions of Sugar (e.g., 656) didn't support # get_activity_root() tmp_dir = path.join( environ['HOME'], ".sugar/default/org.laptop.MeasureActivity/data") self.using_gconf = _using_gconf self.icon_colors = self.get_icon_colors_from_sugar() self.stroke_color, self.fill_color = self.icon_colors.split(',') self.nick = self.get_nick_from_sugar() self.active_status = True self.ACTIVE = True self.LOGGING_IN_SESSION = False self.CONTEXT = '' self.adjustmentf = None # Freq. slider control self.connect('notify::active', self._active_cb) self.connect('destroy', self.on_quit) self.hw = _get_hardware() self.closedSound = None self.openedSound = None self.session_id = 0 self.ji = JournalInteraction(self) colorBlack = Color() colorBlack.init_rgba(0, 0, 0, 255) self.playsoundWin = PlayVideoWindow(colorBlack.gColor) self.playsound = Gplay() self.playsound.window = self.playsoundWin self.wave = DrawWaveform(self, self.playsound) self.hw = _get_hardware() log.debug('running on %s hardware' % (self.hw)) if self.hw == XO15: self.audiograb = AudioGrab_XO15(self.wave.new_buffer, self) elif self.hw == XO1: self.audiograb = AudioGrab_XO1(self.wave.new_buffer, self) else: self.audiograb = AudioGrab_Unknown(self.wave.new_buffer, self) # no sharing self.max_participants = 1 self.has_toolbarbox = _has_toolbarbox self.side_toolbar = SideToolbar(self) self.text_box = TextBox() self.box3 = gtk.HBox(False, 0) self.box3.pack_start(self.wave, True, True, 0) self.box3.pack_start(self.side_toolbar.box1, False, True, 0) self.box1 = gtk.VBox(False, 0) self.box1.pack_start(self.box3, True, True, 0) self.box1.pack_start(self.text_box.box_main, False, True, 0) self.set_canvas(self.box1) self.toolbox = None if self.has_toolbarbox: toolbox = ToolbarBox() self.toolbox = toolbox activity_button = ActivityToolbarButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() else: toolbox = ActivityToolbox(self) self.toolbox = toolbox # no sharing if hasattr(toolbox, 'share'): toolbox.share.hide() elif hasattr(toolbox, 'props'): toolbox.props.visible = False self.set_toolbox(toolbox) toolbox.connect('current-toolbar-changed', self._toolbar_changed_cb) self.sound_toolbar = SoundToolbar(self) if self.has_toolbarbox: self._sound_button = ToolbarButton(label=_('Sound'), page=self.sound_toolbar, icon_name='sound-tools') toolbox.toolbar.insert(self._sound_button, -1) self._sound_button.show() else: toolbox.add_toolbar(_('Sound'), self.sound_toolbar) self.sound_toolbar.show() if _is_xo(self.hw): self.sensor_toolbar = SensorToolbar(self) if self.has_toolbarbox: self._sensor_button = ToolbarButton(label=_('Sensors'), page=self.sensor_toolbar, icon_name='sensor-tools') toolbox.toolbar.insert(self._sensor_button, -1) self._sensor_button.show() else: toolbox.add_toolbar(_('Sensors'), self.sensor_toolbar) self.sensor_toolbar.show() if self.has_toolbarbox: _separator = gtk.SeparatorToolItem() _separator.props.draw = False toolbox.toolbar.insert(_separator, -1) _separator.show() # add a "dummy" button to indicate what capture mode we are in self.label_button = ToolButton('domain-time2') toolbox.toolbar.insert(self.label_button, -1) self.label_button.show() self.label_button.set_tooltip(_('Time Base')) self.label_button.connect('clicked', self._label_cb) self.sound_toolbar.add_frequency_slider(toolbox.toolbar) _separator = gtk.SeparatorToolItem() _separator.props.draw = False _separator.set_expand(True) toolbox.toolbar.insert(_separator, -1) _separator.show() _stop_button = StopButton(self) _stop_button.props.accelerator = _('<Ctrl>Q') toolbox.toolbar.insert(_stop_button, -1) _stop_button.show() self.set_toolbox(toolbox) self._sound_button.set_expanded(True) else: toolbox.set_current_toolbar(TOOLBARS.index('sensor')) toolbox.show() self.sound_toolbar.update_page_size() self.show_all() self.first = True self.set_sound_context() self.set_sensor_context() self.set_show_hide_windows() self.wave.set_active(True) self.wave.set_context_on() self.set_show_hide_windows()
class MeasureActivity(activity.Activity): ''' Oscilloscope Sugar activity ''' def __init__(self, handle): ''' Init canvas, toolbars, etc. The toolbars are in sensor_toolbar.py and toolbar_side.py The audio controls are in audiograb.py The rendering happens in drawwaveform.py Logging is in journal.py ''' activity.Activity.__init__(self, handle) if Gst.version() == (1L, 0L, 10L, 0L): return self._incompatible() self._image_counter = 1 def mode_image(name): path = os.path.join(ICONS_DIR, name) return GdkPixbuf.Pixbuf.new_from_file_at_size(path, 45, 45) self.mode_images = {} self.mode_images['sound'] = mode_image('media-audio.svg') self.mode_images['resistance'] = mode_image('resistance.svg') self.mode_images['voltage'] = mode_image('voltage.svg') self.icon_colors = self.get_icon_colors_from_sugar() self.stroke_color, self.fill_color = self.icon_colors.split(',') self.nick = self.get_nick_from_sugar() self.CONTEXT = '' self.adjustmentf = None # Freq. slider control self.hw = _get_hardware_model() self.new_recording = False self.session_id = 0 self.read_metadata() self._active = True self._dsobject = None self.connect('notify::active', self._notify_active_cb) self.connect('destroy', self.on_quit) self.data_logger = DataLogger(self) self.wave = DrawWaveform(self) ag = audiograb.AudioGrab_Unknown ags = {'XO-1': audiograb.AudioGrab_XO1, 'XO-1.5': audiograb.AudioGrab_XO15, 'XO-1.75': audiograb.AudioGrab_XO175, 'XO-4': audiograb.AudioGrab_XO4, 'NL3': audiograb.AudioGrab_NL3, } if self.hw in ags: ag = ags[self.hw] self.audiograb = ag(self.wave.new_buffer, self) # no sharing self.max_participants = 1 box3 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, homogeneous=False, spacing=0) box3.pack_start(self.wave, True, True, 0) # We need event boxes in order to set the background color. side_eventboxes = [] self.side_toolbars = [] for i in range(self.audiograb.channels): side_eventboxes.append(Gtk.EventBox()) side_eventboxes[i].modify_bg( Gtk.StateType.NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) self.side_toolbars.append(SideToolbar(self, channel=i)) side_eventboxes[i].add(self.side_toolbars[i].box1) box3.pack_start(side_eventboxes[i], False, True, 0) event_box = Gtk.EventBox() self.text_box = Gtk.Label() self.text_box.set_justify(Gtk.Justification.LEFT) rgba = Gdk.RGBA() rgba.red, rgba.green, rgba.blue, rgba.alpha = 1., 1., 1., 1. self.text_box.override_background_color(Gtk.StateFlags.NORMAL, rgba) event_box.add(self.text_box) event_box.modify_bg( Gtk.StateType.NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) box1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, homogeneous=False, spacing=0) box1.pack_start(box3, True, True, 0) box1.pack_start(event_box, False, True, 0) self.set_canvas(box1) toolbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() self.sensor_toolbar = SensorToolbar(self, self.audiograb.channels) self.tuning_toolbar = TuningToolbar(self) self.new_instrument_toolbar = InstrumentToolbar(self) self._extras_toolbar = Gtk.Toolbar() self.control_toolbar = Gtk.Toolbar() sensor_button = ToolbarButton( label=_('Sensors'), page=self.sensor_toolbar, icon_name='sensor-tools') toolbox.toolbar.insert(sensor_button, -1) sensor_button.show() tuning_button = ToolbarButton( # TRANS: Tuning insruments label=_('Tuning'), page=self.tuning_toolbar, icon_name='tuning-tools') toolbox.toolbar.insert(tuning_button, -1) tuning_button.show() new_instrument_button = ToolbarButton( label=_('Add instrument'), page=self.new_instrument_toolbar, icon_name='view-source') toolbox.toolbar.insert(new_instrument_button, -1) new_instrument_button.show() self._extras_button = ToolbarButton( page=self._extras_toolbar, icon_name='domain-time') toolbox.toolbar.insert(self._extras_button, -1) self._extras_toolbar_item = Gtk.ToolItem() self._extras_toolbar.insert(self._extras_toolbar_item, -1) self._extras_button.hide() self.sensor_toolbar.show() self._extra_tools = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) # Set up Frequency-domain Button self.freq = ToolButton('domain-time') self.freq.set_tooltip(_('Time Base')) self.freq.connect('clicked', self.timefreq_control) self.freq.show() self._extra_tools.add(self.freq) self.sensor_toolbar.add_frequency_slider(self._extra_tools) self._extra_item = Gtk.ToolItem() self._extra_item.add(self._extra_tools) self._extra_tools.show() toolbox.toolbar.insert(self._extra_item, -1) self._extra_item.show() self._pause = ToolButton('media-playback-pause') self._pause.set_tooltip(_('Freeze the display')) self._pause.connect('clicked', self._pause_play_cb) self._pause.show() toolbox.toolbar.insert(self._pause, -1) self._capture = ToolButton('image-saveoff') self._capture.set_tooltip(_('Capture sample now')) self._capture.connect('clicked', self._capture_cb) self._capture.show() toolbox.toolbar.insert(self._capture, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbox.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) stop_button.props.accelerator = _('<Ctrl>Q') toolbox.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbox) sensor_button.set_expanded(True) toolbox.show() self.sensor_toolbar.update_page_size() self.show_all() self._first = True # Always start in 'sound' mode. self.sensor_toolbar.set_mode('sound') self.sensor_toolbar.set_sound_context() self.sensor_toolbar.set_show_hide_windows() self.wave.set_active(True) self.wave.set_context_on() screen = Gdk.Screen.get_default() screen.connect('size-changed', self.__screen_size_changed_cb) self.__screen_size_changed_cb(None)
class MeasureActivity(activity.Activity): """ Oscilloscope Sugar activity """ def __init__(self, handle): """ Init canvas, toolbars, etc. The toolbars are in toolbar_top.py and toolbar_side.py The audio controls are in audiograb.py The rendering happens in drawwaveform.py Logging (Journal interactions) are in journal.py """ activity.Activity.__init__(self, handle) try: tmp_dir = path.join(activity.get_activity_root(), "data") except AttributeError: # Early versions of Sugar (e.g., 656) didn't support # get_activity_root() tmp_dir = path.join( environ['HOME'], ".sugar/default/org.laptop.MeasureActivity/data") self.using_gconf = _using_gconf self.icon_colors = self.get_icon_colors_from_sugar() self.stroke_color, self.fill_color = self.icon_colors.split(',') self.nick = self.get_nick_from_sugar() self.active_status = True self.ACTIVE = True self.LOGGING_IN_SESSION = False self.CONTEXT = '' self.adjustmentf = None # Freq. slider control self.connect('notify::active', self._active_cb) self.connect('destroy', self.on_quit) self.hw = _get_hardware() self.closedSound = None self.openedSound = None self.session_id = 0 self.ji = JournalInteraction(self) colorBlack = Color() colorBlack.init_rgba(0, 0, 0, 255) self.playsoundWin = PlayVideoWindow(colorBlack.gColor) self.playsound = Gplay() self.playsound.window = self.playsoundWin self.wave = DrawWaveform(self, self.playsound) self.hw = _get_hardware() log.debug('running on %s hardware' % (self.hw)) if self.hw == XO15: self.audiograb = AudioGrab_XO15(self.wave.new_buffer, self) elif self.hw == XO1: self.audiograb = AudioGrab_XO1(self.wave.new_buffer, self) else: self.audiograb = AudioGrab_Unknown(self.wave.new_buffer, self) # no sharing self.max_participants = 1 self.has_toolbarbox = _has_toolbarbox self.side_toolbar = SideToolbar(self) self.text_box = TextBox() self.box3 = gtk.HBox(False, 0) self.box3.pack_start(self.wave, True, True, 0) self.box3.pack_start(self.side_toolbar.box1, False, True, 0) self.box1 = gtk.VBox(False, 0) self.box1.pack_start(self.box3, True, True, 0) self.box1.pack_start(self.text_box.box_main, False, True, 0) self.set_canvas(self.box1) self.toolbox = None if self.has_toolbarbox: toolbox = ToolbarBox() self.toolbox = toolbox activity_button = ActivityToolbarButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() else: toolbox = ActivityToolbox(self) self.toolbox = toolbox # no sharing if hasattr(toolbox, 'share'): toolbox.share.hide() elif hasattr(toolbox, 'props'): toolbox.props.visible = False self.set_toolbox(toolbox) toolbox.connect('current-toolbar-changed', self._toolbar_changed_cb) self.sound_toolbar = SoundToolbar(self) if self.has_toolbarbox: self._sound_button = ToolbarButton(label=_('Sound'), page=self.sound_toolbar, icon_name='sound-tools') toolbox.toolbar.insert(self._sound_button, -1) self._sound_button.show() else: toolbox.add_toolbar(_('Sound'), self.sound_toolbar) self.sound_toolbar.show() if _is_xo(self.hw): self.sensor_toolbar = SensorToolbar(self) if self.has_toolbarbox: self._sensor_button = ToolbarButton(label=_('Sensors'), page=self.sensor_toolbar, icon_name='sensor-tools') toolbox.toolbar.insert(self._sensor_button, -1) self._sensor_button.show() else: toolbox.add_toolbar(_('Sensors'), self.sensor_toolbar) self.sensor_toolbar.show() if self.has_toolbarbox: _separator = gtk.SeparatorToolItem() _separator.props.draw = False toolbox.toolbar.insert(_separator, -1) _separator.show() # add a "dummy" button to indicate what capture mode we are in self.label_button = ToolButton('domain-time2') toolbox.toolbar.insert(self.label_button, -1) self.label_button.show() self.label_button.set_tooltip(_('Time Base')) self.label_button.connect('clicked', self._label_cb) self.sound_toolbar.add_frequency_slider(toolbox.toolbar) _separator = gtk.SeparatorToolItem() _separator.props.draw = False _separator.set_expand(True) toolbox.toolbar.insert(_separator, -1) _separator.show() _stop_button = StopButton(self) _stop_button.props.accelerator = _('<Ctrl>Q') toolbox.toolbar.insert(_stop_button, -1) _stop_button.show() self.set_toolbox(toolbox) self._sound_button.set_expanded(True) else: toolbox.set_current_toolbar(TOOLBARS.index('sensor')) toolbox.show() self.sound_toolbar.update_page_size() self.show_all() self.first = True self.set_sound_context() self.set_sensor_context() self.set_show_hide_windows() self.wave.set_active(True) self.wave.set_context_on() self.set_show_hide_windows() #wait(10) #self.toolbox.set_current_toolbar(TOOLBARS.index('sensor')) #self._toolbar_changed_cb(self.toolbox, TOOLBARS.index('sensor')) #self.set_show_hide_windows('sensor') def set_show_hide_windows(self, mode='sound'): """Shows the appropriate window identified by the mode """ if mode == 'sound': self.wave.set_context_on() self.side_toolbar.set_show_hide(True, mode) elif mode == 'sensor': self.wave.set_context_on() self.side_toolbar.set_show_hide(True, mode) def on_quit(self, data=None): """Clean up, close journal on quit""" self.audiograb.on_activity_quit() def _active_cb(self, widget, pspec): """ Callback to handle starting/pausing capture when active/idle """ if self.first: self.audiograb.start_grabbing() self.first = False if not self.props.active and self.ACTIVE: self.audiograb.pause_grabbing() self.active_status = False elif self.props.active and not self.ACTIVE: self.audiograb.resume_grabbing() self.active_status = True self.ACTIVE = self.props.active self.wave.set_active(self.ACTIVE) def write_file(self, file_path): """ Write data to journal on quit """ if hasattr(self, 'ji') and len(self.ji.temp_buffer) > 0: # Append new data to Journal entry writer = csv.writer(open(file_path, 'ab')) # Also output to a separate file as a workaround to Ticket 2127 tmp_file_path = join(environ['SUGAR_ACTIVITY_ROOT'], 'instance', 'sensor_data' + '.csv') log.debug('saving sensor data to %s' % (tmp_file_path)) writer2 = csv.writer(open(tmp_file_path, 'ab')) for datum in self.ji.temp_buffer: writer.writerow([datum]) writer2.writerow([datum]) # Set the mimetype so that the file can be read by other Activities self.metadata['mime_type'] = 'text/csv' jobject = datastore.create() jobject.metadata['title'] = _('Measure Log') jobject.metadata['keep'] = '0' jobject.metadata['buddies'] = '' jobject.metadata['preview'] = '' jobject.metadata['icon-color'] = self.icon_colors jobject.metadata['mime_type'] = 'text/csv' jobject.file_path = tmp_file_path datastore.write(jobject) jobject.destroy() del jobject remove(tmp_file_path) def read_file(self, file_path): """ Read csv data from journal on start """ reader = csv.reader(open(file_path, "rb")) # Count the number of sessions for r in reader: if len(r) > 0: if r[0] == _('Session'): self.session_id += 1 elif r[0].find('abiword') != -1: # File has been opened by Write cannot be read by Measure # See Ticket 2127 log.error('File was opened by Write: Measure cannot read') return def _label_cb(self, data=None): """ Ignore the click on the label button """ return def _toolbar_changed_cb(self, toolbox, num): """ Callback for changing the primary toolbar (0.84-) """ if TOOLBARS[num] == 'sound': self.set_sound_context() elif TOOLBARS[num] == 'sensor': self.set_sensor_context() return True def set_sound_context(self): """ Called when sound toolbar is selected or button pushed """ self.set_show_hide_windows('sound') if _is_xo(self.hw): self.sensor_toolbar.context_off() gobject.timeout_add(500, self.sound_toolbar.context_on) self.CONTEXT = 'sound' def set_sensor_context(self): """ Called when sensor toolbar is selected or button pushed """ self.set_show_hide_windows('sensor') self.sound_toolbar.context_off() gobject.timeout_add(500, self.sensor_toolbar.context_on) self.CONTEXT = 'sensor' def get_icon_colors_from_sugar(self): """Returns the icon colors from the Sugar profile""" if self.using_gconf: client = gconf.client_get_default() return client.get_string('/desktop/sugar/user/color') else: return profile.get_color().to_string() def get_nick_from_sugar(self): """ Returns nick from Sugar """ if self.using_gconf: client = gconf.client_get_default() return client.get_string('/desktop/sugar/user/nick') else: return profile.get_nick_name()