class ToolbarInfo(Gtk.Toolbar): __gsignals__ = { "show-simulation": (GObject.SIGNAL_RUN_FIRST, None, []), "show-info": (GObject.SIGNAL_RUN_FIRST, None, []), "go-back": (GObject.SIGNAL_RUN_FIRST, None, []), "go-forward": (GObject.SIGNAL_RUN_FIRST, None, []), } def __init__(self): Gtk.Toolbar.__init__(self) self.button = ToolbarButton(page=self, icon_name="info") self.button_simulation = RadioToolButton(icon_name="solar-system", group=None) self.button_simulation.set_tooltip(_("Show solar system")) self.button_simulation.connect("toggled", self._show_simulation_cb) self.insert(self.button_simulation, -1) self.button_info = RadioToolButton(icon_name="info", group=self.button_simulation) self.button_info.set_tooltip(_("Show information")) self.button_info.connect("toggled", self._show_info_cb) self.insert(self.button_info, -1) self.insert(make_separator(False), -1) self.back_button = ToolButton("go-previous-paired") self.back_button.set_tooltip(_("Go back")) self.back_button.set_sensitive(False) self.back_button.connect("clicked", self._go_back_cb) self.insert(self.back_button, -1) self.forward_button = ToolButton("go-next-paired") self.forward_button.set_tooltip(_("Go forward")) self.forward_button.set_sensitive(False) self.forward_button.connect("clicked", self._go_forward_cb) self.insert(self.forward_button, -1) self.show_all() def _show_simulation_cb(self, widget): self.emit("show-simulation") def _show_info_cb(self, widget): self.emit("show-info") def _go_back_cb(self, widget): self.emit("go-back") def _go_forward_cb(self, widget): self.emit("go-forward") def select_screen(self, screen): if screen == Screen.SOLAR_SYSTEM: self.button_simulation.props = True elif screen == Screen.INFO: self.button_info.props.active = True
def __init__(self, owner): GObject.GObject.__init__(self) self.owner = owner self._insert_separator(True) self.desktop = [] btn = RadioToolButton(group=None) btn.set_icon_name('jam-preset1') btn.connect('toggled', self.setDesktop, 0) btn.set_tooltip(_('Desktop 1')) self.insert(btn, -1) self.desktop.append(btn) for i in range(2, 11): btn = RadioToolButton(group=self.desktop[0]) btn.set_icon_name('jam-preset%d' % i) btn.connect('toggled', self.setDesktop, i - 1) btn.set_tooltip(_('Desktop %d' % i)) self.insert(btn, -1) self.desktop.append(btn) self._insert_separator(True) self.show_all()
def instance(self): book.wiki = book.WikiBook() if not book.custom: book.custom = book.CustomBook() self.edit_page = 1 self.edit = edit.View() self.library = library.View(self) toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) self.set_toolbar_box(toolbar_box) self._toolbar = toolbar_box.toolbar tool_group = None search_button = RadioToolButton() search_button.props.group = tool_group tool_group = search_button search_button.props.icon_name = 'white-search' search_button.set_tooltip(_('Library')) search_button.mode = 'search' search_button.connect('clicked', self.__mode_button_clicked) self._toolbar.insert(search_button, -1) edit_button = RadioToolButton() edit_button.props.group = tool_group edit_button.props.icon_name = 'toolbar-edit' edit_button.set_tooltip(_('Edit')) edit_button.mode = 'edit' edit_button.connect('clicked', self.__mode_button_clicked) self._toolbar.insert(edit_button, -1) self._toolbar.insert(Gtk.SeparatorToolItem(), -1) self.edit_bar = edit.ToolbarBuilder(self.edit, self._toolbar) self.library_bar = library.ToolbarBuilder(self.library, activity_button) self.library_bar.publish.show() edit_fake = Gtk.EventBox() self.notebook.append_page(self.library, None) self.notebook.append_page(self.edit, None) self.notebook.append_page(edit_fake, None) self.show_all() self.__mode_button_clicked(search_button) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) separator.show() self._toolbar.insert(separator, -1) stop_button = StopButton(self) stop_button.show() self._toolbar.insert(stop_button, -1)
def __init__(self, parent): Gtk.Toolbar.__init__(self) self._parent = parent text_mode_btn = RadioToolButton(icon_name='text-mode') text_mode_btn.set_tooltip(_('Text mode')) text_mode_btn.set_accelerator(_('<ctrl>t')) text_mode_btn.connect('clicked', self._parent.mode_cb, MMapArea.MODE_TEXT) self.insert(text_mode_btn, -1) image_mode_btn = RadioToolButton(icon_name='image-mode', group=text_mode_btn) image_mode_btn.set_tooltip(_('Image add mode')) image_mode_btn.set_accelerator(_('<ctrl>i')) image_mode_btn.connect('clicked', self._parent.mode_cb, MMapArea.MODE_IMAGE) self.insert(image_mode_btn, -1) draw_mode_btn = RadioToolButton(icon_name='draw-mode', group=text_mode_btn) draw_mode_btn.set_tooltip(_('Drawing mode')) draw_mode_btn.set_accelerator(_('<ctrl>d')) draw_mode_btn.connect('clicked', self._parent.mode_cb, MMapArea.MODE_DRAW) self.insert(draw_mode_btn, -1) label_mode_btn = RadioToolButton(icon_name='label-mode', group=text_mode_btn) label_mode_btn.set_tooltip(_('Label mode')) label_mode_btn.set_accelerator(_('<ctrl>a')) label_mode_btn.connect('clicked', self._parent.mode_cb, MMapArea.MODE_LABEL) self.insert(label_mode_btn, -1) self.show_all()
def __init__(self, owner): GObject.GObject.__init__(self) self.owner = owner self.toolItem = {} self.blockBeat = False self.beatWheel = [] btn = RadioToolButton(group=None) btn.set_icon_name('beats') btn.connect('toggled', self.setBeat, 0) btn.set_tooltip(_('Jump To Beat')) self.insert(btn, -1) self.beatWheel.append(btn) for i in range(1, 12): btn = RadioToolButton(group=self.beatWheel[0]) btn.set_icon_name('beats') btn.connect('toggled', self.setBeat, i) btn.set_tooltip(_('Jump To Beat')) self.insert(btn, -1) self.beatWheel.append(btn) label = Gtk.Label(label=_("Synch to:")) self.syncLabel = Gtk.ToolItem() self.syncLabel.add(label) self.insert(self.syncLabel, 0) self.comboBox = ComboBox() self.comboBox.append_item(1, _("1 Beat")) self.comboBox.append_item(2, _("2 Beats")) self.comboBox.append_item(3, _("3 Beats")) self.comboBox.append_item(4, _("4 Beats")) self.comboBox.append_item(5, _("5 Beats")) self.comboBox.append_item(6, _("6 Beats")) self.comboBox.append_item(7, _("7 Beats")) self.comboBox.append_item(8, _("8 Beats")) self.comboBox.append_item(9, _("9 Beats")) self.comboBox.append_item(10, _("10 Beats")) self.comboBox.append_item(11, _("11 Beats")) self.comboBox.append_item(12, _("12 Beats")) self.comboBox.set_active(4 - 1) # default 4 beats self.comboBox.connect("changed", self.changeSync) self.syncBox = ToolComboBox(self.comboBox) self.insert(self.syncBox, 1) self.show_all()
def add_level_button(icon_name, tooltip, numeric_level): if self._levels_buttons: button = RadioToolButton(icon_name=icon_name, group=self._levels_buttons[0]) else: button = RadioToolButton(icon_name=icon_name) self._levels_buttons.append(button) def callback(source): if source.get_active(): self.game.set_level(numeric_level) self.game.run() button.connect('clicked', callback) button.set_tooltip(tooltip)
def add_level_button(icon_name, tooltip, numeric_level): if self._levels_buttons: button = RadioToolButton(icon_name=icon_name, group=self._levels_buttons[0]) else: button = RadioToolButton(icon_name=icon_name) self._levels_buttons.append(button) toolbar.add(button) def callback(source): if source.get_active(): self._game.set_level(numeric_level) self._game.new_game() button.connect('clicked', callback) button.set_tooltip(tooltip)
def radio_factory(icon_name, toolbar, callback, cb_arg=None, tooltip=None, group=None): ''' Add a radio button to a toolbar ''' button = RadioToolButton(group=group) button.set_icon_name(icon_name) if tooltip is not None: button.set_tooltip(tooltip) if cb_arg is None: button.connect('clicked', callback) else: button.connect('clicked', callback, cb_arg) if hasattr(toolbar, 'insert'): # the main toolbar toolbar.insert(button, -1) else: # or a secondary toolbar toolbar.props.page.insert(button, -1) button.show() return button
def add_level_button(icon_name, tooltip, numeric_level): if self._levels_buttons: button = RadioToolButton(icon_name=icon_name, group=self._levels_buttons[0]) else: button = RadioToolButton(icon_name=icon_name) self._levels_buttons.append(button) toolbar.add(button) def callback(source): if source.get_active(): self._collab.post({'action': icon_name}) self._game.set_level(numeric_level) self._game.new_game() button.connect('toggled', callback) button.set_tooltip(tooltip)
def radio_factory(button_name, toolbar, callback, cb_arg=None, tooltip=None, group=None): """ Add a radio button to a toolbar """ button = RadioToolButton(group=group) button.set_icon_name(button_name) if callback is not None: if cb_arg is None: button.connect("clicked", callback) else: button.connect("clicked", callback, cb_arg) if hasattr(toolbar, "insert"): # Add button to the main toolbar... toolbar.insert(button, -1) else: # ...or a secondary toolbar. toolbar.props.page.insert(button, -1) button.show() if tooltip is not None: button.set_tooltip(tooltip) return button
def _insert_create_tools(self, create_toolbar): # Make + add the component buttons self.radioList = {} for i, c in enumerate(tools.allTools): if i == 0: button = RadioToolButton(group=None) firstbutton = button else: button = RadioToolButton(group=firstbutton) button.set_icon_name(c.icon) button.set_tooltip(c.toolTip) button.set_accelerator(c.toolAccelerator) button.connect("clicked", self.radioClicked) palette = self._build_palette(c) if palette is not None: palette.show() button.get_palette().set_content(palette) self._insert_item(create_toolbar, button, -1) button.show() self.radioList[button] = c.name if hasattr(c, "constructor"): self._constructors[c.name] = self.game.toolList[c.name].constructor
def _add_clock_controls(self, display_toolbar): # First group of radio button to select the type of clock to display button1 = RadioToolButton(icon_name="simple-clock") button1.set_tooltip(_('Simple Clock')) button1.connect("toggled", self._display_mode_changed_cb, _MODE_SIMPLE_CLOCK) display_toolbar.insert(button1, -1) self._display_mode_buttons.append(button1) button2 = RadioToolButton(icon_name="nice-clock", group=button1) button2.set_tooltip(_('Nice Clock')) button2.connect("toggled", self._display_mode_changed_cb, _MODE_NICE_CLOCK) display_toolbar.insert(button2, -1) self._display_mode_buttons.append(button2) button3 = RadioToolButton(icon_name="digital-clock", group=button1) button3.set_tooltip(_('Digital Clock')) button3.connect("toggled", self._display_mode_changed_cb, _MODE_DIGITAL_CLOCK) display_toolbar.insert(button3, -1) self._display_mode_buttons.append(button3) # A separator between the two groups of buttons separator = Gtk.SeparatorToolItem() separator.set_draw(True) display_toolbar.insert(separator, -1) # Now the options buttons to display other elements: date, day # of week... A button in the toolbar to write the time in # full letters self._write_time_btn = ToggleToolButton("write-time") self._write_time_btn.set_tooltip(_('Display time in full letters')) self._write_time_btn.connect("toggled", self._write_time_clicked_cb) display_toolbar.insert(self._write_time_btn, -1) # The button to display the weekday and date self._write_date_btn = ToggleToolButton("write-date") self._write_date_btn.set_tooltip(_('Display weekday and date')) self._write_date_btn.connect("toggled", self._write_date_clicked_cb) display_toolbar.insert(self._write_date_btn, -1) # Another button to speak aloud the time self._speak_time_btn = ToggleToolButton("microphone") self._speak_time_btn.set_tooltip(_('Talking clock')) self._speak_time_btn.connect("toggled", self._speak_time_clicked_cb) display_toolbar.insert(self._speak_time_btn, -1) # A separator between the two groups of buttons separator = Gtk.SeparatorToolItem() separator.set_draw(True) display_toolbar.insert(separator, -1) # And another button to toggle grabbing the hands self._grab_button = ToggleToolButton("grab") self._grab_button.set_tooltip(_('Grab the hands')) self._grab_button.connect("toggled", self._grab_clicked_cb) display_toolbar.insert(self._grab_button, -1)
def build_toolbox(self): view_tool_group = None registerbtn = RadioToolButton() registerbtn.props.icon_name = 'view-list' registerbtn.props.label = _('Register') registerbtn.set_tooltip(_("Register")) registerbtn.props.group = view_tool_group view_tool_group = registerbtn registerbtn.props.accelerator = '<Ctrl>1' registerbtn.connect('clicked', self.register_cb) budgetbtn = RadioToolButton() budgetbtn.props.icon_name = 'budget' budgetbtn.props.label = _('Budget') budgetbtn.set_tooltip(_("Budget")) budgetbtn.props.group = view_tool_group budgetbtn.props.accelerator = '<Ctrl>2' budgetbtn.connect('clicked', self.budget_cb) chartbtn = RadioToolButton() chartbtn.props.icon_name = 'chart' chartbtn.props.label = _('Chart') chartbtn.set_tooltip(_("Chart")) chartbtn.props.group = view_tool_group chartbtn.props.accelerator = '<Ctrl>3' chartbtn.connect('clicked', self.chart_cb) helpbutton = self._create_help_button() helpbutton.show_all() self.toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) self.toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() self.toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1) self.toolbar_box.toolbar.insert(registerbtn, -1) self.toolbar_box.toolbar.insert(budgetbtn, -1) self.toolbar_box.toolbar.insert(chartbtn, -1) self.toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1) self.toolbar_box.toolbar.insert(helpbutton, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.toolbar_box.toolbar.insert(separator, -1) self.toolbar_box.toolbar.insert(StopButton(self), -1) self.set_toolbar_box(self.toolbar_box) activity_button.page.insert(self._create_export_button(), -1) self.toolbar_box.show_all()
def _insert_create_tools(self, create_toolbar): # Make + add the component buttons self.radioList = {} for i, c in enumerate(tools.allTools): if i == 0: button = RadioToolButton(group=None) firstbutton = button else: button = RadioToolButton(group=firstbutton) button.set_icon_name(c.icon) button.set_tooltip(c.toolTip) button.set_accelerator(c.toolAccelerator) button.connect('clicked', self.radioClicked) palette = self._build_palette(c) if palette is not None: palette.show() button.get_palette().set_content(palette) self._insert_item(create_toolbar, button, -1) button.show() self.radioList[button] = c.name if hasattr(c, 'constructor'): self._constructors[c.name] = \ self.game.toolList[c.name].constructor
def _create_chart_buttons(self, toolbar): add_vbar_chart = RadioToolButton() add_vbar_chart.set_tooltip(_('Vertical Bar Chart')) add_vbar_chart.props.icon_name = 'vbar' charts_group = add_vbar_chart toolbar.insert(add_vbar_chart, -1) add_hbar_chart = RadioToolButton() add_hbar_chart.set_tooltip(_('Horizontal Bar Chart')) add_hbar_chart.props.icon_name = 'hbar' add_hbar_chart.props.group = charts_group toolbar.insert(add_hbar_chart, -1) add_line_chart = RadioToolButton() add_line_chart.set_tooltip(_('Line Chart')) add_line_chart.props.icon_name = 'line' add_line_chart.props.group = charts_group toolbar.insert(add_line_chart, -1) add_pie_chart = RadioToolButton() add_pie_chart.set_active(True) add_pie_chart.set_tooltip(_('Pie Chart')) add_pie_chart.props.icon_name = 'pie' add_pie_chart.props.group = charts_group toolbar.insert(add_pie_chart, -1) add_vbar_chart.connect('toggled', self._add_chart_cb, charts.VERTICAL_BAR) add_hbar_chart.connect('toggled', self._add_chart_cb, charts.HORIZONTAL_BAR) add_line_chart.connect('toggled', self._add_chart_cb, charts.LINE) add_pie_chart.connect('toggled', self._add_chart_cb, charts.PIE) self.chart_type_buttons.append(add_vbar_chart) self.chart_type_buttons.append(add_hbar_chart) self.chart_type_buttons.append(add_line_chart) self.chart_type_buttons.append(add_pie_chart) self._add_chart_cb(add_vbar_chart, charts.VERTICAL_BAR)
def _load_standard_buttons(self, toolbar): fraction_button = RadioToolButton(group=None) fraction_button.set_icon_name('fraction') fraction_button.set_tooltip(_('fractions')) fraction_button.connect('clicked', self._fraction_cb) toolbar.insert(fraction_button, -1) fraction_button.show() sector_button = RadioToolButton(group=fraction_button) sector_button.set_icon_name('sector') sector_button.set_tooltip(_('sectors')) sector_button.connect('clicked', self._sector_cb) toolbar.insert(sector_button, -1) sector_button.show() percent_button = RadioToolButton(group=fraction_button) percent_button.set_icon_name('percent') percent_button.set_tooltip(_('percents')) percent_button.connect('clicked', self._percent_cb) toolbar.insert(percent_button, -1) percent_button.show() self._player = Gtk.Image() self._player.set_from_pixbuf( svg_str_to_pixbuf( generate_xo_svg(scale=0.8, colors=['#282828', '#282828']))) self._player.set_tooltip_text(self.nick) toolitem = Gtk.ToolItem() toolitem.add(self._player) self._player.show() toolbar.insert(toolitem, -1) toolitem.show() self._label = Gtk.Label(_("Click the ball to start.")) self._label.set_line_wrap(True) if Gdk.Screen.width() < 1024: self._label.set_size_request(275, -1) else: self._label.set_size_request(500, -1) self.toolitem = Gtk.ToolItem() self.toolitem.add(self._label) self._label.show() toolbar.insert(self.toolitem, -1) self.toolitem.show()
def _load_standard_buttons(self, toolbar): fraction_button = RadioToolButton(group=None) fraction_button.set_icon_name('fraction') fraction_button.set_tooltip(_('fractions')) fraction_button.connect('clicked', self._fraction_cb) toolbar.insert(fraction_button, -1) fraction_button.show() sector_button = RadioToolButton(group=fraction_button) sector_button.set_icon_name('sector') sector_button.set_tooltip(_('sectors')) sector_button.connect('clicked', self._sector_cb) toolbar.insert(sector_button, -1) sector_button.show() percent_button = RadioToolButton(group=fraction_button) percent_button.set_icon_name('percent') percent_button.set_tooltip(_('percents')) percent_button.connect('clicked', self._percent_cb) toolbar.insert(percent_button, -1) percent_button.show() self._player = Gtk.Image() self._player.set_from_pixbuf(svg_str_to_pixbuf( generate_xo_svg(scale=0.8, colors=['#282828', '#282828']))) self._player.set_tooltip_text(self.nick) toolitem = Gtk.ToolItem() toolitem.add(self._player) self._player.show() toolbar.insert(toolitem, -1) toolitem.show() self._label = Gtk.Label(_("Click the ball to start.")) self._label.set_line_wrap(True) if Gdk.Screen.width() < 1024: self._label.set_size_request(275, -1) else: self._label.set_size_request(500, -1) self.toolitem = Gtk.ToolItem() self.toolitem.add(self._label) self._label.show() toolbar.insert(self.toolitem, -1) self.toolitem.show()
def _insert_stop_play_button(self, toolbar): self.stop_play_toolbar = ToolbarButton() st_toolbar = self.stop_play_toolbar st_toolbar.props.page = Gtk.Toolbar() st_toolbar.props.icon_name = 'media-playback-stop' self.stop_play_state = True self.stop_play = ToolButton('media-playback-stop') self.stop_play.set_tooltip(_('Stop')) self.stop_play.set_accelerator(_('<ctrl>space')) self.stop_play.connect('clicked', self.stop_play_cb) self._insert_item(st_toolbar, self.stop_play) self.stop_play.show() slowest_button = RadioToolButton(group=None) slowest_button.set_icon_name('slow-walk-milton-raposo') slowest_button.set_tooltip(_('Run slower')) slowest_button.connect('clicked', self._set_fps_cb, SLOWEST_FPS) self._insert_item(st_toolbar, slowest_button) slowest_button.show() slow_button = RadioToolButton(group=slowest_button) slow_button.set_icon_name('walking') slow_button.set_tooltip(_('Run slow')) slow_button.connect('clicked', self._set_fps_cb, SLOW_FPS) self._insert_item(st_toolbar, slow_button) slow_button.show() fast_button = RadioToolButton(group=slowest_button) fast_button.set_icon_name('running') fast_button.set_tooltip('Run fast') fast_button.connect('clicked', self._set_fps_cb, FAST_FPS) self._insert_item(st_toolbar, fast_button) fast_button.show() fast_button.set_active(True) toolbar.insert(self.stop_play_toolbar, -1) self.stop_play_toolbar.show_all()
def _insert_stop_play_button(self, toolbar): self.stop_play_toolbar = ToolbarButton() st_toolbar = self.stop_play_toolbar st_toolbar.props.page = Gtk.Toolbar() st_toolbar.props.icon_name = "media-playback-stop" self.stop_play_state = True self.stop_play = ToolButton("media-playback-stop") self.stop_play.set_tooltip(_("Stop")) self.stop_play.set_accelerator(_("<ctrl>space")) self.stop_play.connect("clicked", self.stop_play_cb) self._insert_item(st_toolbar, self.stop_play) self.stop_play.show() slowest_button = RadioToolButton(group=None) slowest_button.set_icon_name("slow-walk-milton-raposo") slowest_button.set_tooltip(_("Run slower")) slowest_button.connect("clicked", self._set_fps_cb, SLOWEST_FPS) self._insert_item(st_toolbar, slowest_button) slowest_button.show() slow_button = RadioToolButton(group=slowest_button) slow_button.set_icon_name("walking") slow_button.set_tooltip(_("Run slow")) slow_button.connect("clicked", self._set_fps_cb, SLOW_FPS) self._insert_item(st_toolbar, slow_button) slow_button.show() fast_button = RadioToolButton(group=slowest_button) fast_button.set_icon_name("running") fast_button.set_tooltip("Run fast") fast_button.connect("clicked", self._set_fps_cb, FAST_FPS) self._insert_item(st_toolbar, fast_button) fast_button.show() fast_button.set_active(True) toolbar.insert(self.stop_play_toolbar, -1) self.stop_play_toolbar.show_all()
class ChartActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 # CHART_OPTIONS self._font_option = TITLE_FONT self.x_label = '' self.y_label = '' self.chart_color = utils.get_user_fill_color('str') self.chart_line_color = utils.get_user_stroke_color('str') self.current_chart = None self.charts_area = None self.chart_data = [] self.chart_type_buttons = [] self._font_options = { 'titleColor': '#000000', 'titleFont': 'Sans', 'titleFontSize': 12, 'axis': { 'tickFont': 'Sans', 'tickFontSize': 12, 'tickColor': '#000000', 'labelFontSize': 14, 'labelColor': '#666666', 'labelFont': 'Sans', 'lineColor': '#b3b3b3'}} # TOOLBARS self._labels_font = RadioToolButton() self._title_font = RadioToolButton() toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_btn_toolbar = activity_button.page activity_btn_toolbar.title.connect('changed', self._set_chart_title) save_as_image = ToolButton('save-as-image') save_as_image.connect('clicked', self._save_as_image) save_as_image.set_tooltip(_('Save as image')) activity_btn_toolbar.insert(save_as_image, -1) save_as_image.show() import_stopwatch = ToolButton('import-stopwatch') import_stopwatch.connect('clicked', self.__import_stopwatch_cb) import_stopwatch.set_tooltip(_('Read StopWatch data')) activity_btn_toolbar.insert(import_stopwatch, -1) import_stopwatch.show() import_measure = ToolButton('import-measure') import_measure.set_tooltip(_('Read Measure data')) if utils.get_channels() == 1: import_measure.connect('clicked', self.__import_measure_cb, 1) else: import_measure.connect('clicked', self._measure_btn_clicked) self._create_measure_palette(import_measure) activity_btn_toolbar.insert(import_measure, -1) import_measure.show() toolbarbox.toolbar.insert(activity_button, 0) add_v = ToolButton('gtk-add') add_v.connect('clicked', self._add_value) add_v.set_tooltip(_('Add a value')) toolbarbox.toolbar.insert(add_v, -1) remove_v = ToolButton('gtk-remove') remove_v.connect('clicked', self._remove_value) remove_v.set_tooltip(_('Remove the selected value')) toolbarbox.toolbar.insert(remove_v, -1) self._remove_v = remove_v separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) # We create two sets: one for the main toolbar and one for the # chart toolbar. We choose which set to use based on the # screen width. self._create_chart_buttons(toolbarbox.toolbar) self._chart_button = ToolbarButton(icon_name='vbar') chart_toolbar = Gtk.Toolbar() self._create_chart_buttons(chart_toolbar) self._chart_button.props.page = chart_toolbar chart_toolbar.show_all() toolbarbox.toolbar.insert(self._chart_button, -1) separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) self._options_button = ToolbarButton(icon_name='preferences-system') options_toolbar = Gtk.Toolbar() self.chart_color_btn = ColorToolButton() self.chart_color_btn.set_color(_COLOR1) self.chart_color_btn.set_title(_('Chart Color')) options_toolbar.insert(self.chart_color_btn, -1) GObject.timeout_add(1000, self._connect_color_btn, self.chart_color_btn, self._set_chart_color) self.line_color_btn = ColorToolButton() self.line_color_btn.set_color(_COLOR2) self.line_color_btn.set_title(_('Line Color')) options_toolbar.insert(self.line_color_btn, -1) GObject.timeout_add(1000, self._connect_color_btn, self.line_color_btn, self._set_chart_line_color) separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) options_toolbar.insert(separator, -1) h_label_icon = Icon(icon_name='hlabel') h_label_tool_item = Gtk.ToolItem() h_label_tool_item.add(h_label_icon) options_toolbar.insert(h_label_tool_item, -1) self.h_label = Entry(_('Horizontal label...')) self.h_label.entry.connect('changed', self._set_h_label) options_toolbar.insert(self.h_label, -1) separator = Gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(False) options_toolbar.insert(separator, -1) v_label_icon = Icon(icon_name='vlabel') v_label_tool_item = Gtk.ToolItem() v_label_tool_item.add(v_label_icon) options_toolbar.insert(v_label_tool_item, -1) self.v_label = Entry(_('Vertical label...')) self.v_label.entry.connect('changed', self._set_v_label) options_toolbar.insert(self.v_label, -1) self._options_button.props.page = options_toolbar options_toolbar.show_all() toolbarbox.toolbar.insert(self._options_button, -1) text_toolbar_btn = ToolbarButton() text_toolbar_btn.props.icon_name = 'format-text' text_toolbar_btn.props.label = _('Text') toolbarbox.toolbar.insert(text_toolbar_btn, -1) self._text_options_btn = text_toolbar_btn texttoolbar = Gtk.Toolbar() self.font_name_combo = FontComboBox() self.font_name_combo.set_font_name('Sans') def set_font_name(w): self._set_chart_font_options(font=w.get_font_name()) self.font_name_combo.connect("changed", set_font_name) texttoolbar.insert(ToolComboBox(self.font_name_combo), -1) self.font_size = FontSize() def set_font_size(w): self._set_chart_font_options(size=w.get_font_size()) self.font_size.connect("changed", set_font_size) texttoolbar.insert(self.font_size, -1) self.text_color_btn = ColorToolButton() self.text_color_btn.set_color(style.COLOR_BLACK.get_gdk_color()) self.text_color_btn.set_title(_('Font Color')) texttoolbar.insert(self.text_color_btn, -1) GObject.timeout_add(1000, self._connect_color_btn, self.text_color_btn, self._set_text_color) # self._title_font created in the top of the file self._title_font.connect('clicked', self._set_font_option, TITLE_FONT) self._title_font.set_tooltip(_('Title font')) self._title_font.props.icon_name = 'title-font' op_group = self._title_font texttoolbar.insert(self._title_font, 0) # self._labels_font created in the top of the file self._labels_font.connect('clicked', self._set_font_option, LABELS_FONT) self._labels_font.set_tooltip(_('Labels font')) self._labels_font.props.icon_name = 'labels-font' self._labels_font.props.group = op_group texttoolbar.insert(self._labels_font, 1) tick_font = RadioToolButton() tick_font.connect('clicked', self._set_font_option, TICK_FONT) tick_font.set_tooltip(_('Tick font')) tick_font.props.icon_name = 'tick-font' tick_font.props.group = op_group texttoolbar.insert(tick_font, 2) separator = Gtk.SeparatorToolItem() texttoolbar.insert(separator, 3) text_toolbar_btn.props.page = texttoolbar texttoolbar.show_all() separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) self._fullscreen_button = ToolButton('view-fullscreen') self._fullscreen_button.set_tooltip(_("Fullscreen")) self._fullscreen_button.props.accelerator = '<Alt>Return' self._fullscreen_button.connect('clicked', self.__fullscreen_cb) toolbarbox.toolbar.insert(self._fullscreen_button, -1) charthelp.create_help(toolbarbox.toolbar) separator = Gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) # CANVAS paned = Gtk.HPaned() box = Gtk.VBox() self.box = box # Set the info box width to 1/3 of the screen: def size_allocate_cb(widget, allocation): paned.disconnect(self._setup_handle) box_width = allocation.width / 3 box.set_size_request(box_width, -1) self._setup_handle = paned.connect('size_allocate', size_allocate_cb) scroll = Gtk.ScrolledWindow() scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.labels_and_values = ChartData(self) scroll.add(self.labels_and_values) self.labels_and_values.connect('label-changed', self._label_changed) self.labels_and_values.connect('value-changed', self._value_changed) box.pack_start(scroll, True, True, 0) liststore_toolbar = Gtk.Toolbar() move_up = ToolButton('go-up') move_up.set_tooltip(_('Move up')) move_up.connect('clicked', self._move_up) move_down = ToolButton('go-down') move_down.set_tooltip(_('Move down')) move_down.connect('clicked', self._move_down) liststore_toolbar.insert(move_up, 0) liststore_toolbar.insert(move_down, 1) box.pack_end(liststore_toolbar, False, False, 0) paned.add1(box) # CHARTS AREA eventbox = Gtk.EventBox() self.charts_area = ChartArea(self) eventbox.modify_bg(Gtk.StateType.NORMAL, _WHITE) eventbox.add(self.charts_area) self._notebook = Gtk.Notebook() self._notebook.set_property('show-tabs', False) self._notebook.append_page(eventbox, Gtk.Label()) # EMPTY WIDGETS empty_widgets = Gtk.EventBox() empty_widgets.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color()) vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) mvbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.pack_start(mvbox, True, False, 0) image_icon = Icon(pixel_size=style.LARGE_ICON_SIZE, icon_name='chart', stroke_color=style.COLOR_BUTTON_GREY.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg()) mvbox.pack_start(image_icon, False, False, style.DEFAULT_PADDING) label = Gtk.Label('<span foreground="%s"><b>%s</b></span>' % (style.COLOR_BUTTON_GREY.get_html(), _('No data'))) label.set_use_markup(True) mvbox.pack_start(label, False, False, style.DEFAULT_PADDING) hbox = Gtk.Box() open_image_btn = Gtk.Button() open_image_btn.connect('clicked', self._add_value) add_image = Gtk.Image.new_from_stock(Gtk.STOCK_ADD, Gtk.IconSize.BUTTON) buttonbox = Gtk.Box() buttonbox.pack_start(add_image, False, True, 0) buttonbox.pack_end(Gtk.Label(_('Add a value')), True, True, 5) open_image_btn.add(buttonbox) hbox.pack_start(open_image_btn, True, False, 0) mvbox.pack_start(hbox, False, False, style.DEFAULT_PADDING) empty_widgets.add(vbox) empty_widgets.show_all() self._notebook.append_page(empty_widgets, Gtk.Label()) paned.add2(self._notebook) self.set_canvas(paned) self.charts_area.connect('size_allocate', self._chart_size_allocate) self.show_all() Gdk.Screen.get_default().connect('size-changed', self._configure_cb) self._configure_cb() def _set_text_color(self, *args): color = utils.rgb2html(args[-1].get_color()) self._set_chart_font_options(color=color) def _set_chart_font_options(self, font=None, size=None, color=None): op = self._font_options if self._font_option == TITLE_FONT: op['titleFont'] = font or op['titleFont'] op['titleFontSize'] = size or op['titleFontSize'] op['titleColor'] = color or op['titleColor'] elif self._font_option == LABELS_FONT: op['axis']['labelFont'] = font or op['axis']['labelFont'] op['axis']['labelFontSize'] = size or op['axis']['labelFontSize'] op['axis']['labelColor'] = color or op['axis']['labelColor'] elif self._font_option == TICK_FONT: op['axis']['tickFont'] = font or op['axis']['tickFont'] op['axis']['tickFontSize'] = size or op['axis']['tickFontSize'] op['axis']['tickColor'] = color or op['axis']['tickColor'] self._font_options = op self._render_chart() def _get_chart_font_options(self, option): chart_options = self._font_options if option == TITLE_FONT: font = chart_options['titleFont'] size = chart_options['titleFontSize'] color = chart_options['titleColor'] elif option == LABELS_FONT: font = chart_options['axis']['labelFont'] size = chart_options['axis']['labelFontSize'] color = chart_options['axis']['labelColor'] elif option == TICK_FONT: font = chart_options['axis']['tickFont'] size = chart_options['axis']['tickFontSize'] color = chart_options['axis']['tickColor'] else: return None, None, None return font, size, color def _set_font_option(self, *args): if not hasattr(self, 'font_name_combo'): return self._font_option = args[-1] font, size, color = self._get_chart_font_options(self._font_option) self.font_name_combo.set_font_name(font) self.font_size.set_font_size(size) self.text_color_btn.set_color(Color(color).get_gdk_color()) def _create_chart_buttons(self, toolbar): add_vbar_chart = RadioToolButton() add_vbar_chart.connect('clicked', self._add_chart_cb, charts.VERTICAL_BAR) add_vbar_chart.set_tooltip(_('Vertical Bar Chart')) add_vbar_chart.props.icon_name = 'vbar' charts_group = add_vbar_chart toolbar.insert(add_vbar_chart, -1) add_hbar_chart = RadioToolButton() add_hbar_chart.connect('clicked', self._add_chart_cb, charts.HORIZONTAL_BAR) add_hbar_chart.set_tooltip(_('Horizontal Bar Chart')) add_hbar_chart.props.icon_name = 'hbar' add_hbar_chart.props.group = charts_group toolbar.insert(add_hbar_chart, -1) add_line_chart = RadioToolButton() add_line_chart.connect('clicked', self._add_chart_cb, charts.LINE) add_line_chart.set_tooltip(_('Line Chart')) add_line_chart.props.icon_name = 'line' add_line_chart.props.group = charts_group toolbar.insert(add_line_chart, -1) add_pie_chart = RadioToolButton() add_pie_chart.set_active(True) add_pie_chart.connect('clicked', self._add_chart_cb, charts.PIE) add_pie_chart.set_tooltip(_('Pie Chart')) add_pie_chart.props.icon_name = 'pie' add_pie_chart.props.group = charts_group toolbar.insert(add_pie_chart, -1) self.chart_type_buttons.append(add_vbar_chart) self.chart_type_buttons.append(add_hbar_chart) self.chart_type_buttons.append(add_line_chart) self.chart_type_buttons.append(add_pie_chart) def _show_empty_widgets(self): if hasattr(self, '_notebook'): self._notebook.set_current_page(1) self._remove_v.set_sensitive(False) for btn in self.chart_type_buttons: btn.set_sensitive(False) self._options_button.set_sensitive(False) self._text_options_btn.set_sensitive(False) self._fullscreen_button.set_sensitive(False) def _show_chart_area(self): if self._notebook.get_current_page() == 1: self._notebook.set_current_page(0) self._remove_v.set_sensitive(True) for btn in self.chart_type_buttons: btn.set_sensitive(True) self._options_button.set_sensitive(True) self._text_options_btn.set_sensitive(True) self._fullscreen_button.set_sensitive(True) def _create_measure_palette(self, button): palette = button.get_palette() hbox = Gtk.HBox() channel1 = ToolButton('measure-channel-1') channel1.connect('clicked', self.__import_measure_cb, 1) channel2 = ToolButton('measure-channel-2') channel2.connect('clicked', self.__import_measure_cb, 2) hbox.pack_start(channel1, False, True, 0) hbox.pack_end(channel2, False, True, 0) hbox.show_all() palette.set_content(hbox) def _measure_btn_clicked(self, button): palette = button.get_palette() palette.popup(immediate=True, state=1) def _add_value(self, widget, label='', value='0.0'): if label == '': label = str(len(self.chart_data) + 1) is_number = True try: float(value) except ValueError: _logger.debug('data (%s) not a number' % (str(value))) is_number = False if is_number: data = (label, float(value)) if data not in self.chart_data: pos = self.labels_and_values.add_value(label, value) self.chart_data.insert(pos, data) self._update_chart_data() elif not is_number: _invalid_number_alert(activity) def _remove_value(self, widget): value = self.labels_and_values.remove_selected_value() self.chart_data.remove(value) self._update_chart_data() def _add_chart_cb(self, widget, type=charts.VERTICAL_BAR): self.current_chart = charts.Chart(type) def update_btn(): if (type == charts.PIE and not self.chart_type_buttons[3].get_active() and not self.chart_type_buttons[7].get_active()): self.chart_type_buttons[3].set_active(True) self.chart_type_buttons[7].set_active(True) GObject.idle_add(update_btn) self.update_chart() def _configure_cb(self, event=None): # If we have room, put buttons on the main toolbar if Gdk.Screen.width() / 14 > style.GRID_CELL_SIZE: self._chart_button.set_expanded(False) self._chart_button.hide() for i in range(4): self.chart_type_buttons[i].show() self.chart_type_buttons[i + 4].hide() else: self._chart_button.show() self._chart_button.set_expanded(True) for i in range(4): self.chart_type_buttons[i].hide() self.chart_type_buttons[i + 4].show() def _chart_size_allocate(self, widget, allocation): self._render_chart() def unfullscreen(self): self.box.show() activity.Activity.unfullscreen(self) GObject.idle_add(self._render_chart) def __fullscreen_cb(self, button): self.box.hide() self._render_chart(fullscreen=True) activity.Activity.fullscreen(self) def _render_chart(self, fullscreen=False): if not self.chart_data: self._show_empty_widgets() return if self.current_chart is None or self.charts_area is None: return try: # Resize the chart for all the screen sizes alloc = self.get_allocation() if fullscreen: new_width = alloc.width new_height = alloc.height self.current_chart.width = alloc.width self.current_chart.height = alloc.height if not fullscreen: alloc = self.charts_area.get_allocation() new_width = alloc.width - 40 new_height = alloc.height - 40 self.current_chart.width = new_width self.current_chart.height = new_height # Set options self.current_chart.set_color_scheme(color=self.chart_color) self.current_chart.set_line_color(self.chart_line_color) self.current_chart.set_font_options(self._font_options) if self.current_chart.type == charts.PIE: self.current_chart.render(self) else: self.current_chart.render() self.charts_area.queue_draw() except (ZeroDivisionError, ValueError): pass self._show_chart_area() return False def _update_chart_active_button(self, type=None): if self.current_chart is None and type is None: return _type = type or self.current_chart.type if _type == charts.VERTICAL_BAR: self.chart_type_buttons[0].set_active(True) self.chart_type_buttons[4].set_active(True) elif _type == charts.HORIZONTAL_BAR: self.chart_type_buttons[1].set_active(True) self.chart_type_buttons[5].set_active(True) elif _type == charts.LINE: self.chart_type_buttons[2].set_active(True) self.chart_type_buttons[6].set_active(True) elif _type == charts.PIE: self.chart_type_buttons[3].set_active(True) self.chart_type_buttons[7].set_active(True) self._labels_font.set_sensitive(False) def _update_chart_data(self): if self.current_chart is None: return self.current_chart.data_set(self.chart_data) self._update_chart_labels() def _set_chart_title(self, widget): self._update_chart_labels(title=widget.get_text()) def _update_chart_labels(self, title=''): if self.current_chart is None: return if not title and self.metadata['title']: title = self.metadata['title'] self.current_chart.set_title(title) self.current_chart.set_x_label(self.x_label) self.current_chart.set_y_label(self.y_label) self._render_chart() def update_chart(self): if self.current_chart: self.current_chart.data_set(self.chart_data) self.current_chart.set_title(self.metadata['title']) self.current_chart.set_x_label(self.x_label) self.current_chart.set_y_label(self.y_label) self._set_font_option(self._font_option) self._render_chart() def _label_changed(self, treeview, path, new_label): path = int(path) self.chart_data[path] = (new_label, self.chart_data[path][1]) self._update_chart_data() def _value_changed(self, treeview, path, new_value): path = int(path) self.chart_data[path] = (self.chart_data[path][0], float(new_value)) self._update_chart_data() def _move_up(self, widget): old, new = self.labels_and_values.move_up() _object = self.chart_data[old] self.chart_data.remove(_object) self.chart_data.insert(new, _object) self._update_chart_data() def _move_down(self, widget): old, new = self.labels_and_values.move_down() if old is not None: _object = self.chart_data[old] self.chart_data.remove(_object) self.chart_data.insert(new, _object) self._update_chart_data() def _set_h_label(self, widget): self.x_label = widget.get_text() self._update_chart_labels() def _set_v_label(self, widget): self.y_label = widget.get_text() self._update_chart_labels() def _set_chart_color(self, *args): self.chart_color = utils.rgb2html(args[-1].get_color()) self._render_chart() def _set_chart_line_color(self, *args): self.chart_line_color = utils.rgb2html(args[-1].get_color()) self._render_chart() def _connect_color_btn(self, colorbtn, function): if colorbtn._palette is None: return True for scale in colorbtn._palette._scales: scale.connect('button-release-event', function, colorbtn) for button in colorbtn._palette._swatch_tray.get_children(): button.connect('clicked', function, colorbtn) return False def _object_chooser(self, mime_type, type_name): chooser = ObjectChooser() matches_mime_type = False response = chooser.run() if response == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() metadata = jobject.metadata file_path = jobject.file_path if metadata['mime_type'] == mime_type: matches_mime_type = True else: alert = Alert() alert.props.title = _('Invalid object') alert.props.msg = \ _('The selected object must be a %s file' % (type_name)) ok_icon = Icon(icon_name='dialog-ok') alert.add_button(Gtk.ResponseType.OK, _('Ok'), ok_icon) ok_icon.show() alert.connect('response', lambda a, r: self.remove_alert(a)) self.add_alert(alert) alert.show() return matches_mime_type, file_path, metadata['title'] def _graph_from_reader(self, reader): self.labels_and_values.model.clear() self.chart_data = [] chart_data = reader.get_chart_data() horizontal, vertical = reader.get_labels_name() self.v_label.entry.set_text(horizontal) self.h_label.entry.set_text(vertical) # Load the data for row in chart_data: self._add_value(None, label=row[0], value=float(row[1])) self.update_chart() def __import_stopwatch_cb(self, widget): matches_mime_type, file_path, title = \ self._object_chooser(_STOPWATCH_MIME_TYPE, _('StopWatch')) if matches_mime_type: f = open(file_path) reader = StopWatchReader(f) self._graph_from_reader(reader) f.close() def __import_measure_cb(self, widget, channel=1): matches_mime_type, file_path, title = \ self._object_chooser(_CSV_MIME_TYPE, _('Measure')) if matches_mime_type: f = open(file_path) reader = MeasureReader(f, channel) self._graph_from_reader(reader) f.close() def _save_as_image(self, widget): if self.current_chart: jobject = datastore.create() jobject.metadata['title'] = self.metadata['title'] jobject.metadata['mime_type'] = 'image/png' self.current_chart.as_png(_CHART_FILE) jobject.set_file_path(_CHART_FILE) datastore.write(jobject) def load_from_file(self, f): try: data = json.load(f) finally: f.close() self.metadata['title'] = data['title'] self.x_label = data['x_label'] self.y_label = data['y_label'] self.chart_color = data['chart_color'] self.chart_line_color = data['chart_line_color'] self.current_chart.type = data['current_chart.type'] # Make it compatible with old Chart instances if 'font_options' in data: self._font_options = data['font_options'] chart_data = data['chart_data'] # Update charts buttons self._update_chart_active_button() # Update the controls in the config subtoolbar self.chart_color_btn.set_color(Color(self.chart_color).get_gdk_color()) self.line_color_btn.set_color(Color(self.chart_line_color). get_gdk_color()) # If the saved label is not '', set the text entry with the saved label if self.x_label != '': self.h_label.entry.set_text(self.x_label) if self.y_label != '': self.v_label.entry.set_text(self.y_label) # load the data for row in chart_data: self._add_value(None, label=row[0], value=float(row[1])) self.update_chart() def write_file(self, file_path): self.metadata['mime_type'] = 'application/x-chart-activity' if self.current_chart: data = {} data['title'] = self.metadata['title'] data['x_label'] = self.x_label data['y_label'] = self.y_label data['chart_color'] = self.chart_color data['chart_line_color'] = self.chart_line_color data['current_chart.type'] = self.current_chart.type data['chart_data'] = self.chart_data data['font_options'] = self._font_options f = open(file_path, 'w') try: json.dump(data, f) finally: f.close() def read_file(self, file_path): f = open(file_path, 'r') GObject.idle_add(self.load_from_file, f)
class ActionButtons(): ''' This class manages the action buttons that move among toolsbars ''' def __init__(self, parent): self._main_toolbar = parent.get_toolbar_box().toolbar self._main_area = parent._main_area self._erase_button = parent.edit_toolbar.erase_button self._sw = parent._sw if HASTOOLBARBOX: target_toolbar = self._main_toolbar else: target_toolbar = self.parent.edit_toolbar self._mods = RadioToolButton(icon_name='select-mode') self._mods.set_tooltip(_('Select thoughts')) self._mods.set_accelerator(_('<ctrl>e')) self._mods.connect('clicked', parent.mode_cb, MMapArea.MODE_NULL) target_toolbar.insert(self._mods, -1) self._link_button = RadioToolButton(icon_name='link', group=self._mods) self._link_button.set_tooltip(_('Link/unlink two selected thoughts')) self._link_button.set_accelerator(_('<ctrl>l')) self._link_button.connect('clicked', self.__link_cb) target_toolbar.insert(self._link_button, -1) self.move_button = RadioToolButton(icon_name='move', group=self._mods) self.move_button.set_tooltip(_('Move selected thoughs')) self.move_button.set_accelerator(_('<ctrl>m')) self.move_button.connect('clicked', self.__move_cb) target_toolbar.insert(self.move_button, -1) self.drag_button = RadioToolButton(icon_name='drag', group=self._mods) self.drag_button.set_tooltip(_('Scroll the screen')) self.drag_button.connect('clicked', self.__drag_cb) target_toolbar.insert(self.drag_button, -1) if HASTOOLBARBOX: self._separator_2 = Gtk.SeparatorToolItem() self._separator_2.props.draw = False #self._separator_2.set_size_request(0, -1) self._separator_2.set_expand(True) self._separator_2.show() target_toolbar.insert(self._separator_2, -1) self._stop_button = StopButton(parent) target_toolbar.insert(self._stop_button, -1) def stop_dragging(self): if self._main_area.is_dragging(): self._main_area.drag_menu_cb(self._sw, False) def _stop_moving(self): self._main_area.move_mode = False def __link_cb(self, widget): self._stop_moving() self.stop_dragging() self._main_area.link_menu_cb() def __move_cb(self, widget): self.stop_dragging() if self._main_area.move_mode: self._main_area.stop_moving() else: self._main_area.start_moving(self.move_button) self._erase_button.set_sensitive(False) def __drag_cb(self, widget): # If we were moving, stop self._stop_moving() if not self._main_area.is_dragging(): self._main_area.drag_menu_cb(self._sw, True) else: self.stop_dragging() self._erase_button.set_sensitive(False) def reconfigure(self): ''' If screen width has changed, we may need to reconfigure the toolbars ''' if not HASTOOLBARBOX: return if hasattr(self, '_separator_2'): if Gdk.Screen.width() / 13 > style.GRID_CELL_SIZE: if self._separator_2.get_parent() is None: self._main_toolbar.remove(self._stop_button) self._main_toolbar.insert(self._separator_2, -1) self._main_toolbar.insert(self._stop_button, -1) else: self._main_toolbar.remove(self._separator_2)
class Toolbar(ToolbarBox): def __init__(self, activity): ToolbarBox.__init__(self) activity_button = ActivityToolbarButton(activity) self.toolbar.insert(activity_button, 0) activity_button.show() separator = Gtk.SeparatorToolItem() self.toolbar.insert(separator, -1) self.choose_button = RadioToolButton('view-list') self.choose_button.set_tooltip(_('Choose a Poll')) self.toolbar.insert(self.choose_button, -1) modes_group = self.choose_button self.create_button = RadioToolButton('new-poll') self.create_button.set_tooltip(_('Build a Poll')) self.toolbar.insert(self.create_button, -1) self.create_button.props.group = modes_group self.settings_button = ToolButton('preferences-system') self.settings_button.set_tooltip(_('Settings')) self.settings_button.palette_invoker.props.toggle_palette = True self.settings_button.palette_invoker.props.lock_palette = True self.settings_button.props.hide_tooltip_on_click = False palette = self.settings_button.get_palette() hbox = Gtk.HBox() self._options_palette = OptionsPalette(activity) hbox.pack_start(self._options_palette, True, True, style.DEFAULT_SPACING) hbox.show_all() palette.set_content(hbox) self.toolbar.insert(self.settings_button, -1) self.toolbar.insert(Gtk.SeparatorToolItem(), -1) self.pie_chart_button = RadioToolButton('pie-chart') self.pie_chart_button.set_tooltip(_('Pie chart')) self.toolbar.insert(self.pie_chart_button, -1) charts_group = self.pie_chart_button self.vbar_chart_button = RadioToolButton('vbar-chart') self.vbar_chart_button.set_tooltip(_('Vertical bar chart')) self.toolbar.insert(self.vbar_chart_button, -1) self.vbar_chart_button.props.group = charts_group separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.toolbar.insert(separator, -1) separator.show() self.toolbar.insert(StopButton(activity), -1) # add the export buttons activity_button.page.insert(Gtk.SeparatorToolItem(), -1) self.export_data_bt = ToolButton('save-as-data') self.export_data_bt.props.tooltip = _('Export data') activity_button.page.insert(self.export_data_bt, -1) self.export_image_bt = ToolButton('save-as-image') self.export_image_bt.set_tooltip(_("Save as Image")) activity_button.page.insert(self.export_image_bt, -1) activity_button.page.show_all() self.show_all() def update_configs(self): self._options_palette.update_configs()
def build_toolbar(self): toolbox = ToolbarBox() toolbar = toolbox.toolbar activity_button = ActivityButton(self) toolbar.insert(activity_button, -1) toolbar.insert(Gtk.SeparatorToolItem(), -1) new_game = ToolButton("hear") new_game.set_tooltip(_("Hear new hint")) new_game.connect("clicked", self.game.new_game) play_sound = ToolButton("repeat") play_sound.set_tooltip(_("Repeat hint")) play_sound.connect("clicked", self.game.sound_current_game) toolbar.insert(new_game, -1) toolbar.insert(play_sound, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar.insert(separator, -1) item = Gtk.ToolItem() item.add(self.word_label) toolbar.insert(item, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar.insert(separator, -1) en_button = RadioToolButton(icon_name='en') en_button.set_tooltip(_("English")) en_button.connect("clicked", self.game.change_language) toolbar.insert(en_button, -1) fr_button = RadioToolButton(icon_name='fr', group=en_button) fr_button.set_tooltip(_("French")) fr_button.connect("clicked", self.game.change_language) toolbar.insert(fr_button, -1) es_button = RadioToolButton(icon_name='es', group=en_button) es_button.set_tooltip(_("Spanish")) es_button.connect("clicked", self.game.change_language) toolbar.insert(es_button, -1) locale = os.environ["LANG"] locale = locale.split("_")[0] if locale == "en": en_button.set_active(True) elif locale == "fr": fr_button.set_active(True) elif locale == "es": es_button.set_active(True) else: en_button.set_active(True) separator = Gtk.SeparatorToolItem() toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbar.insert(stopbtn, -1) toolbar.show_all() self.set_toolbar_box(toolbox)
class ConvertActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 self.dic = {} # Canvas self._canvas = Gtk.VBox() hbox = Gtk.HBox() self._liststore = Gtk.ListStore(str) self.combo1 = Gtk.ComboBox.new_with_model_and_entry(self._liststore) cell = Gtk.CellRendererText() self.combo1.pack_start(cell, True) self.combo1.set_entry_text_column(0) self.combo1.connect('changed', self._update_label) flip_btn = Gtk.Button() flip_btn.connect('clicked', self._flip) flip_btn.set_tooltip_text("Flip Units") flip_btn.add(Gtk.Image.new_from_file('icons/flip.svg')) self.combo2 = Gtk.ComboBox.new_with_model_and_entry(self._liststore) cell = Gtk.CellRendererText() self.combo2.pack_start(cell, True) self.combo2.set_entry_text_column(0) self.combo2.connect('changed', self._update_label) self.label_box = Gtk.HBox() self.value_entry = Gtk.Entry() self.value_entry.set_placeholder_text("Enter number") self.value_entry.connect('insert-text', self._value_insert_text) self.value_entry.connect('changed', self._update_label) self.label = Gtk.Label() self.label.set_selectable(True) self.label._size = 12 self.label.connect('draw', self.resize_label) self._canvas.pack_start(hbox, False, False, 20) hbox.pack_start(self.combo1, False, True, 20) hbox.pack_start(flip_btn, True, False, 20) hbox.pack_end(self.combo2, False, True, 20) value_box = Gtk.HBox() convert_box = Gtk.HBox() convert_box.pack_start(value_box, True, False, 0) value_box.pack_start(self.value_entry, False, False, 0) self._canvas.pack_start(convert_box, False, False, 5) self._canvas.pack_start(self.label_box, True, False, 0) self.label_box.add(self.label) self.set_canvas(self._canvas) # Toolbar toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbarbox.toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() separator.set_expand(False) separator.set_draw(True) toolbarbox.toolbar.insert(separator, -1) # RadioToolButton self._length_btn = RadioToolButton() self._length_btn.connect('clicked', lambda w: self._update_combo(convert.length)) # TRANS: https://en.wikipedia.org/wiki/Length self._length_btn.set_tooltip(_('Length')) self._length_btn.props.icon_name = 'length' self._volume_btn = RadioToolButton() self._volume_btn.connect('clicked', lambda w: self._update_combo(convert.volume)) # TRANS: https://en.wikipedia.org/wiki/Volume self._volume_btn.set_tooltip(_('Volume')) self._volume_btn.props.icon_name = 'volume' self._volume_btn.props.group = self._length_btn self._area_btn = RadioToolButton() self._area_btn.connect('clicked', lambda w: self._update_combo(convert.area)) # TRANS: https://en.wikipedia.org/wiki/Area self._area_btn.set_tooltip(_('Area')) self._area_btn.props.icon_name = 'area' self._area_btn.props.group = self._length_btn self._weight_btn = RadioToolButton() self._weight_btn.connect('clicked', lambda w: self._update_combo(convert.weight)) # TRANS: https://en.wikipedia.org/wiki/Weight self._weight_btn.set_tooltip(_('Weight')) self._weight_btn.props.icon_name = 'weight' self._weight_btn.props.group = self._length_btn self._speed_btn = RadioToolButton() self._speed_btn.connect('clicked', lambda w: self._update_combo(convert.speed)) # TRANS: https://en.wikipedia.org/wiki/Speed self._speed_btn.set_tooltip(_('Speed')) self._speed_btn.props.icon_name = 'speed' self._speed_btn.props.group = self._length_btn self._time_btn = RadioToolButton() self._time_btn.connect('clicked', lambda w: self._update_combo(convert.time)) # TRANS: https://en.wikipedia.org/wiki/Time self._time_btn.set_tooltip(_('Time')) self._time_btn.props.icon_name = 'time' self._time_btn.props.group = self._length_btn self._temp_btn = RadioToolButton() self._temp_btn.connect('clicked', lambda w: self._update_combo(convert.temp)) # TRANS: https://en.wikipedia.org/wiki/Temperature self._temp_btn.set_tooltip(_('Temperature')) self._temp_btn.props.icon_name = 'temp' self._temp_btn.props.group = self._length_btn #Circle self._circle_btn = RadioToolButton() self._circle_btn.connect('clicked', lambda w: self._update_combo(convert.circle)) self._circle_btn.set_tooltip(_('Angles of Circles')) self._circle_btn.props.icon_name = 'circle' self._circle_btn.props.group = self._length_btn #pressure self._pressure_btn = RadioToolButton() self._pressure_btn.connect('clicked', lambda w: self._update_combo(convert.pressure)) self._pressure_btn.set_tooltip(_('Pressure')) self._pressure_btn.props.icon_name = 'pressure' self._pressure_btn.props.group = self._length_btn #force self._force_btn = RadioToolButton() self._force_btn.connect('clicked', lambda w: self._update_combo(convert.force)) self._force_btn.set_tooltip(_('Force')) self._force_btn.props.icon_name = 'force' self._force_btn.props.group = self._length_btn #energy self._energy_btn = RadioToolButton() self._energy_btn.connect('clicked', lambda w: self._update_combo(convert.energy)) self._energy_btn.set_tooltip(_('Energy')) self._energy_btn.props.icon_name = 'energy' self._energy_btn.props.group = self._length_btn #Storage self._storage_btn = RadioToolButton() self._storage_btn.connect('clicked', lambda w: self._update_combo(convert.storage)) self._storage_btn.set_tooltip(_('Digital Storage')) self._storage_btn.props.icon_name = 'storage' self._storage_btn.props.group = self._length_btn toolbarbox.toolbar.insert(self._length_btn, -1) toolbarbox.toolbar.insert(self._volume_btn, -1) toolbarbox.toolbar.insert(self._area_btn, -1) toolbarbox.toolbar.insert(self._weight_btn, -1) toolbarbox.toolbar.insert(self._speed_btn, -1) toolbarbox.toolbar.insert(self._time_btn, -1) toolbarbox.toolbar.insert(self._temp_btn, -1) toolbarbox.toolbar.insert(self._circle_btn, -1) toolbarbox.toolbar.insert(self._pressure_btn, -1) toolbarbox.toolbar.insert(self._force_btn, -1) toolbarbox.toolbar.insert(self._energy_btn, -1) toolbarbox.toolbar.insert(self._storage_btn, -1) separator = Gtk.SeparatorToolItem() separator.set_expand(True) separator.set_draw(False) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) self._update_combo(convert.length) self.show_all() def _update_label(self, entry): try: num_value = str(self.value_entry.get_text()) num_value = str(num_value.replace(',', '')) decimals = str(len(num_value.split('.')[-1])) fmt = '%.' + decimals + 'f' new_value = locale.format(fmt, float(num_value)) new_value = new_value.rstrip("0") if new_value[-1] == '.': new_value = new_value[0:len(new_value)-1] convert_value = str(self.convert()) decimals = str(len(convert_value.split('.')[-1])) fmt = '%.' + decimals + 'f' new_convert = locale.format(fmt, float(convert_value)) new_convert = new_convert.rstrip("0") if new_convert[-1] == '.': new_convert = new_convert[0:len(new_convert)-1] text = '%s ~ %s' % (new_value, new_convert) self.label.set_text(text) except ValueError: pass def _update_combo(self, data): self._liststore.clear() self.dic = data keys = self.dic.keys() keys.sort() for x in keys: self._liststore.append(['%s' % (x)]) if keys[0] == 'Cables': self.combo1.set_active(12) self.combo2.set_active(12) elif keys[0] == 'Cubic Centimeter': self.combo1.set_active(3) self.combo2.set_active(3) elif keys[0] == 'Acre': self.combo1.set_active(4) self.combo2.set_active(4) elif keys[0] == 'Carat': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Centimeters/Minute': self.combo1.set_active(9) self.combo2.set_active(9) elif keys[0] == 'Day': self.combo1.set_active(8) self.combo2.set_active(8) elif keys[0] == 'Celsius': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Degrees': self.combo1.set_active(1) self.combo2.set_active(1) elif keys[0] == 'Atmosphere (atm)': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Dyne (dyn)': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Calories (cal)': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Bit': self.combo1.set_active(1) self.combo2.set_active(1) else: pass self.show_all() def _get_active_text(self, combobox): active = combobox.get_active() keys = self.dic.keys() keys.sort() if active < 0: active = 0 text = keys[active] if '<sup>' in text: text = text.split('<b>')[1].split('</b>')[0] return text def _flip(self, widget): value = self.label.get_text().split(' ~ ') self.value_entry.set_text(value[1]) active_combo1 = self.combo1.get_active() active_combo2 = self.combo2.get_active() self.combo1.set_active(active_combo2) self.combo2.set_active(active_combo1) def resize_label(self, widget, event): num_label = len(self.label.get_text()) try: size = str((60 * SCREEN_WIDTH / 100) / num_label) if not size == self.label._size: self.label.modify_font(Pango.FontDescription(size)) self.label._size = size except ZeroDivisionError: pass def convert(self): number = float(self.value_entry.get_text().replace(',', '')) unit = self._get_active_text(self.combo1) to_unit = self._get_active_text(self.combo2) return convert.convert(number, unit, to_unit, self.dic) def _value_insert_text(self, entry, text, length, position): for char in text: if char == "-" and \ self.value_entry.get_text() is "" and len(text) == 1: return False elif not re.match('[0-9,.]', char): entry.emit_stop_by_name('insert-text') return True return False
def _add_clock_controls(self, display_toolbar): # First group of radio button to select the type of clock to display button1 = RadioToolButton(icon_name="simple-clock") button1.set_tooltip(_('Simple Clock')) button1.connect("toggled", self._display_mode_changed_cb, _MODE_SIMPLE_CLOCK) display_toolbar.insert(button1, -1) self._display_mode_buttons.append(button1) button2 = RadioToolButton(icon_name="nice-clock", group=button1) button2.set_tooltip(_('Nice Clock')) button2.connect("toggled", self._display_mode_changed_cb, _MODE_NICE_CLOCK) display_toolbar.insert(button2, -1) self._display_mode_buttons.append(button2) button3 = RadioToolButton(icon_name="digital-clock", group=button1) button3.set_tooltip(_('Digital Clock')) button3.connect("toggled", self._display_mode_changed_cb, _MODE_DIGITAL_CLOCK) display_toolbar.insert(button3, -1) self._display_mode_buttons.append(button3) # A separator between the two groups of buttons self._add_separator(display_toolbar) # Now the options buttons to display other elements: date, day # of week... A button in the toolbar to write the time in # full letters self._write_time_btn = ToggleToolButton("write-time") self._write_time_btn.set_tooltip(_('Display time in full letters')) self._write_time_btn.connect("toggled", self._write_time_clicked_cb) display_toolbar.insert(self._write_time_btn, -1) # The button to display the weekday and date self._write_date_btn = ToggleToolButton("write-date") self._write_date_btn.set_tooltip(_('Display weekday and date')) self._write_date_btn.connect("toggled", self._write_date_clicked_cb) display_toolbar.insert(self._write_date_btn, -1) # Another button to speak aloud the time self._speak_time_btn = ToggleToolButton("microphone") self._speak_time_btn.set_tooltip(_('Talking clock')) self._speak_time_btn.connect("toggled", self._speak_time_clicked_cb) display_toolbar.insert(self._speak_time_btn, -1) # A separator between the two groups of buttons self._add_separator(display_toolbar) # And another button to toggle grabbing the hands self._grab_button = ToggleToolButton("grab") self._grab_button.set_tooltip(_('Grab the hands')) self._grab_button.connect("toggled", self._grab_clicked_cb) display_toolbar.insert(self._grab_button, -1) if os.access('/boot/olpc_build', os.R_OK) and \ os.access('/usr/sbin/ntpdate', os.R_OK): self._add_separator(display_toolbar) self._ntp_button = ProgressToolButton("emblem-downloads", style.STANDARD_ICON_SIZE, 'vertical') self._ntp_button.set_tooltip(_('Download time')) self._ntp_button.connect("clicked", self._ntp_clicked_cb) self._ntp_button.update(0.05) display_toolbar.insert(self._ntp_button, -1)
class ImageToolbar(Gtk.Toolbar): _EFFECT_RAINBOW_NAME = 'rainbow' _EFFECT_KALIDOSCOPE_NAME = 'kalidoscope' def __init__(self, activity): Gtk.Toolbar.__init__(self) self._activity = activity self.properties = self._activity.area.tool self._object_insert = ToolButton('insert-picture') self.insert(self._object_insert, -1) self._object_insert.set_tooltip(_('Insert Image')) separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.insert(separator, -1) self.width_percent = 1. self.height_percent = 1. # FIXME: Sometimes we get the gnome icons not the sugar ones self._object_rotate_left = ToolButton('object-rotate-left-sugar') self.insert(self._object_rotate_left, -1) self._object_rotate_left.set_tooltip(_('Rotate Left')) self._object_rotate_right = ToolButton('object-rotate-right-sugar') self.insert(self._object_rotate_right, -1) self._object_rotate_right.set_tooltip(_('Rotate Right')) self._mirror_horizontal = ToolButton('mirror-horizontal') self.insert(self._mirror_horizontal, -1) self._mirror_horizontal.show() self._mirror_horizontal.set_tooltip(_('Horizontal Mirror')) self._mirror_vertical = ToolButton('mirror-vertical') self.insert(self._mirror_vertical, -1) self._mirror_vertical.show() self._mirror_vertical.set_tooltip(_('Vertical Mirror')) separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.insert(separator, -1) self._effect_grayscale = ToolButton('effect-grayscale') self.insert(self._effect_grayscale, -1) self._effect_grayscale.set_tooltip(_('Grayscale')) self._effect_rainbow = RadioToolButton('effect-rainbow') self._effect_rainbow.props.group = activity.tool_group self.insert(self._effect_rainbow, -1) self._effect_rainbow.set_tooltip(_('Rainbow')) self._effect_kalidoscope = RadioToolButton('effect-kalidoscope') self._effect_kalidoscope.props.group = activity.tool_group self.insert(self._effect_kalidoscope, -1) self._effect_kalidoscope.set_tooltip(_('Kaleidoscope')) self._invert_colors = ToolButton('invert-colors') self.insert(self._invert_colors, -1) self._invert_colors.set_tooltip(_('Invert Colors')) self._object_insert.connect('clicked', self.insertImage, activity) self._object_rotate_left.connect('clicked', self.rotate_left, activity) self._object_rotate_right.connect('clicked', self.rotate_right, activity) self._mirror_vertical.connect('clicked', self.mirror_vertical) self._mirror_horizontal.connect('clicked', self.mirror_horizontal) self._effect_grayscale.connect('clicked', self.grayscale) self._effect_rainbow.connect('clicked', self.rainbow) self._effect_kalidoscope.connect('clicked', self.kalidoscope) self._invert_colors.connect('clicked', self.invert_colors) self.show_all() def rotate_left(self, widget, activity): activity.area.rotate_left(activity.area) def rotate_right(self, widget, activity): activity.area.rotate_right(activity.area) def mirror_horizontal(self, widget): self._activity.area.mirror(widget) def mirror_vertical(self, widget): self._activity.area.mirror(widget, horizontal=False) def insertImage(self, widget, activity): try: chooser = ObjectChooser(self._activity, what_filter='Image', filter_type=FILTER_TYPE_GENERIC_MIME, show_preview=True) except: # for compatibility with older versions chooser = ObjectChooser(self._activity, what_filter='Image') try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: logging.debug('ObjectChooser: %r', chooser.get_selected_object()) jobject = chooser.get_selected_object() if jobject and jobject.file_path: self._activity.area.load_image(jobject.file_path) finally: chooser.destroy() del chooser # Make the colors be in grayscale def grayscale(self, widget): self._activity.area.grayscale(widget) # Like the brush, but change it color when painting def rainbow(self, widget): self.properties['name'] = self._EFFECT_RAINBOW_NAME self._activity.area.set_tool(self.properties) def kalidoscope(self, widget): self.properties['name'] = self._EFFECT_KALIDOSCOPE_NAME self._activity.area.set_tool(self.properties) def invert_colors(self, widget): self._activity.area.invert_colors()
class ConvertActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 self.dic = {} # Canvas self._canvas = Gtk.VBox() hbox = Gtk.HBox() self._liststore1 = Gtk.ListStore(str) self.combo1 = Gtk.ComboBox(self._liststore1) cell = Gtk.CellRendererText() self.combo1.pack_start(cell, True) self.combo1.add_attribute(cell, 'markup', 0) self.combo1.connect('changed', self._call) flip_btn = Gtk.Button() flip_btn.connect('clicked', self._flip) flip_btn.add(Gtk.image_new_from_file('icons/flip.svg')) self._liststore2 = Gtk.ListStore(str) self.combo2 = Gtk.ComboBox(self._liststore1) cell = Gtk.CellRendererText() self.combo2.pack_start(cell, True) self.combo2.add_attribute(cell, 'markup', 0) self.combo2.connect('changed', self._call) self.label_box = Gtk.HBox() self.adjustment = Gtk.Adjustment(1.0, 0.0000000001, 10.0 ** 20.0, 0.1, 1.0) self.spin = Gtk.SpinButton(self.adjustment, 0.0, 2) self.label = Gtk.Label() self.label.set_selectable(True) self.label._size = 12 self.label.connect('expose-event', self.resize_label) self.convert_btn = Gtk.Button(_('Convert')) self.convert_btn.connect('clicked', self._call) self._canvas.pack_start(hbox, False, False, 20) hbox.pack_start(self.combo1, False, True, 20) hbox.pack_start(flip_btn, True, False) hbox.pack_end(self.combo2, False, True, 20) spin_box = Gtk.HBox() convert_box = Gtk.HBox() convert_box.pack_start(spin_box, True, False, 0) spin_box.pack_start(self.spin, False, False, 0) self._canvas.pack_start(convert_box, False, False, 5) self._canvas.pack_start(self.label_box, True, False, 0) self.label_box.add(self.label) spin_box.pack_start(self.convert_btn, False, False, 20) self.set_canvas(self._canvas) # Toolbar toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbarbox.toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() separator.set_expand(False) separator.set_draw(True) toolbarbox.toolbar.insert(separator, -1) # RadioToolButton self._length_btn = RadioToolButton() self._length_btn.connect('clicked', lambda w: self._update_combo(convert.length)) # TRANS: https://en.wikipedia.org/wiki/Length self._length_btn.set_tooltip(_('Length')) self._length_btn.props.icon_name = 'length' self._volume_btn = RadioToolButton() self._volume_btn.connect('clicked', lambda w: self._update_combo(convert.volume)) # TRANS: https://en.wikipedia.org/wiki/Volume self._volume_btn.set_tooltip(_('Volume')) self._volume_btn.props.icon_name = 'volume' self._volume_btn.props.group = self._length_btn self._area_btn = RadioToolButton() self._area_btn.connect('clicked', lambda w: self._update_combo(convert.area)) # TRANS: https://en.wikipedia.org/wiki/Area self._area_btn.set_tooltip(_('Area')) self._area_btn.props.icon_name = 'area' self._area_btn.props.group = self._length_btn self._weight_btn = RadioToolButton() self._weight_btn.connect('clicked', lambda w: self._update_combo(convert.weight)) # TRANS: https://en.wikipedia.org/wiki/Weight self._weight_btn.set_tooltip(_('Weight')) self._weight_btn.props.icon_name = 'weight' self._weight_btn.props.group = self._length_btn self._speed_btn = RadioToolButton() self._speed_btn.connect('clicked', lambda w: self._update_combo(convert.speed)) # TRANS: https://en.wikipedia.org/wiki/Speed self._speed_btn.set_tooltip(_('Speed')) self._speed_btn.props.icon_name = 'speed' self._speed_btn.props.group = self._length_btn self._time_btn = RadioToolButton() self._time_btn.connect('clicked', lambda w: self._update_combo(convert.time)) # TRANS: https://en.wikipedia.org/wiki/Time self._time_btn.set_tooltip(_('Time')) self._time_btn.props.icon_name = 'time' self._time_btn.props.group = self._length_btn self._temp_btn = RadioToolButton() self._temp_btn.connect('clicked', lambda w: self._update_combo(convert.temp)) # TRANS: https://en.wikipedia.org/wiki/Temperature self._temp_btn.set_tooltip(_('Temperature')) self._temp_btn.props.icon_name = 'temp' self._temp_btn.props.group = self._length_btn toolbarbox.toolbar.insert(self._length_btn, -1) toolbarbox.toolbar.insert(self._volume_btn, -1) toolbarbox.toolbar.insert(self._area_btn, -1) toolbarbox.toolbar.insert(self._weight_btn, -1) toolbarbox.toolbar.insert(self._speed_btn, -1) toolbarbox.toolbar.insert(self._time_btn, -1) toolbarbox.toolbar.insert(self._temp_btn, -1) separator = Gtk.SeparatorToolItem() separator.set_expand(True) separator.set_draw(False) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) self._update_combo(convert.length) self.show_all() def _update_label(self): try: spin_value = str(self.spin.get_value()) decimals = str(len(spin_value.split('.')[-1])) fmt = '%.' + decimals + 'f' new_value = locale.format(fmt, float(spin_value)) convert_value = str(self.convert()) decimals = str(len(convert_value.split('.')[-1])) fmt = '%.' + decimals + 'f' new_convert = locale.format(fmt, float(convert_value)) text = '%s ~ %s' % (new_value, new_convert) self.label.set_text(text) except KeyError: pass def _call(self, widget=None): self._update_label() self.show_all() def _update_combo(self, data): self._liststore1.clear() self._liststore2.clear() self.dic = data keys = self.dic.keys() keys.sort() for x in keys: symbol = '' if len(self.dic[x]) == 3: symbol = self.dic[x][-1] symbol = '<sup><b>%s</b></sup>' % symbol self._liststore1.append(['%s%s' % (x, symbol)]) self._liststore2.append(['%s%s' % (x, symbol)]) self.combo1.set_active(0) self.combo2.set_active(0) self._call() self.show_all() def _get_active_text(self, combobox): active = combobox.get_active() keys = self.dic.keys() keys.sort() if active < 0: return None text = keys[active] if '<sup>' in text: text = text.split('<b>')[1].split('</b>')[0] return text def _flip(self, widget): active_combo1 = self.combo1.get_active() active_combo2 = self.combo2.get_active() self.combo1.set_active(active_combo2) self.combo2.set_active(active_combo1) value = float(self.label.get_text().split(' ~ ')[1].replace(',', '.')) self.spin.set_value(value) self._call() def resize_label(self, widget, event): num_label = len(self.label.get_text()) try: size = str((60 * SCREEN_WIDTH / 100) / num_label) if not size == self.label._size: self.label.modify_font(pango.FontDescription(size)) self.label._size = size except ZeroDivisionError: pass def convert(self): number = float(self.spin.get_text().replace(',', '.')) unit = self._get_active_text(self.combo1) to_unit = self._get_active_text(self.combo2) return convert.convert(number, unit, to_unit, self.dic)
class SensorToolbar(Gtk.Toolbar): ''' The toolbar for specifiying the sensor: sound, resitance, or voltage ''' LOWER = 0.0 UPPER = 1.0 STR_DC_R = \ _("Resistive sensor (connect sensor to pink 'Mic In' on left side \ of XO)" ) + ' ' STR_DC_V = \ _("Voltage sensor (connect sensor to pink 'Mic In' on left side \ of XO)" ) + ' ' STR_AC = _('Sound') + ' ' STR_RESISTANCE = _('Resistance') + ' (' + _('Ohms') + ') ' STR_VOLTAGE = _('Voltage') + ' (' + _('Volts') + ') ' STR_TIME = _('Time Base') + ' ' STR_FREQUENCY = _('Frequency Base') + ' ' STR_INVERT = ' ' + _('Invert') + ' ' STR_XAXIS_TEXT = _('X Axis Scale: 1 division = %(division)s %(unit)s') # TRANSLATORS: This is milli seconds. MS = _('ms') # TRANSLATORS: This is Hertz, so 1/second. HZ = _('Hz') def __init__(self, activity, channels): ''' By default, start with resistance mode ''' super(type(self), self).__init__() self.activity = activity self._channels = channels self._lock_radio_buttons = False self._radio_button_pushed = False self.values = [] for i in range(self._channels): self.values.append('') self.string_for_textbox = '' self.gain = 1.0 self.y_mag = 3.0 self.capture_gain = CAPTURE_GAIN self.mic_boost = MIC_BOOST self.mode = 'sound' # Set up Time-domain Button self.time = RadioToolButton(icon_name='media-audio', group=None) self.insert(self.time, -1) self.time.set_tooltip(_('Sound')) self.time.connect('clicked', self.analog_resistance_voltage_mode_cb, 'sound') # Set up Resistance Button self.resistance = RadioToolButton(icon_name='resistance', group=self.time) if _can_use_dc(self.activity.hw): self.insert(self.resistance, -1) self.resistance.show() self.resistance.set_tooltip(_('Resistance Sensor')) self.resistance.connect('clicked', self.analog_resistance_voltage_mode_cb, 'resistance') # Set up Voltage Button self.voltage = RadioToolButton(icon_name='voltage', group=self.time) if _can_use_dc(self.activity.hw): self.insert(self.voltage, -1) self.voltage.set_tooltip(_('Voltage Sensor')) self.voltage.connect('clicked', self.analog_resistance_voltage_mode_cb, 'voltage') separator = Gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._log_value = LOG_TIMER_VALUES[1] self.log_label = Gtk.Label(self._log_to_string(self._log_value)) toolitem = Gtk.ToolItem() toolitem.add(self.log_label) self.insert(toolitem, -1) self._log_button = ToolButton('timer-10') self._log_button.set_tooltip(_('Select logging interval')) self._log_button.connect('clicked', self._log_selection_cb) self.insert(self._log_button, -1) self._setup_log_palette() # Set up Logging/Stop Logging Button self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.set_tooltip(_('Start logging')) self._record.connect('clicked', self.record_control_cb) separator = Gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) toolitem = Gtk.ToolItem() self.trigger_label = Gtk.Label(_('Trigger')) toolitem.add(self.trigger_label) self.insert(toolitem, -1) # Set up Trigger Combo box self.trigger_none = RadioToolButton() self.trigger_none.set_icon_name('trigger-none') self.insert(self.trigger_none, -1) self.trigger_none.set_tooltip(_('None')) self.trigger_none.connect('clicked', self.update_trigger_control_cb, self.activity.wave.TRIGGER_NONE) self.trigger_rise = RadioToolButton(group=self.trigger_none) self.trigger_rise.set_icon_name('trigger-rise') self.insert(self.trigger_rise, -1) self.trigger_rise.set_tooltip(_('Rising Edge')) self.trigger_rise.connect('clicked', self.update_trigger_control_cb, self.activity.wave.TRIGGER_POS) self.trigger_fall = RadioToolButton(group=self.trigger_none) self.trigger_fall.set_icon_name('trigger-fall') self.insert(self.trigger_fall, -1) self.trigger_fall.set_tooltip(_('Falling Edge')) self.trigger_fall.connect('clicked', self.update_trigger_control_cb, self.activity.wave.TRIGGER_NEG) self.show_all() def get_log(self): return self._log_value def get_log_idx(self): if self._log_value in LOG_TIMER_VALUES: return LOG_TIMER_VALUES.index(self._log_value) else: return LOG_TIMER_VALUES[0] def set_log_idx(self, idx): self._log_value = LOG_TIMER_VALUES[idx] self.log_label.set_text(self._log_to_string(self._log_value)) if hasattr(self, '_log_button'): self._log_button.set_icon('timer-%d' % (self._log_value)) def _log_selection_cb(self, widget): if self._log_palette: if not self._log_palette.is_up(): self._log_palette.popup(immediate=True) else: self._log_palette.popdown(immediate=True) return def _log_to_seconds(self, tenth_seconds): return tenth_seconds / 10. def _log_to_string(self, tenth_seconds): if tenth_seconds in LOG_TIMER_LABELS: return LOG_TIMER_LABELS[tenth_seconds] else: return _('1 second') def _setup_log_palette(self): self._log_palette = self._log_button.get_palette() for tenth_seconds in LOG_TIMER_VALUES: text = self._log_to_string(tenth_seconds) menu_item = MenuItem(icon_name='timer-%d' % (tenth_seconds), text_label=text) menu_item.connect('activate', self._log_selected_cb, tenth_seconds) self._log_palette.menu.append(menu_item) menu_item.show() def _log_selected_cb(self, button, seconds): self.set_log_idx(LOG_TIMER_VALUES.index(seconds)) def add_frequency_slider(self, toolbox): ''' Either on the Sound toolbar or the Main toolbar ''' self._freq_stepper_up = ToolButton('freq-high') self._freq_stepper_up.set_tooltip(_('Zoom out')) self._freq_stepper_up.connect('clicked', self._freq_stepper_up_cb) self._freq_stepper_up.show() self.activity.adjustmentf = Gtk.Adjustment(0.5, self.LOWER, self.UPPER, 0.01, 0.1, 0) self.activity.adjustmentf.connect('value_changed', self.cb_page_sizef) self._freq_range = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL, adjustment=self.activity.adjustmentf) self._freq_range.set_inverted(True) self._freq_range.set_draw_value(False) self._freq_range.set_size_request(120, 15) self._freq_range.show() self._freq_stepper_down = ToolButton('freq-low') self._freq_stepper_down.set_tooltip(_('Zoom in')) self._freq_stepper_down.connect('clicked', self._freq_stepper_down_cb) self._freq_stepper_down.show() self._freq_range_tool = Gtk.ToolItem() self._freq_range_tool.add(self._freq_range) self._freq_range_tool.show() toolbox.add(self._freq_stepper_up) toolbox.add(self._freq_range_tool) toolbox.add(self._freq_stepper_down) return def update_trigger_control_cb(self, button, value): if button is None: value = self.activity.wave.TRIGGER_NONE if self.activity.wave.get_fft_mode(): self.trigger_none.set_active(True) else: self.activity.wave.set_trigger(value) def analog_resistance_voltage_mode_cb(self, button=None, mode_to_set='sound'): ''' Callback for Analog/Resistance/Voltage Buttons ''' if self._lock_radio_buttons: logging.debug('mode selector locked') self._radio_button_pushed = True return if self.mode == mode_to_set: logging.debug('mode already set to %s' % mode_to_set) return self._lock_radio_buttons = True if self.activity.CONTEXT == 'sound': self.sound_context_off() else: self.sensor_context_off() # Force time domain when switching modes if self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Turn off logging when switching modes if self.activity.audiograb.we_are_logging: self.record_control_cb() self.set_mode(mode_to_set) if mode_to_set == 'sound': self.set_sound_context() elif mode_to_set == 'resistance': self.set_sensor_context() elif mode_to_set == 'voltage': self.set_sensor_context() self.update_string_for_textbox() return False def unlock_radio_buttons(self): ''' Enable radio button selection ''' logging.debug('unlocking radio buttons') if self._radio_button_pushed: if self.mode == 'sound': self.time.set_active(True) elif self.mode == 'resistance': self.resistance.set_active(True) elif self.mode == 'voltage': self.voltage.set_active(True) self._lock_radio_buttons = False self._radio_button_pushed = False def set_mode(self, mode='sound'): ''' Set the mixer settings to match the current mode. ''' self.mode = mode self.activity.audiograb.set_sensor_type(self.mode) for i in range(self._channels): self.values[i] = 0.0 return def get_mode(self): ''' Get the mixer settings. ''' return self.mode def _freq_stepper_up_cb(self, button=None): ''' Moves the horizontal zoom slider to the left one notch, where one notch is 1/100 of the total range. This correspond to zooming out as a larger number of Hertz or milliseconds will be represented by the same space on the screen. ''' new_value = self._freq_range.get_value() + \ (self.UPPER - self.LOWER) / 100.0 if new_value <= self.UPPER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.UPPER) def _freq_stepper_down_cb(self, button=None): ''' Moves the horizontal zoom slider to the right one notch, where one notch is 1/100 of the total range. This corresponds to zooming in. ''' new_value = self._freq_range.get_value() - \ (self.UPPER - self.LOWER) / 100.0 if new_value >= self.LOWER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.LOWER) def cb_page_sizef(self, button=None): ''' Callback to scale the frequency range (zoom in and out) ''' if self._update_page_size_id: GObject.source_remove(self._update_page_size_id) self._update_page_size_id =\ GObject.timeout_add(250, self.update_page_size) return True def update_page_size(self): ''' Set up the scaling of the display. ''' self._update_page_size_id = None value = self.activity.adjustmentf.get_value() new_value = round(value * 100.0) / 100.0 if value != new_value: self.activity.adjustmentf.set_value(new_value) return False time_div = 0.001 * max(value, 0.05) freq_div = 1000 * max(value, 0.01) self.activity.wave.set_div(time_div, freq_div) self.update_string_for_textbox() return False def set_sound_context(self): ''' Called when analog sensing is selected ''' self.set_show_hide_windows(mode='sound') GObject.timeout_add(500, self.sound_context_on) self.activity.CONTEXT = 'sound' def set_sensor_context(self): ''' Called when digital sensing is selected ''' self.set_show_hide_windows(mode='sensor') GObject.timeout_add(500, self.sensor_context_on) self.activity.CONTEXT = 'sensor' def set_show_hide_windows(self, mode='sound'): ''' Shows the appropriate window identified by the mode ''' self.activity.wave.set_context_on() for i in range(self._channels): self.activity.side_toolbars[i].set_show_hide(True, mode) def sensor_context_off(self): ''' Called when a DC sensor is no longer selected ''' # self.activity.audiograb.pause_grabbing() self.activity.audiograb.stop_grabbing() def sensor_context_on(self): ''' Called when a DC sensor is selected ''' self.update_string_for_textbox() self.activity.wave.set_trigger(self.activity.wave.TRIGGER_NONE) # self.activity.audiograb.resume_grabbing() self.activity.audiograb.start_grabbing() return False def sound_context_off(self): ''' Called when an analog sensor is no longer selected ''' self.gain, self.y_mag = self.activity.wave.get_mag_params() self.capture_gain = self.activity.audiograb.get_capture_gain() self.mic_boost = self.activity.audiograb.get_mic_boost() self.activity.audiograb.stop_grabbing() def sound_context_on(self): ''' Called when an analog sensor is selected ''' self.activity.wave.set_mag_params(self.gain, self.y_mag) self.update_string_for_textbox() self.update_trigger_control_cb(None, self.activity.wave.TRIGGER_NONE) self.activity.audiograb.start_grabbing() return False def set_sample_value(self, value='', channel=0): ''' Write a sample value to the textbox. ''' self.values[channel] = value self.update_string_for_textbox() return def record_control_cb(self, button=None): ''' Depending upon the selected interval, does either a logging session, or just logs the current buffer. ''' if self.activity.audiograb.we_are_logging: self.activity.audiograb.set_logging_params(start_stop=False) self._record.set_icon_name('media-record') self._record.show() self._record.set_tooltip(_('Start Recording')) else: Xscale = (1.00 / self.activity.audiograb.get_sampling_rate()) Yscale = 0.0 interval = self._log_value / 10. # self.interval_convert() username = self.activity.nick if self.activity.wave.get_fft_mode(): self.activity.data_logger.start_new_session( username, Xscale, Yscale, self._log_to_string(self._log_value), channels=self._channels, mode='frequency') else: self.activity.data_logger.start_new_session( username, Xscale, Yscale, self._log_to_string(self._log_value), channels=self._channels, mode=self.mode) self.activity.audiograb.set_logging_params(start_stop=True, interval=interval) self._record.set_icon_name('record-stop') self._record.show() self._record.set_tooltip(_('Stop Recording')) self.activity.new_recording = True def update_string_for_textbox(self): ''' Update the status field at the bottom of the canvas. ''' if self.mode == 'resistance': string_for_textbox = (self.STR_DC_R + '\n') string_for_textbox += self.STR_RESISTANCE elif self.mode == 'voltage': string_for_textbox = (self.STR_DC_V + '\n') string_for_textbox += self.STR_VOLTAGE else: string_for_textbox = (self.STR_AC + '\t') if self.activity.wave.get_fft_mode(): scalex = self.STR_XAXIS_TEXT % { 'unit': self.HZ, 'division': self.activity.wave.freq_div } string_for_textbox += self.STR_FREQUENCY string_for_textbox += ('\n' + scalex) elif self.mode == 'sound': scalex = self.STR_XAXIS_TEXT % { 'unit': self.MS, 'division': self.activity.wave.time_div * 1000 } string_for_textbox += self.STR_TIME string_for_textbox += ('\n' + scalex) else: for i in range(self._channels): string_for_textbox += '\t(%s)' % (self.values[i]) invert = False for i in range(self._channels): if self.activity.wave.get_invert_state(channel=i): invert = True if invert: string_for_textbox += self.STR_INVERT self.activity.text_box.set_label(string_for_textbox)
def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 # CHART_OPTIONS self.x_label = "" self.y_label = "" self.chart_color = utils.get_user_fill_color('str') self.chart_line_color = utils.get_user_stroke_color('str') self.current_chart = None self.charts_area = None self.chart_data = [] # TOOLBARS toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_btn_toolbar = activity_button.page activity_btn_toolbar.title.connect('changed', self._set_chart_title) save_as_image = ToolButton("save-as-image") save_as_image.connect("clicked", self._save_as_image) save_as_image.set_tooltip(_("Save as image")) activity_btn_toolbar.insert(save_as_image, -1) save_as_image.show() toolbarbox.toolbar.insert(activity_button, 0) import_freespace = ToolButton("import-freespace") import_freespace.connect("clicked", self.__import_freespace_cb) import_freespace.set_tooltip(_("Read Freespace data")) toolbarbox.toolbar.insert(import_freespace, -1) import_freespace.show() import_journal = ToolButton('import-journal') import_journal.connect('clicked', self.__import_journal_cb) import_journal.set_tooltip(_('Read Journal data')) toolbarbox.toolbar.insert(import_journal, -1) import_journal.show() import_turtle = ToolButton('import-turtle') import_turtle.connect('clicked', self.__import_turtle_cb) import_turtle.set_tooltip(_('Read Turtle data')) toolbarbox.toolbar.insert(import_turtle, -1) import_turtle.show() separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) add_vbar_chart = RadioToolButton() add_vbar_chart.connect("clicked", self._add_chart_cb, "vbar") add_vbar_chart.set_tooltip(_("Vertical Bar Chart")) add_vbar_chart.props.icon_name = "vbar" charts_group = add_vbar_chart toolbarbox.toolbar.insert(add_vbar_chart, -1) add_hbar_chart = RadioToolButton() add_hbar_chart.connect("clicked", self._add_chart_cb, "hbar") add_hbar_chart.set_tooltip(_("Horizontal Bar Chart")) add_hbar_chart.props.icon_name = "hbar" add_hbar_chart.props.group = charts_group toolbarbox.toolbar.insert(add_hbar_chart, -1) add_pie_chart = RadioToolButton() add_pie_chart.connect("clicked", self._add_chart_cb, "pie") add_pie_chart.set_tooltip(_("Pie Chart")) add_pie_chart.props.icon_name = "pie" add_pie_chart.props.group = charts_group add_pie_chart.set_active(True) toolbarbox.toolbar.insert(add_pie_chart, -1) self.chart_type_buttons = [add_vbar_chart, add_hbar_chart, add_pie_chart] separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) fullscreen_btn = ToolButton('view-fullscreen') fullscreen_btn.set_tooltip(_('Fullscreen')) fullscreen_btn.connect("clicked", self.__fullscreen_cb) toolbarbox.toolbar.insert(fullscreen_btn, -1) charthelp.create_help(toolbarbox.toolbar) separator = Gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) # CANVAS paned = Gtk.HPaned() box = Gtk.VBox() self.box = box # Set the info box width to 1/3 of the screen: def size_allocate_cb(widget, allocation): paned.disconnect(self._setup_handle) box_width = allocation.width / 3 box.set_size_request(box_width, -1) self._setup_handle = paned.connect('size_allocate', size_allocate_cb) scroll = Gtk.ScrolledWindow() scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.labels_and_values = ChartData(self) scroll.add(self.labels_and_values) self.labels_and_values.connect("label-changed", self._label_changed) self.labels_and_values.connect("value-changed", self._value_changed) box.pack_start(scroll, True, True, 0) paned.add1(box) # CHARTS AREA eventbox = Gtk.EventBox() self.charts_area = ChartArea(self) self.charts_area.connect('size_allocate', self._chart_size_allocate) eventbox.modify_bg(Gtk.StateType.NORMAL, _WHITE) eventbox.add(self.charts_area) paned.add2(eventbox) self.set_canvas(paned) self.show_all()
class ReflectActivity(activity.Activity): ''' An activity for reflecting on one's work ''' def __init__(self, handle): ''' Initialize the toolbar ''' try: super(ReflectActivity, self).__init__(handle) except dbus.exceptions.DBusException as e: _logger.error(str(e)) logging.error('setting reflection data to []') self.reflection_data = [] self.connect('realize', self.__realize_cb) self.font_size = 8 self.max_participants = 4 self._setup_toolbars() color = profile.get_color() color_stroke = color.get_stroke_color() color_fill = color.get_fill_color() lighter = utils.lighter_color([color_stroke, color_fill]) darker = 1 - lighter if lighter == 0: self.bg_color = style.Color(color_stroke) self.fg_color = style.Color(color_fill) else: self.bg_color = style.Color(color_fill) self.fg_color = style.Color(color_stroke) self.modify_bg(Gtk.StateType.NORMAL, self.bg_color.get_gdk_color()) self.bundle_path = activity.get_bundle_path() self.tmp_path = os.path.join(activity.get_activity_root(), 'instance') self.sharing = False self._copy_entry = None self._paste_entry = None self._webkit = None self._clipboard_text = '' self._fixed = None self.initiating = True if self.shared_activity: # We're joining if not self.get_shared(): self.initiating = False self.busy_cursor() share_icon = Icon(icon_name='zoom-neighborhood') self._joined_alert = Alert() self._joined_alert.props.icon = share_icon self._joined_alert.props.title = _('Please wait') self._joined_alert.props.msg = _('Starting connection...') self.add_alert(self._joined_alert) # Wait for joined signal self.connect("joined", self._joined_cb) self._open_reflect_windows() self._setup_presence_service() # Joiners wait to receive data from sharer # Otherwise, load reflections from local store if not self.shared_activity: self.busy_cursor() GObject.idle_add(self._load_reflections) def read_file(self, file_path): fd = open(file_path, 'r') data = fd.read() fd.close() self.reflection_data = json.loads(data) def write_file(self, file_path): data = json.dumps(self.reflection_data) fd = open(file_path, 'w') fd.write(data) fd.close() self.metadata['font_size'] = str(self.font_size) def _load_reflections(self): self._find_starred() self._reflect_window.load(self.reflection_data) self.reset_cursor() def _found_obj_id(self, obj_id): for item in self.reflection_data: if 'obj_id' in item and item['obj_id'] == obj_id: return True return False def reload_data(self, data): ''' Reload data after sorting or searching ''' self._reflection_data = data[:] self._reflect_window.reload(self._reflection_data) self.reset_scrolled_window_adjustments() def _find_starred(self): ''' Find all the _stars in the Journal. ''' self.dsobjects, self._nobjects = datastore.find({'keep': '1'}) for dsobj in self.dsobjects: if self._found_obj_id(dsobj.object_id): continue # Already have this object -- TODO: update it self._add_new_from_journal(dsobj) def _add_new_from_journal(self, dsobj): self.reflection_data.append({ 'title': _('Untitled'), 'obj_id': dsobj.object_id}) if hasattr(dsobj, 'metadata'): if 'creation_time' in dsobj.metadata: self.reflection_data[-1]['creation_time'] = \ dsobj.metadata['creation_time'] else: self.reflection_data[-1]['creation_time'] = \ int(time.time()) if 'timestamp' in dsobj.metadata: self.reflection_data[-1]['modification_time'] = \ dsobj.metadata['timestamp'] else: self.reflection_data[-1]['modification_time'] = \ self.reflection_data[-1]['creation_time'] if 'activity' in dsobj.metadata: self.reflection_data[-1]['activities'] = \ [utils.bundle_id_to_icon(dsobj.metadata['activity'])] if 'title' in dsobj.metadata: self.reflection_data[-1]['title'] = \ dsobj.metadata['title'] if 'description' in dsobj.metadata: self.reflection_data[-1]['content'] = \ [{'text': dsobj.metadata['description']}] else: self.reflection_data[-1]['content'] = [] if 'tags' in dsobj.metadata: self.reflection_data[-1]['tags'] = [] tags = dsobj.metadata['tags'].split() for tag in tags: if tag[0] != '#': self.reflection_data[-1]['tags'].append('#' + tag) else: self.reflection_data[-1]['tags'].append(tag) if 'comments' in dsobj.metadata: try: comments = json.loads(dsobj.metadata['comments']) except: comments = [] self.reflection_data[-1]['comments'] = [] for comment in comments: try: data = {'nick': comment['from'], 'comment': comment['message']} if 'icon-color' in comment: colors = comment['icon-color'].split(',') darker = 1 - utils.lighter_color(colors) data['color'] = colors[darker] else: data['color'] = '#000000' self.reflection_data[-1]['comments'].append(data) except: _logger.debug('could not parse comment %s' % comment) if 'mime_type' in dsobj.metadata and \ dsobj.metadata['mime_type'][0:5] == 'image': new_path = os.path.join(self.tmp_path, dsobj.object_id) try: shutil.copy(dsobj.file_path, new_path) except Exception as e: logging.error("Couldn't copy %s to %s: %s" % (dsobj.file_path, new_path, e)) self.reflection_data[-1]['content'].append( {'image': new_path}) elif 'preview' in dsobj.metadata: pixbuf = utils.get_pixbuf_from_journal(dsobj, 300, 225) if pixbuf is not None: path = os.path.join(self.tmp_path, dsobj.object_id + '.png') utils.save_pixbuf_to_file(pixbuf, path) self.reflection_data[-1]['content'].append( {'image': path}) self.reflection_data[-1]['stars'] = 0 def delete_item(self, obj_id): for i, obj in enumerate(self.reflection_data): if obj['obj_id'] == obj_id: self.reflection_data.remove(self.reflection_data[i]) return def busy_cursor(self): self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) def reset_cursor(self): self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)) def _open_reflect_windows(self): # Most things need only be done once if self._fixed is None: self._fixed = Gtk.Fixed() self._fixed.set_size_request(Gdk.Screen.width(), Gdk.Screen.height()) # Offsets from the bottom of the screen dy1 = 2 * style.GRID_CELL_SIZE dy2 = 1 * style.GRID_CELL_SIZE self._button_area = Gtk.Alignment.new(0.5, 0, 0, 0) self._button_area.set_size_request(Gdk.Screen.width(), style.GRID_CELL_SIZE) self._fixed.put(self._button_area, 0, 0) self._button_area.show() self._scrolled_window = Gtk.ScrolledWindow() self._scrolled_window.set_size_request( Gdk.Screen.width(), Gdk.Screen.height() - dy1) self._set_scroll_policy() self._graphics_area = Gtk.Alignment.new(0.5, 0, 0, 0) self._scrolled_window.add_with_viewport(self._graphics_area) self._graphics_area.show() self._fixed.put(self._scrolled_window, 0, dy2) self._scrolled_window.show() self._overlay_window = Gtk.ScrolledWindow() self._overlay_window.set_size_request( style.GRID_CELL_SIZE * 10, style.GRID_CELL_SIZE * 6) self._overlay_window.modify_bg( Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color()) self._overlay_window.set_policy( Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self._overlay_area = Gtk.Alignment.new(0.5, 0, 0, 0) self._overlay_window.add_with_viewport(self._overlay_area) self._overlay_area.show() x = int((Gdk.Screen.width() - style.GRID_CELL_SIZE * 10) / 2) self._fixed.put(self._overlay_window, 0, Gdk.Screen.height()) self._overlay_window.show() self._old_overlay_widget = None self._reflect_window = ReflectWindow(self) self._reflect_window.show() Gdk.Screen.get_default().connect('size-changed', self._configure_cb) self._toolbox.connect('hide', self._resize_hide_cb) self._toolbox.connect('show', self._resize_show_cb) self._reflect_window.set_events(Gdk.EventMask.KEY_PRESS_MASK) self._reflect_window.connect('key_press_event', self._reflect_window.keypress_cb) self._reflect_window.set_can_focus(True) self._reflect_window.grab_focus() self.set_canvas(self._fixed) self._fixed.show() def reset_scrolled_window_adjustments(self): adj = self._scrolled_window.get_hadjustment() if adj is not None: adj.set_value(0) adj = self._scrolled_window.get_vadjustment() if adj is not None: adj.set_value(0) def load_graphics_area(self, widget): self._graphics_area.add(widget) def load_button_area(self, widget): self._button_area.add(widget) def load_overlay_area(self, widget): if self._old_overlay_widget is not None: self._overlay_area.remove(self._old_overlay_widget) self._overlay_area.add(widget) self._old_overlay_widget = widget def show_overlay_area(self): x = int((Gdk.Screen.width() - style.GRID_CELL_SIZE * 10) / 2) self._fixed.move(self._overlay_window, x, style.GRID_CELL_SIZE) def hide_overlay_area(self): self._fixed.move( self._overlay_window, 0, Gdk.Screen.height()) def _resize_hide_cb(self, widget): self._resize_canvas(widget, True) def _resize_show_cb(self, widget): self._resize_canvas(widget, False) def _configure_cb(self, event): self._fixed.set_size_request(Gdk.Screen.width(), Gdk.Screen.height()) self._set_scroll_policy() self._resize_canvas(None) self._reflect_window.reload_graphics() def _resize_canvas(self, widget, fullscreen=False): # When a toolbar is expanded or collapsed, resize the canvas if hasattr(self, '_reflect_window'): if self.toolbar_expanded(): dy1 = 3 * style.GRID_CELL_SIZE dy2 = 2 * style.GRID_CELL_SIZE else: dy1 = 2 * style.GRID_CELL_SIZE dy2 = 1 * style.GRID_CELL_SIZE if fullscreen: dy1 -= 2 * style.GRID_CELL_SIZE dy2 -= 2 * style.GRID_CELL_SIZE self._scrolled_window.set_size_request( Gdk.Screen.width(), Gdk.Screen.height() - dy2) self._fixed.move(self._button_area, 0, 0) self._about_panel_visible = False def toolbar_expanded(self): if self.activity_button.is_expanded(): return True elif self.edit_toolbar_button.is_expanded(): return True elif self.view_toolbar_button.is_expanded(): return True return False def get_activity_version(self): info_path = os.path.join(self.bundle_path, 'activity', 'activity.info') try: info_file = open(info_path, 'r') except Exception as e: _logger.error('Could not open %s: %s' % (info_path, e)) return 'unknown' cp = ConfigParser() cp.readfp(info_file) section = 'Activity' if cp.has_option(section, 'activity_version'): activity_version = cp.get(section, 'activity_version') else: activity_version = 'unknown' return activity_version def get_uid(self): if len(self.volume_data) == 1: return self.volume_data[0]['uid'] else: return 'unknown' def _setup_toolbars(self): ''' Setup the toolbars. ''' self._toolbox = ToolbarBox() self.activity_button = ActivityToolbarButton(self) self.activity_button.connect('clicked', self._resize_canvas) self._toolbox.toolbar.insert(self.activity_button, 0) self.activity_button.show() self.set_toolbar_box(self._toolbox) self._toolbox.show() self.toolbar = self._toolbox.toolbar view_toolbar = Gtk.Toolbar() self.view_toolbar_button = ToolbarButton( page=view_toolbar, label=_('View'), icon_name='toolbar-view') self.view_toolbar_button.connect('clicked', self._resize_canvas) self._toolbox.toolbar.insert(self.view_toolbar_button, 1) view_toolbar.show() self.view_toolbar_button.show() button = ToolButton('view-fullscreen') button.set_tooltip(_('Fullscreen')) button.props.accelerator = '<Alt>Return' view_toolbar.insert(button, -1) button.show() button.connect('clicked', self._fullscreen_cb) edit_toolbar = Gtk.Toolbar() self.edit_toolbar_button = ToolbarButton( page=edit_toolbar, label=_('Edit'), icon_name='toolbar-edit') self.edit_toolbar_button.connect('clicked', self._resize_canvas) self._toolbox.toolbar.insert(self.edit_toolbar_button, 1) edit_toolbar.show() self.edit_toolbar_button.show() self._copy_button = ToolButton('edit-copy') self._copy_button.set_tooltip(_('Copy')) self._copy_button.props.accelerator = '<Ctrl>C' edit_toolbar.insert(self._copy_button, -1) self._copy_button.show() self._copy_button.connect('clicked', self._copy_cb) self._copy_button.set_sensitive(False) self._paste_button = ToolButton('edit-paste') self._paste_button.set_tooltip(_('Paste')) self._paste_button.props.accelerator = '<Ctrl>V' edit_toolbar.insert(self._paste_button, -1) self._paste_button.show() self._paste_button.connect('clicked', self._paste_cb) self._paste_button.set_sensitive(False) button = ToolButton('list-add') button.set_tooltip(_('Add Item')) button.props.accelerator = '<Ctrl>+' self._toolbox.toolbar.insert(button, -1) button.show() button.connect('clicked', self.__add_item_cb) self._date_button = RadioToolButton('date-sort', group=None) self._date_button.set_tooltip(_('Sort by Date')) self._date_button.connect('clicked', self._date_button_cb) self._toolbox.toolbar.insert(self._date_button, -1) self._date_button.show() self._title_button = RadioToolButton('title-sort', group=self._date_button) self._title_button.set_tooltip(_('Sort by Title')) self._title_button.connect('clicked', self._title_button_cb) self._toolbox.toolbar.insert(self._title_button, -1) self._title_button.show() self._stars_button = RadioToolButton('stars-sort', group=self._date_button) self._stars_button.set_tooltip(_('Sort by Favourite')) self._stars_button.connect('clicked', self._stars_button_cb) self._toolbox.toolbar.insert(self._stars_button, -1) self._stars_button.show() # setup the search options self._search_entry = iconentry.IconEntry() self._search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, 'system-search') self._search_entry.connect('activate', self._search_entry_activated_cb) self._search_entry.connect('changed', self._search_entry_changed_cb) self._search_entry.add_clear_button() tool_item = Gtk.ToolItem() tool_item.set_expand(True) tool_item.add(self._search_entry) self._search_entry.show() self._toolbox.toolbar.insert(tool_item, -1) tool_item.show() self._search_button = ToolButton('dialog-ok') self._search_button.set_tooltip(_('Search by Tags')) self._search_button.connect('clicked', self._search_button_cb) self._toolbox.toolbar.insert(self._search_button, -1) self._search_button.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self._toolbox.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) stop_button.props.accelerator = '<Ctrl>q' self._toolbox.toolbar.insert(stop_button, -1) stop_button.show() def _search_button_cb(self, button): self.busy_cursor() self._do_search() def _search_entry_activated_cb(self, entry): self.busy_cursor() self._do_search() def _do_search(self): logging.debug('_search_entry_activated_cb') if self._search_entry.props.text == '': logging.debug('clearing search') for item in self.reflection_data: item['hidden'] = False else: tags = self._search_entry.props.text.split() for i, tag in enumerate(tags): if not tag[0] == '#': tags[i] = '#%s' % tag logging.error(tags) for item in self.reflection_data: hidden = True if 'tags' in item: for tag in tags: if tag in item['tags']: hidden = False item['hidden'] = hidden self.reload_data(self.reflection_data) self.reset_cursor() def _search_entry_changed_cb(self, entry): logging.debug('_search_entry_changed_cb search for \'%s\'', self._search_entry.props.text) self.busy_cursor() self._do_search_changed() def _do_search_changed(self): if self._search_entry.props.text == '': logging.debug('clearing search') for item in self.reflection_data: item['hidden'] = False self.reload_data(self.reflection_data) self.reset_cursor() def _title_button_cb(self, button): ''' sort by title ''' self.busy_cursor() GObject.idle_add(self._title_sort) def _title_sort(self): sorted_data = sorted(self.reflection_data, key=lambda item: item['title'].lower()) self.reload_data(sorted_data) self.reset_cursor() def _date_button_cb(self, button): ''' sort by modification date ''' self.busy_cursor() GObject.idle_add(self._date_sort) def _date_sort(self): sorted_data = sorted(self.reflection_data, key=lambda item: int(item['modification_time']), reverse=True) self.reload_data(sorted_data) self.reset_cursor() def _stars_button_cb(self, button): ''' sort by number of stars ''' self.busy_cursor() GObject.idle_add(self._stars_sort) def _stars_sort(self): sorted_data = sorted(self.reflection_data, key=lambda item: item['stars'], reverse=True) self.reload_data(sorted_data) self.reset_cursor() def __realize_cb(self, window): self.window_xid = window.get_window().get_xid() def set_copy_widget(self, webkit=None, text_entry=None): # Each task is responsible for setting a widget for copy if webkit is not None: self._webkit = webkit else: self._webkit = None if text_entry is not None: self._copy_entry = text_entry else: self._copy_entry = None self._copy_button.set_sensitive(webkit is not None or text_entry is not None) def _copy_cb(self, button): if self._copy_entry is not None: self._copy_entry.copy_clipboard() elif self._webkit is not None: self._webkit.copy_clipboard() else: _logger.debug('No widget set for copy.') def set_paste_widget(self, text_entry=None): # Each task is responsible for setting a widget for paste if text_entry is not None: self._paste_entry = text_entry self._paste_button.set_sensitive(text_entry is not None) def _paste_cb(self, button): clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) self.clipboard_text = clipboard.wait_for_text() if self._paste_entry is not None: self._paste_entry.paste_clipboard() else: _logger.debug('No widget set for paste (%s).' % self.clipboard_text) def _fullscreen_cb(self, button): ''' Hide the Sugar toolbars. ''' self.fullscreen() def __add_item_cb(self, button): try: chooser = ObjectChooser(parent=self, what_filter=None) except TypeError: chooser = ObjectChooser( None, self._reflection.activity, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT) try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() if jobject: self._add_new_from_journal(jobject) self.reload_data(self.reflection_data) finally: chooser.destroy() del chooser def _set_scroll_policy(self): if Gdk.Screen.width() < Gdk.Screen.height(): self._scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) else: self._scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) def _remove_alert_cb(self, alert, response_id): self.remove_alert(alert) def _close_alert_cb(self, alert, response_id): self.remove_alert(alert) if response_id is Gtk.ResponseType.OK: self.close() def _setup_presence_service(self): ''' Setup the Presence Service. ''' self.pservice = presenceservice.get_instance() owner = self.pservice.get_owner() self.owner = owner self._share = '' self.connect('shared', self._shared_cb) self.connect('joined', self._joined_cb) def _shared_cb(self, activity): ''' Either set up initial share...''' if self.shared_activity is None: _logger.error('Failed to share or join activity ... \ shared_activity is null in _shared_cb()') return self.initiating = True self._waiting_for_reflections = False _logger.debug('I am sharing...') self.conn = self.shared_activity.telepathy_conn self.tubes_chan = self.shared_activity.telepathy_tubes_chan self.text_chan = self.shared_activity.telepathy_text_chan self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( 'NewTube', self._new_tube_cb) _logger.debug('This is my activity: making a tube...') self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube( SERVICE, {}) self.sharing = True def _joined_cb(self, activity): ''' ...or join an exisiting share. ''' if self.shared_activity is None: _logger.error('Failed to share or join activity ... \ shared_activity is null in _shared_cb()') return if self._joined_alert is not None: self.remove_alert(self._joined_alert) self._joined_alert = None self.initiating = False self._waiting_for_reflections = True _logger.debug('I joined a shared activity.') self.conn = self.shared_activity.telepathy_conn self.tubes_chan = self.shared_activity.telepathy_tubes_chan self.text_chan = self.shared_activity.telepathy_text_chan self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( 'NewTube', self._new_tube_cb) _logger.debug('I am joining an activity: waiting for a tube...') self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes( reply_handler=self._list_tubes_reply_cb, error_handler=self._list_tubes_error_cb) self.sharing = True def _list_tubes_reply_cb(self, tubes): ''' Reply to a list request. ''' for tube_info in tubes: self._new_tube_cb(*tube_info) def _list_tubes_error_cb(self, e): ''' Log errors. ''' _logger.error('ListTubes() failed: %s', e) def _new_tube_cb(self, id, initiator, type, service, params, state): ''' Create a new tube. ''' _logger.debug('New tube: ID=%d initator=%d type=%d service=%s ' 'params=%r state=%d', id, initiator, type, service, params, state) if (type == telepathy.TUBE_TYPE_DBUS and service == SERVICE): if state == telepathy.TUBE_STATE_LOCAL_PENDING: self.tubes_chan[ telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id) self.collab = CollabWrapper(self) self.collab.message.connect(self.event_received_cb) self.collab.setup() if self._waiting_for_reflections: self.send_event(JOIN_CMD, {}) self._joined_alert = Alert() self._joined_alert.props.title = _('Please wait') self._joined_alert.props.msg = _('Requesting reflections...') self.add_alert(self._joined_alert) def event_received_cb(self, collab, buddy, msg): ''' Data is passed as tuples: cmd:text ''' command = msg.get("command") payload = msg.get("payload") logging.debug(command) if command == JOIN_CMD: # Sharer needs to send reflections database to joiners. if self.initiating: # Send pictures first. for item in self.reflection_data: if 'content' in item: for content in item['content']: if 'image' in content: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( content['image'], 120, 90) if pixbuf is not None: data = utils.pixbuf_to_base64(pixbuf) self.send_event(PICTURE_CMD, {"image": os.path.basename(content['image']), "data": data}) data = json.dumps(self.reflection_data) self.send_event(SHARE_CMD, {"data": data}) elif command == NEW_REFLECTION_CMD: self._reflect_window.add_new_reflection(payload) elif command == TITLE_CMD: obj_id = payload.get("obj_id") title = payload.get("title") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True self._reflect_window.update_title(obj_id, title) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == TAG_CMD: obj_id = payload.get("obj_id") data = payload.get("data") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True self._reflect_window.update_tags(obj_id, data) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == ACTIVITY_CMD: obj_id = payload.get("obj_id") bundle_id = payload.get("bundle_id") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True self._reflect_window.insert_activity(obj_id, bundle_id) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == STAR_CMD: obj_id = payload.get("obj_id") stars = payload.get("stars") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True self._reflect_window.update_stars(obj_id, int(stars)) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == COMMENT_CMD: found_the_object = False # Receive a comment and associated reflection ID obj_id = payload.get("obj_id") nick = payload.get("nick") color = payload.get("color") comment = payload.get("comment") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True if not 'comments' in item: item['comments'] = [] data = {'nick': nick, 'comment': comment, 'color': color} item['comments'].append(data) self._reflect_window.insert_comment(obj_id, data) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == REFLECTION_CMD: found_the_object = False # Receive a reflection and associated reflection ID obj_id = payload.get("obj_id") reflection = payload.get("reflection") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True if not '' in item: item['content'] = [] item['content'].append({'text': reflection}) self._reflect_window.insert_reflection(obj_id, reflection) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == IMAGE_REFLECTION_CMD: found_the_object = False # Receive a picture reflection and associated reflection ID obj_id = payload.get("obj_id") basename = payload.get("basename") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True if not '' in item: item['content'] = [] item['content'].append( {'image': os.path.join(self.tmp_path, basename)}) self._reflect_window.insert_picture( obj_id, os.path.join(self.tmp_path, basename)) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == PICTURE_CMD: # Receive a picture (MAYBE DISPLAY IT AS IT ARRIVES?) basename = payload.get("basename") data = payload.get("data") utils.base64_to_file(data, os.path.join(self.tmp_path, basename)) elif command == SHARE_CMD: # Joiner needs to load reflection database. if not self.initiating: # Note that pictures should be received. self.reflection_data = payload self._reflect_window.load(self.reflection_data) self._waiting_for_reflections = False self.reset_cursor() if self._joined_alert is not None: self.remove_alert(self._joined_alert) self._joined_alert = None def send_event(self, command, data): ''' Send event through the tube. ''' if hasattr(self, 'collab') and self.collab is not None: data["command"] = command self.collab.post(data)
class ConvertActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 self.dic = {} # Canvas self._canvas = Gtk.VBox() hbox = Gtk.HBox() self._liststore = Gtk.ListStore(str) self.combo1 = Gtk.ComboBox.new_with_model_and_entry(self._liststore) cell = Gtk.CellRendererText() self.combo1.pack_start(cell, True) self.combo1.set_entry_text_column(0) self.combo1.connect('changed', self._update_label) flip_btn = Gtk.Button() flip_btn.connect('clicked', self._flip) flip_btn.set_tooltip_text("Flip Units") flip_btn.add(Gtk.Image.new_from_file('icons/flip.svg')) self.combo2 = Gtk.ComboBox.new_with_model_and_entry(self._liststore) cell = Gtk.CellRendererText() self.combo2.pack_start(cell, True) self.combo2.set_entry_text_column(0) self.combo2.connect('changed', self._update_label) self.label_box = Gtk.HBox() self.value_entry = Gtk.Entry() self.value_entry.set_placeholder_text("Enter number") self.value_entry.connect('insert-text', self._value_insert_text) self.value_entry.connect('changed', self._update_label) self.label = Gtk.Label() self.label.set_selectable(True) self.label._size = 12 self.label.connect('draw', self.resize_label) self._canvas.pack_start(hbox, False, False, 20) hbox.pack_start(self.combo1, False, True, 20) hbox.pack_start(flip_btn, True, False, 20) hbox.pack_end(self.combo2, False, True, 20) value_box = Gtk.HBox() convert_box = Gtk.HBox() convert_box.pack_start(value_box, True, False, 0) value_box.pack_start(self.value_entry, False, False, 0) self._canvas.pack_start(convert_box, False, False, 5) self._canvas.pack_start(self.label_box, True, False, 0) self.label_box.add(self.label) self.set_canvas(self._canvas) # Toolbar toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbarbox.toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() separator.set_expand(False) separator.set_draw(True) toolbarbox.toolbar.insert(separator, -1) # RadioToolButton self._length_btn = RadioToolButton() self._length_btn.connect('clicked', lambda w: self._update_combo(convert.length)) # TRANS: https://en.wikipedia.org/wiki/Length self._length_btn.set_tooltip(_('Length')) self._length_btn.props.icon_name = 'length' self._volume_btn = RadioToolButton() self._volume_btn.connect('clicked', lambda w: self._update_combo(convert.volume)) # TRANS: https://en.wikipedia.org/wiki/Volume self._volume_btn.set_tooltip(_('Volume')) self._volume_btn.props.icon_name = 'volume' self._volume_btn.props.group = self._length_btn self._area_btn = RadioToolButton() self._area_btn.connect('clicked', lambda w: self._update_combo(convert.area)) # TRANS: https://en.wikipedia.org/wiki/Area self._area_btn.set_tooltip(_('Area')) self._area_btn.props.icon_name = 'area' self._area_btn.props.group = self._length_btn self._weight_btn = RadioToolButton() self._weight_btn.connect('clicked', lambda w: self._update_combo(convert.weight)) # TRANS: https://en.wikipedia.org/wiki/Weight self._weight_btn.set_tooltip(_('Weight')) self._weight_btn.props.icon_name = 'weight' self._weight_btn.props.group = self._length_btn self._speed_btn = RadioToolButton() self._speed_btn.connect('clicked', lambda w: self._update_combo(convert.speed)) # TRANS: https://en.wikipedia.org/wiki/Speed self._speed_btn.set_tooltip(_('Speed')) self._speed_btn.props.icon_name = 'speed' self._speed_btn.props.group = self._length_btn self._time_btn = RadioToolButton() self._time_btn.connect('clicked', lambda w: self._update_combo(convert.time)) # TRANS: https://en.wikipedia.org/wiki/Time self._time_btn.set_tooltip(_('Time')) self._time_btn.props.icon_name = 'time' self._time_btn.props.group = self._length_btn self._temp_btn = RadioToolButton() self._temp_btn.connect('clicked', lambda w: self._update_combo(convert.temp)) # TRANS: https://en.wikipedia.org/wiki/Temperature self._temp_btn.set_tooltip(_('Temperature')) self._temp_btn.props.icon_name = 'temp' self._temp_btn.props.group = self._length_btn #Circle self._circle_btn = RadioToolButton() self._circle_btn.connect('clicked', lambda w: self._update_combo(convert.circle)) self._circle_btn.set_tooltip(_('Angles of Circles')) self._circle_btn.props.icon_name = 'circle' self._circle_btn.props.group = self._length_btn #pressure self._pressure_btn = RadioToolButton() self._pressure_btn.connect( 'clicked', lambda w: self._update_combo(convert.pressure)) self._pressure_btn.set_tooltip(_('Pressure')) self._pressure_btn.props.icon_name = 'pressure' self._pressure_btn.props.group = self._length_btn #force self._force_btn = RadioToolButton() self._force_btn.connect('clicked', lambda w: self._update_combo(convert.force)) self._force_btn.set_tooltip(_('Force')) self._force_btn.props.icon_name = 'force' self._force_btn.props.group = self._length_btn #energy self._energy_btn = RadioToolButton() self._energy_btn.connect('clicked', lambda w: self._update_combo(convert.energy)) self._energy_btn.set_tooltip(_('Energy')) self._energy_btn.props.icon_name = 'energy' self._energy_btn.props.group = self._length_btn #Storage self._storage_btn = RadioToolButton() self._storage_btn.connect( 'clicked', lambda w: self._update_combo(convert.storage)) self._storage_btn.set_tooltip(_('Digital Storage')) self._storage_btn.props.icon_name = 'storage' self._storage_btn.props.group = self._length_btn toolbarbox.toolbar.insert(self._length_btn, -1) toolbarbox.toolbar.insert(self._volume_btn, -1) toolbarbox.toolbar.insert(self._area_btn, -1) toolbarbox.toolbar.insert(self._weight_btn, -1) toolbarbox.toolbar.insert(self._speed_btn, -1) toolbarbox.toolbar.insert(self._time_btn, -1) toolbarbox.toolbar.insert(self._temp_btn, -1) toolbarbox.toolbar.insert(self._circle_btn, -1) toolbarbox.toolbar.insert(self._pressure_btn, -1) toolbarbox.toolbar.insert(self._force_btn, -1) toolbarbox.toolbar.insert(self._energy_btn, -1) toolbarbox.toolbar.insert(self._storage_btn, -1) separator = Gtk.SeparatorToolItem() separator.set_expand(True) separator.set_draw(False) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) self._update_combo(convert.length) self.show_all() def _update_label(self, entry): try: num_value = str(self.value_entry.get_text()) num_value = str(num_value.replace(',', '')) decimals = str(len(num_value.split('.')[-1])) fmt = '%.' + decimals + 'f' new_value = locale.format(fmt, float(num_value)) new_value = new_value.rstrip("0") if new_value[-1] == '.': new_value = new_value[0:len(new_value) - 1] convert_value = str(self.convert()) decimals = str(len(convert_value.split('.')[-1])) fmt = '%.' + decimals + 'f' new_convert = locale.format(fmt, float(convert_value)) new_convert = new_convert.rstrip("0") if new_convert[-1] == '.': new_convert = new_convert[0:len(new_convert) - 1] text = '%s ~ %s' % (new_value, new_convert) self.label.set_text(text) except ValueError: pass def _update_combo(self, data): self._liststore.clear() self.dic = data keys = self.dic.keys() keys.sort() for x in keys: self._liststore.append(['%s' % (x)]) if keys[0] == 'Cables': self.combo1.set_active(12) self.combo2.set_active(12) elif keys[0] == 'Cubic Centimeter': self.combo1.set_active(3) self.combo2.set_active(3) elif keys[0] == 'Acre': self.combo1.set_active(4) self.combo2.set_active(4) elif keys[0] == 'Carat': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Centimeters/Minute': self.combo1.set_active(9) self.combo2.set_active(9) elif keys[0] == 'Day': self.combo1.set_active(8) self.combo2.set_active(8) elif keys[0] == 'Celsius': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Degrees': self.combo1.set_active(1) self.combo2.set_active(1) elif keys[0] == 'Atmosphere (atm)': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Dyne (dyn)': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Calories (cal)': self.combo1.set_active(2) self.combo2.set_active(2) elif keys[0] == 'Bit': self.combo1.set_active(1) self.combo2.set_active(1) else: pass self.show_all() def _get_active_text(self, combobox): active = combobox.get_active() keys = self.dic.keys() keys.sort() if active < 0: active = 0 text = keys[active] if '<sup>' in text: text = text.split('<b>')[1].split('</b>')[0] return text def _flip(self, widget): value = self.label.get_text().split(' ~ ') self.value_entry.set_text(value[1]) active_combo1 = self.combo1.get_active() active_combo2 = self.combo2.get_active() self.combo1.set_active(active_combo2) self.combo2.set_active(active_combo1) def resize_label(self, widget, event): num_label = len(self.label.get_text()) try: size = str((60 * SCREEN_WIDTH / 100) / num_label) if not size == self.label._size: self.label.modify_font(Pango.FontDescription(size)) self.label._size = size except ZeroDivisionError: pass def convert(self): number = float(self.value_entry.get_text().replace(',', '')) unit = self._get_active_text(self.combo1) to_unit = self._get_active_text(self.combo2) return convert.convert(number, unit, to_unit, self.dic) def _value_insert_text(self, entry, text, length, position): for char in text: if char == "-" and self.value_entry.get_text() is "" and len( text) == 1: return False elif not re.match('[0-9,.]', char): entry.emit_stop_by_name('insert-text') return True return False
class ImageToolbar(Gtk.Toolbar): _EFFECT_RAINBOW_NAME = 'rainbow' _EFFECT_KALIDOSCOPE_NAME = 'kalidoscope' def __init__(self, activity): GObject.GObject.__init__(self) self._activity = activity self.properties = self._activity.area.tool self._object_insert = ToolButton('insert-picture') self.insert(self._object_insert, -1) self._object_insert.set_tooltip(_('Insert Image')) separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.insert(separator, -1) self.width_percent = 1. self.height_percent = 1. # FIXME: Sometimes we get the gnome icons not the sugar ones self._object_rotate_left = ToolButton('object-rotate-left-sugar') self.insert(self._object_rotate_left, -1) self._object_rotate_left.set_tooltip(_('Rotate Left')) self._object_rotate_right = ToolButton('object-rotate-right-sugar') self.insert(self._object_rotate_right, -1) self._object_rotate_right.set_tooltip(_('Rotate Right')) self._mirror_horizontal = ToolButton('mirror-horizontal') self.insert(self._mirror_horizontal, -1) self._mirror_horizontal.show() self._mirror_horizontal.set_tooltip(_('Horizontal Mirror')) self._mirror_vertical = ToolButton('mirror-vertical') self.insert(self._mirror_vertical, -1) self._mirror_vertical.show() self._mirror_vertical.set_tooltip(_('Vertical Mirror')) separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.insert(separator, -1) self._effect_grayscale = ToolButton('effect-grayscale') self.insert(self._effect_grayscale, -1) self._effect_grayscale.set_tooltip(_('Grayscale')) self._effect_rainbow = RadioToolButton('effect-rainbow') self._effect_rainbow.props.group = activity.tool_group self.insert(self._effect_rainbow, -1) self._effect_rainbow.set_tooltip(_('Rainbow')) self._effect_kalidoscope = RadioToolButton('effect-kalidoscope') self._effect_kalidoscope.props.group = activity.tool_group self.insert(self._effect_kalidoscope, -1) self._effect_kalidoscope.set_tooltip(_('Kaleidoscope')) self._invert_colors = ToolButton('invert-colors') self.insert(self._invert_colors, -1) self._invert_colors.set_tooltip(_('Invert Colors')) self._object_insert.connect('clicked', self.insertImage, activity) self._object_rotate_left.connect('clicked', self.rotate_left, activity) self._object_rotate_right.connect('clicked', self.rotate_right, activity) self._mirror_vertical.connect('clicked', self.mirror_vertical) self._mirror_horizontal.connect('clicked', self.mirror_horizontal) self._effect_grayscale.connect('clicked', self.grayscale) self._effect_rainbow.connect('clicked', self.rainbow) self._effect_kalidoscope.connect('clicked', self.kalidoscope) self._invert_colors.connect('clicked', self.invert_colors) self.show_all() def rotate_left(self, widget, activity): activity.area.rotate_left(activity.area) def rotate_right(self, widget, activity): activity.area.rotate_right(activity.area) def mirror_horizontal(self, widget): self._activity.area.mirror(widget) def mirror_vertical(self, widget): self._activity.area.mirror(widget, horizontal=False) def insertImage(self, widget, activity): try: chooser = ObjectChooser(self._activity, what_filter='Image', filter_type=FILTER_TYPE_GENERIC_MIME, show_preview=True) except: # for compatibility with older versions chooser = ObjectChooser(self._activity, what_filter='Image') try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: logging.debug('ObjectChooser: %r', chooser.get_selected_object()) jobject = chooser.get_selected_object() if jobject and jobject.file_path: self._activity.area.load_image(jobject.file_path) finally: chooser.destroy() del chooser # Make the colors be in grayscale def grayscale(self, widget): self._activity.area.grayscale(widget) # Like the brush, but change it color when painting def rainbow(self, widget): self.properties['name'] = self._EFFECT_RAINBOW_NAME self._activity.area.set_tool(self.properties) def kalidoscope(self, widget): self.properties['name'] = self._EFFECT_KALIDOSCOPE_NAME self._activity.area.set_tool(self.properties) def invert_colors(self, widget): self._activity.area.invert_colors()
class MusicpainterActivity(activity.Activity): def __init__(self, handle): self.to_read = '' self.btn_added = False activity.Activity.__init__(self, handle) self.max_participants = 1 self.connect('destroy', self._cleanup_cb) #load the sugar toolbar self.toolbar_box = ToolbarBox() self.activity_btn = ActivityToolbarButton(self) self.activity_btn.connect('clicked', self.to_detail_mode) self.new_file_btn = ToolButton('file_new') self.new_file_btn.set_tooltip('New') self.new_file_btn.connect('clicked', self.new_file) self.save_file_btn = ToolButton('file_save') self.save_file_btn.set_tooltip('Save') self.save_file_btn.connect('clicked', self.save_file) self.save_file_as_btn = ToolButton('file_save_as') self.save_file_as_btn.set_tooltip('Save As') self.save_file_as_btn.connect('clicked', self.save_file_as) self.share_file_btn = ToolButton('file_upload') self.share_file_btn.set_tooltip('Share') self.share_file_btn.connect('clicked', self.share_file) separator = Gtk.SeparatorToolItem() separator.show() toolbar = self.activity_btn.props.page self.title_box = toolbar.get_nth_item(0) self.desc_btn = toolbar.get_nth_item(1) toolbar.insert(separator, 2) toolbar.insert(self.new_file_btn, -1) toolbar.insert(self.save_file_btn, -1) toolbar.insert(self.save_file_as_btn, -1) toolbar.insert(self.share_file_btn, -1) self.toolbar_box.toolbar.insert(self.activity_btn, 0) self.toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), 1) self.home_btn = RadioToolButton() self.home_btn.set_tooltip('Home') self.home_btn.props.icon_name = 'toolbox_home' self.home_btn.props.group = self.home_btn self.home_btn.connect('clicked', self.go_home) self.toolbar_box.toolbar.insert(self.home_btn, 2) self.canvas_mode_btn = RadioToolButton() self.canvas_mode_btn.set_tooltip('Canvas') self.canvas_mode_btn.props.icon_name = 'toolbox_canvas' self.canvas_mode_btn.props.group = self.home_btn self.canvas_mode_btn.connect('clicked', self.to_canvas_mode) self.toolbar_box.toolbar.insert(self.canvas_mode_btn, 3) self.keyboard_mode_btn = RadioToolButton() self.keyboard_mode_btn.set_tooltip('Keyboard') self.keyboard_mode_btn.props.icon_name = 'toolbox_keyboard' self.keyboard_mode_btn.props.group = self.home_btn self.keyboard_mode_btn.connect('clicked', self.to_keyboard_mode) self.toolbar_box.toolbar.insert(self.keyboard_mode_btn, 4) self.configure_ins_btn = RadioToolButton() self.configure_ins_btn.set_tooltip('Select instruments') self.configure_ins_btn.props.icon_name = 'toolbox_instrument' self.configure_ins_btn.props.group = self.home_btn self.configure_ins_btn.connect('clicked', self.configure_ins) self.toolbar_box.toolbar.insert(self.configure_ins_btn, 5) self.seperator = Gtk.SeparatorToolItem() #self.toolbar_box.toolbar.insert(self.seperator, 6) self.configure_scale_btn = ToggleToolButton() self.configure_scale_btn.set_tooltip('Select scale') self.configure_scale_btn.props.icon_name = 'toolbox_scale' self.configure_scale_btn.connect('toggled', self.choose_scale) #self.toolbar_box.toolbar.insert(self.configure_scale_btn, 7) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.toolbar_box.toolbar.insert(separator, -1) stop_button = StopButton(self) stop_button.props.accelerator = '<Ctrl><Shift>Q' self.toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(self.toolbar_box) self.toolbar_box.show_all() #self.set_toolbox(toolbox) #activity_toolbar = toolbox.get_activity_toolbar() #activity_toolbar.remove(activity_toolbar.share) #activity_toolbar.share = None #activity_toolbar.keep.connect('clicked', self._keep_cb) #activity_toolbar.stop.can_focus = True #activity_toolbar.keep.can_focus = True #toolbox.show() #activity_toolbar.keep.grab_focus() self.gamename = 'Musicpainter' self.set_title("Music Painter") ## connect to the in/out events #self.connect('notify::active', self.onActive) #self.connect('focus_in_event', self._focus_in) #self.connect('focus_out_event', self._focus_out) self.musicpainter = Musicpainter.Musicpainter() presenceService = presenceservice.get_instance() xoOwner = presenceService.get_owner() # get my name self.musicpainter.initSugar(self, xoOwner.props.nick) if not (self.to_read == '' or self.uid == ''): #try: print "Read journal uid: (" + self.uid + "), filename: " + self.to_read self.musicpainter.score.read_journal(self.to_read, self.uid) #except: #print "Exception caught when reading journal." #try: print "Init view: " + self.metadata['view'] self.musicpainter.init_view(self.metadata['view']) self.init_view_sugar(self.metadata['view']) #except: #print "No initial view." else: self.musicpainter.score.new_score() # init a canvas #self.musicpainter.init_view('canvas') #self.init_view_sugar('canvas') self.musicpainter.init_view('home') self.init_view_sugar('home') #self.create_journal() #bus = dbus.SessionBus() #remote_object = bus.get_object(DS_DBUS_SERVICE, DS_DBUS_PATH) #_datastore = dbus.Interface(remote_object, DS_DBUS_INTERFACE) #_datastore.connect_to_signal('Created', self.datastore_created_cb) #_datastore.connect_to_signal('Updated', self.datastore_updated_cb) #_datastore.connect_to_signal('Deleted', self.datastore_deleted_cb) def new_file(self, widget): self.musicpainter.score.new_score() self.to_canvas_mode(widget) self.activity_btn.set_expanded(False) self.toolbar_changed(widget) def msg_box_callback(self): self.to_canvas_mode(self.w) #self.activity_btn.set_expanded(False) #self.toolbar_changed(self.w) def upload_callback(self): self.musicpainter.detail_view.show_message_box("Upload successful! ") def save_file(self, widget): if self.musicpainter.current_view != 'detail': self.to_detail_mode(widget) self.musicpainter.detail_view.set_toolbar_expanded( self.musicpainter.toolbar_expanded) if self.musicpainter.score.save_score(): self.w = widget self.musicpainter.detail_view.show_message_box("Save successful!") def save_file_as(self, widget): if self.musicpainter.current_view != 'detail': self.to_detail_mode(widget) self.musicpainter.detail_view.set_toolbar_expanded( self.musicpainter.toolbar_expanded) if self.musicpainter.score.save_score_as(): self.w = widget self.musicpainter.detail_view.show_message_box("Save successful!") def share_file(self, widget): if self.musicpainter.current_view != 'detail': self.to_detail_mode(widget) self.musicpainter.detail_view.set_toolbar_expanded( self.musicpainter.toolbar_expanded) if not self.musicpainter.score.upload_eligible(): self.w = widget self.musicpainter.detail_view.show_message_box( "Please make changes before upload. ") else: self.w = widget self.musicpainter.score.save_score() self.musicpainter.network.upload_music( self.musicpainter.score.uid + ".png") def toolbar_changed(self, widget): #print "activity.toolbar_changed()" self.musicpainter.toolbar_switch() def go_home(self, widget): self.musicpainter.go_home() self.hide_scale_btn() if self.musicpainter.toolbar_expanded: self.activity_btn.set_expanded(False) self.toolbar_changed(widget) def to_detail_mode(self, widget): if self.musicpainter.to_detail_mode_from_sugar(): self.show_scale_btn() else: self.hide_scale_btn() def to_canvas_mode(self, widget): self.musicpainter.to_canvas_view() self.show_scale_btn() if self.musicpainter.toolbar_expanded: self.activity_btn.set_expanded(False) self.toolbar_changed(widget) def to_keyboard_mode(self, widget): self.musicpainter.to_keyboard_mode() self.show_scale_btn() if self.musicpainter.toolbar_expanded: self.activity_btn.set_expanded(False) self.toolbar_changed(widget) def configure_ins(self, widget): self.musicpainter.to_instrument_view() self.hide_scale_btn() if self.musicpainter.toolbar_expanded: self.activity_btn.set_expanded(False) self.toolbar_changed(widget) def choose_scale(self, widget): self.musicpainter.choose_scale() def hide_scale_btn(self): if self.btn_added: self.seperator.set_visible(False) self.configure_scale_btn.set_visible(False) def show_scale_btn(self): if not self.btn_added: self.toolbar_box.toolbar.insert(self.seperator, 6) self.toolbar_box.toolbar.insert(self.configure_scale_btn, 7) self.toolbar_box.show_all() self.btn_added = True else: self.seperator.set_visible(True) self.configure_scale_btn.set_visible(True) def set_active_btn(self, mode): if mode == 'canvas': self.canvas_mode_btn.set_active(True) elif mode == 'keyboard': self.keyboard_mode_btn.set_active(True) elif mode == 'instruments': self.configure_ins_btn.set_active(True) def set_scale(self, flag): self.configure_scale_btn.set_active(flag) def hide_scale_btn(self): self.seperator.set_visible(False) self.configure_scale_btn.set_visible(False) def _keep_cb(self, data=None): #print "to keep()" #self.musicpainter.canvas.save_file() return def _cleanup_cb(self, data=None): return def _focus_in(self, event, data=None): return def _focus_out(self, event, data=None): return def onActive(self, widget=None, event=None): #if widget.props.active == False: # print "MusicpainterActivity.onActive: to disconnect" # self.musicpainter.deactivate() ##else: # #print "MusicpainterActivity.onActive: to re-connect" # #self.musicpainter.reactivate() return def read_file(self, file_path): #'''Read file from Sugar Journal.''' #print "read file: " + file_path + " pending" self.to_read = file_path self.uid = self.metadata['uid'] #print self.metadata.keys() return #def create_journal(self): #file_path = 'temp.mpn' #journal_entry = datastore.create() #try: #print "new entry uid after create: " + str(journal_entry.metadata['uid']) #except: #print "no uid" #journal_entry.metadata['title'] = 'create journal test' #journal_entry.file_path = file_path #self.musicpainter.score.write_journal(file_path) #datastore.write(journal_entry) #os.remove(file_path) #print "journal created" #try: #print "new entry uid: " + str(journal_entry.metadata['uid']) #except: #print "no uid" #def create_journal(self): #print 'create_journal()' #journal_entry = datastore.create() #journal_entry.metadata['activity'] = self.get_bundle_id() #journal_entry.metadata['mime_type'] = 'application/x-musicpainter' #datastore.write(journal_entry) def update_uid(self, uid): # actually, this is meant to screw up the original id #self.metadata['uid'] = uid self._jobject.object_id = uid def update_title(self, title): self.metadata['title'] = title self.title_box.entry.set_text(title) def get_description(self): try: return self.metadata['description'] except: return def write_file(self, file_path): #'''Save file on Sugar Journal. ''' print "write journal: " + file_path #print "uid = " + self.metadata['uid'] #if self._jobject.object_id == None or self.metadata['uid'] == None: #print 'no uid yet' uid = self.musicpainter.score.uid #uid = self.metadata['uid'] #else: #print "wait for uid" #return self.musicpainter.score.title = self.metadata['title'] try: self.musicpainter.score.description = self.metadata['description'] except: print "no description" self.musicpainter.score.write_journal(file_path, uid) #self.musicpainter.score.write_journal(file_path, self._jobject.object_id) self.metadata['activity'] = self.get_bundle_id() self.metadata['mime_type'] = 'activity-musicpainter' self.metadata['view'] = self.musicpainter.get_current_view() def init_view_sugar(self, view): if view == 'canvas': self.toolbar_box.toolbar.insert(self.seperator, 6) self.toolbar_box.toolbar.insert(self.configure_scale_btn, 7) self.toolbar_box.show_all() self.btn_added = True elif view == 'keyboard': self.toolbar_box.toolbar.insert(self.seperator, 6) self.toolbar_box.toolbar.insert(self.configure_scale_btn, 7) self.toolbar_box.show_all() self.btn_added = True self.set_active_btn(view)
class ReflectActivity(activity.Activity): ''' An activity for reflecting on one's work ''' def __init__(self, handle): ''' Initialize the toolbar ''' try: super(ReflectActivity, self).__init__(handle) except dbus.exceptions.DBusException as e: _logger.error(str(e)) logging.error('setting reflection data to []') self.reflection_data = [] self.connect('realize', self.__realize_cb) self.font_size = 8 self.max_participants = 4 self._setup_toolbars() color = profile.get_color() color_stroke = color.get_stroke_color() color_fill = color.get_fill_color() lighter = utils.lighter_color([color_stroke, color_fill]) darker = 1 - lighter if lighter == 0: self.bg_color = style.Color(color_stroke) self.fg_color = style.Color(color_fill) else: self.bg_color = style.Color(color_fill) self.fg_color = style.Color(color_stroke) self.modify_bg(Gtk.StateType.NORMAL, self.bg_color.get_gdk_color()) self.bundle_path = activity.get_bundle_path() self.tmp_path = os.path.join(activity.get_activity_root(), 'instance') self.sharing = False self._copy_entry = None self._paste_entry = None self._webkit = None self._clipboard_text = '' self._fixed = None self.initiating = True if self.shared_activity: # We're joining if not self.get_shared(): self.initiating = False self.busy_cursor() share_icon = Icon(icon_name='zoom-neighborhood') self._joined_alert = Alert() self._joined_alert.props.icon = share_icon self._joined_alert.props.title = _('Please wait') self._joined_alert.props.msg = _('Starting connection...') self.add_alert(self._joined_alert) # Wait for joined signal self.connect("joined", self._joined_cb) self._open_reflect_windows() self._setup_presence_service() # Joiners wait to receive data from sharer # Otherwise, load reflections from local store if not self.shared_activity: self.busy_cursor() GObject.idle_add(self._load_reflections) def read_file(self, file_path): fd = open(file_path, 'r') data = fd.read() fd.close() self.reflection_data = json.loads(data) def write_file(self, file_path): data = json.dumps(self.reflection_data) fd = open(file_path, 'w') fd.write(data) fd.close() self.metadata['font_size'] = str(self.font_size) def _load_reflections(self): self._find_starred() self._reflect_window.load(self.reflection_data) self.reset_cursor() def _found_obj_id(self, obj_id): for item in self.reflection_data: if 'obj_id' in item and item['obj_id'] == obj_id: return True return False def reload_data(self, data): ''' Reload data after sorting or searching ''' self._reflection_data = data[:] self._reflect_window.reload(self._reflection_data) self.reset_scrolled_window_adjustments() def _find_starred(self): ''' Find all the _stars in the Journal. ''' self.dsobjects, self._nobjects = datastore.find({'keep': '1'}) for dsobj in self.dsobjects: if self._found_obj_id(dsobj.object_id): continue # Already have this object -- TODO: update it self._add_new_from_journal(dsobj) def _add_new_from_journal(self, dsobj): self.reflection_data.append({ 'title': _('Untitled'), 'obj_id': dsobj.object_id }) if hasattr(dsobj, 'metadata'): if 'creation_time' in dsobj.metadata: self.reflection_data[-1]['creation_time'] = \ dsobj.metadata['creation_time'] else: self.reflection_data[-1]['creation_time'] = \ int(time.time()) if 'timestamp' in dsobj.metadata: self.reflection_data[-1]['modification_time'] = \ dsobj.metadata['timestamp'] else: self.reflection_data[-1]['modification_time'] = \ self.reflection_data[-1]['creation_time'] if 'activity' in dsobj.metadata: self.reflection_data[-1]['activities'] = \ [utils.bundle_id_to_icon(dsobj.metadata['activity'])] if 'title' in dsobj.metadata: self.reflection_data[-1]['title'] = \ dsobj.metadata['title'] if 'description' in dsobj.metadata: self.reflection_data[-1]['content'] = \ [{'text': dsobj.metadata['description']}] else: self.reflection_data[-1]['content'] = [] if 'tags' in dsobj.metadata: self.reflection_data[-1]['tags'] = [] tags = dsobj.metadata['tags'].split() for tag in tags: if tag[0] != '#': self.reflection_data[-1]['tags'].append('#' + tag) else: self.reflection_data[-1]['tags'].append(tag) if 'comments' in dsobj.metadata: try: comments = json.loads(dsobj.metadata['comments']) except BaseException: comments = [] self.reflection_data[-1]['comments'] = [] for comment in comments: try: data = { 'nick': comment['from'], 'comment': comment['message'] } if 'icon-color' in comment: colors = comment['icon-color'].split(',') darker = 1 - utils.lighter_color(colors) data['color'] = colors[darker] else: data['color'] = '#000000' self.reflection_data[-1]['comments'].append(data) except BaseException: _logger.debug('could not parse comment %s' % comment) if 'mime_type' in dsobj.metadata and \ dsobj.metadata['mime_type'][0:5] == 'image': new_path = os.path.join(self.tmp_path, dsobj.object_id) try: shutil.copy(dsobj.file_path, new_path) except Exception as e: logging.error("Couldn't copy %s to %s: %s" % (dsobj.file_path, new_path, e)) self.reflection_data[-1]['content'].append({'image': new_path}) elif 'preview' in dsobj.metadata: pixbuf = utils.get_pixbuf_from_journal(dsobj, 300, 225) if pixbuf is not None: path = os.path.join(self.tmp_path, dsobj.object_id + '.png') utils.save_pixbuf_to_file(pixbuf, path) self.reflection_data[-1]['content'].append({'image': path}) self.reflection_data[-1]['stars'] = 0 def delete_item(self, obj_id): for i, obj in enumerate(self.reflection_data): if obj['obj_id'] == obj_id: self.reflection_data.remove(self.reflection_data[i]) return def busy_cursor(self): self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) def reset_cursor(self): self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)) def _open_reflect_windows(self): # Most things need only be done once if self._fixed is None: self._fixed = Gtk.Fixed() self._fixed.set_size_request(Gdk.Screen.width(), Gdk.Screen.height()) # Offsets from the bottom of the screen dy1 = 2 * style.GRID_CELL_SIZE dy2 = 1 * style.GRID_CELL_SIZE self._button_area = Gtk.Alignment.new(0.5, 0, 0, 0) self._button_area.set_size_request(Gdk.Screen.width(), style.GRID_CELL_SIZE) self._fixed.put(self._button_area, 0, 0) self._button_area.show() self._scrolled_window = Gtk.ScrolledWindow() self._scrolled_window.set_size_request(Gdk.Screen.width(), Gdk.Screen.height() - dy1) self._set_scroll_policy() self._graphics_area = Gtk.Alignment.new(0.5, 0, 0, 0) self._scrolled_window.add_with_viewport(self._graphics_area) self._graphics_area.show() self._fixed.put(self._scrolled_window, 0, dy2) self._scrolled_window.show() self._overlay_window = Gtk.ScrolledWindow() self._overlay_window.set_size_request(style.GRID_CELL_SIZE * 10, style.GRID_CELL_SIZE * 6) self._overlay_window.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color()) self._overlay_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self._overlay_area = Gtk.Alignment.new(0.5, 0, 0, 0) self._overlay_window.add_with_viewport(self._overlay_area) self._overlay_area.show() x = int((Gdk.Screen.width() - style.GRID_CELL_SIZE * 10) / 2) self._fixed.put(self._overlay_window, 0, Gdk.Screen.height()) self._overlay_window.show() self._old_overlay_widget = None self._reflect_window = ReflectWindow(self) self._reflect_window.show() Gdk.Screen.get_default().connect('size-changed', self._configure_cb) self._toolbox.connect('hide', self._resize_hide_cb) self._toolbox.connect('show', self._resize_show_cb) self._reflect_window.set_events(Gdk.EventMask.KEY_PRESS_MASK) self._reflect_window.connect('key_press_event', self._reflect_window.keypress_cb) self._reflect_window.set_can_focus(True) self._reflect_window.grab_focus() self.set_canvas(self._fixed) self._fixed.show() def reset_scrolled_window_adjustments(self): adj = self._scrolled_window.get_hadjustment() if adj is not None: adj.set_value(0) adj = self._scrolled_window.get_vadjustment() if adj is not None: adj.set_value(0) def load_graphics_area(self, widget): self._graphics_area.add(widget) def load_button_area(self, widget): self._button_area.add(widget) def load_overlay_area(self, widget): if self._old_overlay_widget is not None: self._overlay_area.remove(self._old_overlay_widget) self._overlay_area.add(widget) self._old_overlay_widget = widget def show_overlay_area(self): x = int((Gdk.Screen.width() - style.GRID_CELL_SIZE * 10) / 2) self._fixed.move(self._overlay_window, x, style.GRID_CELL_SIZE) def hide_overlay_area(self): self._fixed.move(self._overlay_window, 0, Gdk.Screen.height()) def collapse_overlay_area(self, button, event): self._fixed.move(self._overlay_window, 0, Gdk.Screen.height()) def _resize_hide_cb(self, widget): self._resize_canvas(widget, True) def _resize_show_cb(self, widget): self._resize_canvas(widget, False) def _configure_cb(self, event): self._fixed.set_size_request(Gdk.Screen.width(), Gdk.Screen.height()) self._set_scroll_policy() self._resize_canvas(None) self._reflect_window.reload_graphics() def _resize_canvas(self, widget, fullscreen=False): # When a toolbar is expanded or collapsed, resize the canvas if hasattr(self, '_reflect_window'): if self.toolbar_expanded(): dy1 = 3 * style.GRID_CELL_SIZE dy2 = 2 * style.GRID_CELL_SIZE else: dy1 = 2 * style.GRID_CELL_SIZE dy2 = 1 * style.GRID_CELL_SIZE if fullscreen: dy1 -= 2 * style.GRID_CELL_SIZE dy2 -= 2 * style.GRID_CELL_SIZE self._scrolled_window.set_size_request(Gdk.Screen.width(), Gdk.Screen.height() - dy2) self._fixed.move(self._button_area, 0, 0) self._about_panel_visible = False def toolbar_expanded(self): if self.activity_button.is_expanded(): return True elif self.edit_toolbar_button.is_expanded(): return True elif self.view_toolbar_button.is_expanded(): return True return False def get_activity_version(self): info_path = os.path.join(self.bundle_path, 'activity', 'activity.info') try: info_file = open(info_path, 'r') except Exception as e: _logger.error('Could not open %s: %s' % (info_path, e)) return 'unknown' cp = ConfigParser() cp.readfp(info_file) section = 'Activity' if cp.has_option(section, 'activity_version'): activity_version = cp.get(section, 'activity_version') else: activity_version = 'unknown' return activity_version def get_uid(self): if len(self.volume_data) == 1: return self.volume_data[0]['uid'] else: return 'unknown' def _setup_toolbars(self): ''' Setup the toolbars. ''' self._toolbox = ToolbarBox() self.activity_button = ActivityToolbarButton(self) self.activity_button.connect('clicked', self._resize_canvas) self._toolbox.toolbar.insert(self.activity_button, 0) self.activity_button.show() self.set_toolbar_box(self._toolbox) self._toolbox.show() self.toolbar = self._toolbox.toolbar view_toolbar = Gtk.Toolbar() self.view_toolbar_button = ToolbarButton(page=view_toolbar, label=_('View'), icon_name='toolbar-view') self.view_toolbar_button.connect('clicked', self._resize_canvas) self._toolbox.toolbar.insert(self.view_toolbar_button, 1) view_toolbar.show() self.view_toolbar_button.show() button = ToolButton('view-fullscreen') button.set_tooltip(_('Fullscreen')) button.props.accelerator = '<Alt>Return' view_toolbar.insert(button, -1) button.show() button.connect('clicked', self._fullscreen_cb) edit_toolbar = Gtk.Toolbar() self.edit_toolbar_button = ToolbarButton(page=edit_toolbar, label=_('Edit'), icon_name='toolbar-edit') self.edit_toolbar_button.connect('clicked', self._resize_canvas) self._toolbox.toolbar.insert(self.edit_toolbar_button, 1) edit_toolbar.show() self.edit_toolbar_button.show() self._copy_button = ToolButton('edit-copy') self._copy_button.set_tooltip(_('Copy')) self._copy_button.props.accelerator = '<Ctrl>C' edit_toolbar.insert(self._copy_button, -1) self._copy_button.show() self._copy_button.connect('clicked', self._copy_cb) self._copy_button.set_sensitive(False) self._paste_button = ToolButton('edit-paste') self._paste_button.set_tooltip(_('Paste')) self._paste_button.props.accelerator = '<Ctrl>V' edit_toolbar.insert(self._paste_button, -1) self._paste_button.show() self._paste_button.connect('clicked', self._paste_cb) self._paste_button.set_sensitive(False) button = ToolButton('list-add') button.set_tooltip(_('Add Item')) button.props.accelerator = '<Ctrl>+' self._toolbox.toolbar.insert(button, -1) button.show() button.connect('clicked', self.__add_item_cb) self._date_button = RadioToolButton('date-sort', group=None) self._date_button.set_tooltip(_('Sort by Date')) self._date_button.connect('clicked', self._date_button_cb) self._toolbox.toolbar.insert(self._date_button, -1) self._date_button.show() self._title_button = RadioToolButton('title-sort', group=self._date_button) self._title_button.set_tooltip(_('Sort by Title')) self._title_button.connect('clicked', self._title_button_cb) self._toolbox.toolbar.insert(self._title_button, -1) self._title_button.show() self._stars_button = RadioToolButton('stars-sort', group=self._date_button) self._stars_button.set_tooltip(_('Sort by Favourite')) self._stars_button.connect('clicked', self._stars_button_cb) self._toolbox.toolbar.insert(self._stars_button, -1) self._stars_button.show() # setup the search options self._search_entry = iconentry.IconEntry() self._search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, 'system-search') self._search_entry.connect('activate', self._search_entry_activated_cb) self._search_entry.connect('changed', self._search_entry_changed_cb) self._search_entry.add_clear_button() tool_item = Gtk.ToolItem() tool_item.set_expand(True) tool_item.add(self._search_entry) self._search_entry.show() self._toolbox.toolbar.insert(tool_item, -1) tool_item.show() self._search_button = ToolButton('dialog-ok') self._search_button.set_tooltip(_('Search by Tags')) self._search_button.connect('clicked', self._search_button_cb) self._toolbox.toolbar.insert(self._search_button, -1) self._search_button.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self._toolbox.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) stop_button.props.accelerator = '<Ctrl>q' self._toolbox.toolbar.insert(stop_button, -1) stop_button.show() def _search_button_cb(self, button): self.busy_cursor() self._do_search() def _search_entry_activated_cb(self, entry): self.busy_cursor() self._do_search() def _do_search(self): logging.debug('_search_entry_activated_cb') if self._search_entry.props.text == '': logging.debug('clearing search') for item in self.reflection_data: item['hidden'] = False else: tags = self._search_entry.props.text.split() for i, tag in enumerate(tags): if not tag[0] == '#': tags[i] = '#%s' % tag logging.error(tags) for item in self.reflection_data: hidden = True if 'tags' in item: for tag in tags: if tag in item['tags']: hidden = False item['hidden'] = hidden self.reload_data(self.reflection_data) self.reset_cursor() def _search_entry_changed_cb(self, entry): logging.debug('_search_entry_changed_cb search for \'%s\'', self._search_entry.props.text) self.busy_cursor() self._do_search_changed() def _do_search_changed(self): if self._search_entry.props.text == '': logging.debug('clearing search') for item in self.reflection_data: item['hidden'] = False self.reload_data(self.reflection_data) self.reset_cursor() def _title_button_cb(self, button): ''' sort by title ''' self.busy_cursor() GObject.idle_add(self._title_sort) def _title_sort(self): sorted_data = sorted(self.reflection_data, key=lambda item: item['title'].lower()) self.reload_data(sorted_data) self.reset_cursor() def _date_button_cb(self, button): ''' sort by modification date ''' self.busy_cursor() GObject.idle_add(self._date_sort) def _date_sort(self): sorted_data = sorted(self.reflection_data, key=lambda item: int(item['modification_time']), reverse=True) self.reload_data(sorted_data) self.reset_cursor() def _stars_button_cb(self, button): ''' sort by number of stars ''' self.busy_cursor() GObject.idle_add(self._stars_sort) def _stars_sort(self): sorted_data = sorted(self.reflection_data, key=lambda item: item['stars'], reverse=True) self.reload_data(sorted_data) self.reset_cursor() def __realize_cb(self, window): self.window_xid = window.get_window().get_xid() def set_copy_widget(self, webkit=None, text_entry=None): # Each task is responsible for setting a widget for copy if webkit is not None: self._webkit = webkit else: self._webkit = None if text_entry is not None: self._copy_entry = text_entry else: self._copy_entry = None self._copy_button.set_sensitive(webkit is not None or text_entry is not None) def _copy_cb(self, button): if self._copy_entry is not None: self._copy_entry.copy_clipboard() elif self._webkit is not None: self._webkit.copy_clipboard() else: _logger.debug('No widget set for copy.') def set_paste_widget(self, text_entry=None): # Each task is responsible for setting a widget for paste if text_entry is not None: self._paste_entry = text_entry self._paste_button.set_sensitive(text_entry is not None) def _paste_cb(self, button): clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) self.clipboard_text = clipboard.wait_for_text() if self._paste_entry is not None: self._paste_entry.paste_clipboard() else: _logger.debug('No widget set for paste (%s).' % self.clipboard_text) def _fullscreen_cb(self, button): ''' Hide the Sugar toolbars. ''' self.fullscreen() def __add_item_cb(self, button): try: chooser = ObjectChooser(parent=self, what_filter=None) except TypeError: chooser = ObjectChooser( None, self._reflection.activity, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT) try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() if jobject: self._add_new_from_journal(jobject) self.reload_data(self.reflection_data) finally: chooser.destroy() del chooser def _set_scroll_policy(self): if Gdk.Screen.width() < Gdk.Screen.height(): self._scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) else: self._scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) def _remove_alert_cb(self, alert, response_id): self.remove_alert(alert) def _close_alert_cb(self, alert, response_id): self.remove_alert(alert) if response_id is Gtk.ResponseType.OK: self.close() def _setup_presence_service(self): ''' Setup the Presence Service. ''' self.pservice = presenceservice.get_instance() owner = self.pservice.get_owner() self.owner = owner self._share = '' self.connect('shared', self._shared_cb) self.connect('joined', self._joined_cb) def _shared_cb(self, activity): ''' Either set up initial share...''' if self.shared_activity is None: _logger.error('Failed to share or join activity ... \ shared_activity is null in _shared_cb()') return self.initiating = True self._waiting_for_reflections = False _logger.debug('I am sharing...') self.conn = self.shared_activity.telepathy_conn self.tubes_chan = self.shared_activity.telepathy_tubes_chan self.text_chan = self.shared_activity.telepathy_text_chan self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( 'NewTube', self._new_tube_cb) _logger.debug('This is my activity: making a tube...') self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube( SERVICE, {}) self.sharing = True def _joined_cb(self, activity): ''' ...or join an exisiting share. ''' if self.shared_activity is None: _logger.error('Failed to share or join activity ... \ shared_activity is null in _shared_cb()') return if self._joined_alert is not None: self.remove_alert(self._joined_alert) self._joined_alert = None self.initiating = False self._waiting_for_reflections = True _logger.debug('I joined a shared activity.') self.conn = self.shared_activity.telepathy_conn self.tubes_chan = self.shared_activity.telepathy_tubes_chan self.text_chan = self.shared_activity.telepathy_text_chan self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( 'NewTube', self._new_tube_cb) _logger.debug('I am joining an activity: waiting for a tube...') self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes( reply_handler=self._list_tubes_reply_cb, error_handler=self._list_tubes_error_cb) self.sharing = True def _list_tubes_reply_cb(self, tubes): ''' Reply to a list request. ''' for tube_info in tubes: self._new_tube_cb(*tube_info) def _list_tubes_error_cb(self, e): ''' Log errors. ''' _logger.error('ListTubes() failed: %s', e) def _new_tube_cb(self, id, initiator, type, service, params, state): ''' Create a new tube. ''' _logger.debug( 'New tube: ID=%d initator=%d type=%d service=%s ' 'params=%r state=%d', id, initiator, type, service, params, state) if (type == telepathy.TUBE_TYPE_DBUS and service == SERVICE): if state == telepathy.TUBE_STATE_LOCAL_PENDING: self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube( id) self.collab = CollabWrapper(self) self.collab.message.connect(self.event_received_cb) self.collab.setup() if self._waiting_for_reflections: self.send_event(JOIN_CMD, {}) self._joined_alert = Alert() self._joined_alert.props.title = _('Please wait') self._joined_alert.props.msg = _('Requesting reflections...') self.add_alert(self._joined_alert) def event_received_cb(self, collab, buddy, msg): ''' Data is passed as tuples: cmd:text ''' command = msg.get("command") payload = msg.get("payload") logging.debug(command) if command == JOIN_CMD: # Sharer needs to send reflections database to joiners. if self.initiating: # Send pictures first. for item in self.reflection_data: if 'content' in item: for content in item['content']: if 'image' in content: pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( content['image'], 120, 90) if pixbuf is not None: data = utils.pixbuf_to_base64(pixbuf) self.send_event( PICTURE_CMD, { "image": os.path.basename( content['image']), "data": data }) data = json.dumps(self.reflection_data) self.send_event(SHARE_CMD, {"data": data}) elif command == NEW_REFLECTION_CMD: self._reflect_window.add_new_reflection(payload) elif command == TITLE_CMD: obj_id = payload.get("obj_id") title = payload.get("title") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True self._reflect_window.update_title(obj_id, title) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == TAG_CMD: obj_id = payload.get("obj_id") data = payload.get("data") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True self._reflect_window.update_tags(obj_id, data) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == ACTIVITY_CMD: obj_id = payload.get("obj_id") bundle_id = payload.get("bundle_id") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True self._reflect_window.insert_activity(obj_id, bundle_id) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == STAR_CMD: obj_id = payload.get("obj_id") stars = payload.get("stars") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True self._reflect_window.update_stars(obj_id, int(stars)) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == COMMENT_CMD: found_the_object = False # Receive a comment and associated reflection ID obj_id = payload.get("obj_id") nick = payload.get("nick") color = payload.get("color") comment = payload.get("comment") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True if 'comments' not in item: item['comments'] = [] data = {'nick': nick, 'comment': comment, 'color': color} item['comments'].append(data) self._reflect_window.insert_comment(obj_id, data) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == REFLECTION_CMD: found_the_object = False # Receive a reflection and associated reflection ID obj_id = payload.get("obj_id") reflection = payload.get("reflection") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True if '' not in item: item['content'] = [] item['content'].append({'text': reflection}) self._reflect_window.insert_reflection(obj_id, reflection) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == IMAGE_REFLECTION_CMD: found_the_object = False # Receive a picture reflection and associated reflection ID obj_id = payload.get("obj_id") basename = payload.get("basename") for item in self.reflection_data: if item['obj_id'] == obj_id: found_the_object = True if '' not in item: item['content'] = [] item['content'].append( {'image': os.path.join(self.tmp_path, basename)}) self._reflect_window.insert_picture( obj_id, os.path.join(self.tmp_path, basename)) break if not found_the_object: logging.error('Could not find obj_id %s' % obj_id) elif command == PICTURE_CMD: # Receive a picture (MAYBE DISPLAY IT AS IT ARRIVES?) basename = payload.get("basename") data = payload.get("data") utils.base64_to_file(data, os.path.join(self.tmp_path, basename)) elif command == SHARE_CMD: # Joiner needs to load reflection database. if not self.initiating: # Note that pictures should be received. self.reflection_data = payload self._reflect_window.load(self.reflection_data) self._waiting_for_reflections = False self.reset_cursor() if self._joined_alert is not None: self.remove_alert(self._joined_alert) self._joined_alert = None def send_event(self, command, data): ''' Send event through the tube. ''' if hasattr(self, 'collab') and self.collab is not None: data["command"] = command self.collab.post(data)
def build_toolbox(self): self.newcreditbtn = ToolButton('row-insert-credit') self.newcreditbtn.set_tooltip(_("New Credit")) self.newcreditbtn.props.accelerator = '<Ctrl>A' self.newcreditbtn.connect('clicked', self.register.newcredit_cb) self.newdebitbtn = ToolButton('row-insert-debit') self.newdebitbtn.set_tooltip(_("New Debit")) self.newdebitbtn.props.accelerator = '<Ctrl>D' self.newdebitbtn.connect('clicked', self.register.newdebit_cb) self.eraseitembtn = ToolButton('row-remove-transaction') self.eraseitembtn.set_tooltip(_("Erase Transaction")) self.eraseitembtn.props.accelerator = '<Ctrl>E' self.eraseitembtn.connect('clicked', self.register.eraseitem_cb) transactionbar = Gtk.Toolbar() transactionbar.insert(self.newcreditbtn, -1) transactionbar.insert(self.newdebitbtn, -1) transactionbar.insert(self.eraseitembtn, -1) self.thisperiodbtn = ToolButton('go-down') self.thisperiodbtn.props.accelerator = '<Ctrl>Down' self.thisperiodbtn.connect('clicked', self.thisperiod_cb) self.prevperiodbtn = ToolButton('go-previous-paired') self.prevperiodbtn.props.accelerator = '<Ctrl>Left' self.prevperiodbtn.connect('clicked', self.prevperiod_cb) self.nextperiodbtn = ToolButton('go-next-paired') self.nextperiodbtn.props.accelerator = '<Ctrl>Right' self.nextperiodbtn.connect('clicked', self.nextperiod_cb) periodsep = Gtk.SeparatorToolItem() periodsep.set_expand(True) periodsep.set_draw(False) periodlabel = Gtk.Label(label=_('Period: ')) periodlabelitem = Gtk.ToolItem() periodlabelitem.add(periodlabel) periodcombo = Gtk.ComboBoxText() periodcombo.append_text(_('Day')) periodcombo.append_text(_('Week')) periodcombo.append_text(_('Month')) periodcombo.append_text(_('Year')) periodcombo.append_text(_('Forever')) periodcombo.set_active(2) periodcombo.connect('changed', self.period_changed_cb) perioditem = ToolComboBox(periodcombo) view_tool_group = None registerbtn = RadioToolButton() registerbtn.props.icon_name = 'view-list' registerbtn.props.label = _('Register') registerbtn.set_tooltip(_("Register")) registerbtn.props.group = view_tool_group view_tool_group = registerbtn registerbtn.props.accelerator = '<Ctrl>1' registerbtn.connect('clicked', self.register_cb) budgetbtn = RadioToolButton() budgetbtn.props.icon_name = 'budget' budgetbtn.props.label = _('Budget') budgetbtn.set_tooltip(_("Budget")) budgetbtn.props.group = view_tool_group budgetbtn.props.accelerator = '<Ctrl>2' budgetbtn.connect('clicked', self.budget_cb) chartbtn = RadioToolButton() chartbtn.props.icon_name = 'chart' chartbtn.props.label = _('Chart') chartbtn.set_tooltip(_("Chart")) chartbtn.props.group = view_tool_group chartbtn.props.accelerator = '<Ctrl>3' chartbtn.connect('clicked', self.chart_cb) viewbar = Gtk.Toolbar() viewbar.insert(registerbtn, -1) viewbar.insert(budgetbtn, -1) viewbar.insert(chartbtn, -1) helpbtn = ToggleToolButton('help') helpbtn.set_active(True) helpbtn.set_tooltip(_("Show Help")) helpbtn.connect('clicked', self.help_cb) self.toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) self.toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() transaction_toolbar_button = ToolbarButton(page=transactionbar, icon_name='transaction') transactionbar.show_all() view_toolbar_button = ToolbarButton(page=viewbar, icon_name='toolbar-view') viewbar.show_all() self.toolbar_box.toolbar.insert(transaction_toolbar_button, -1) transaction_toolbar_button.show() self.toolbar_box.toolbar.view = view_toolbar_button self.toolbar_box.toolbar.insert(view_toolbar_button, -1) view_toolbar_button.show() separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.toolbar_box.toolbar.insert(separator, -1) self.toolbar_box.toolbar.insert(periodlabelitem, -1) self.toolbar_box.toolbar.insert(perioditem, -1) self.toolbar_box.toolbar.insert(self.prevperiodbtn, -1) self.toolbar_box.toolbar.insert(self.nextperiodbtn, -1) self.toolbar_box.toolbar.insert(self.thisperiodbtn, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.toolbar_box.toolbar.insert(separator, -1) self.toolbar_box.toolbar.insert(helpbtn, -1) self.toolbar_box.toolbar.insert(StopButton(self), -1) self.set_toolbar_box(self.toolbar_box) self.toolbar_box.show_all()
def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 self.units = {} self._liststore = Gtk.ListStore(str) self.label1 = Gtk.Label() self.label1.set_markup('<big>From value</big>') self.label2 = Gtk.Label() self.label2.set_markup('<big>From unit</big>') self.label3 = Gtk.Label() self.label3.set_markup('<big>To value</big>') self.label4 = Gtk.Label() self.label4.set_markup('<big>To unit</big>') u_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) u_hbox.pack_start(self.label1, True, True, 5) u_hbox.pack_start(self.label2, True, True, 20) u_hbox.pack_start(self.label3, True, True, 20) u_hbox.pack_start(self.label4, True, True, 5) arrow_font = Pango.FontDescription( '%s %d' % (FONT_FACE, int(FONT_SIZE * 1.8))) input_font = Pango.FontDescription( '%s %d' % (FONT_FACE, int(FONT_SIZE * 1.2))) self.from_value = Gtk.Entry() self.from_value.set_placeholder_text("Enter value") self.from_value.connect('insert-text', self._insert_text_cb) self.from_value.connect('changed', self._from_changed_cb) self.from_value.override_font(input_font) self.from_unit = Gtk.ComboBox.new_with_model_and_entry(self._liststore) self.from_unit.pack_start(Gtk.CellRendererText(), True) self.from_unit.set_entry_text_column(0) self.from_unit.set_id_column(0) self.from_unit.connect('changed', self._from_changed_cb) self.from_unit.override_font(input_font) self.arrow = Gtk.Label() self.arrow.override_font(arrow_font) self.arrow.set_text("→") self.to_value = Gtk.Entry() self.to_value.connect('insert-text', self._insert_text_cb) self.to_value.connect('changed', self._to_changed_cb) self.to_value.override_font(input_font) self.to_unit = Gtk.ComboBox.new_with_model_and_entry(self._liststore) self.to_unit.pack_start(Gtk.CellRendererText(), True) self.to_unit.set_entry_text_column(0) self.to_unit.set_id_column(0) self.to_unit.connect('changed', self._to_changed_cb) self.to_unit.override_font(input_font) l_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) l_hbox.pack_start(self.from_value, True, True, 5) l_hbox.pack_start(self.from_unit, True, True, 5) l_hbox.pack_start(self.arrow, False, False, 15) l_hbox.pack_start(self.to_value, True, True, 5) l_hbox.pack_end(self.to_unit, True, True, 5) self.ratio = Ratio() box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) box.pack_start(u_hbox, False, False, 30) box.pack_start(l_hbox, False, False, 0) box.pack_start(self.ratio, True, False, 0) self.set_canvas(box) # Toolbar toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbarbox.toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() separator.set_expand(False) separator.set_draw(True) toolbarbox.toolbar.insert(separator, -1) self.dimensions = {} for name in convert.dimensions: button = RadioToolButton() button.set_tooltip(convert.dimension_tooltips[name]) button.props.icon_name = name if len(self.dimensions) > 0: button.props.group = self.dimensions['length'] button.connect('clicked', self.set_dimension, name) toolbarbox.toolbar.insert(button, -1) self.dimensions[name] = button separator = Gtk.SeparatorToolItem() separator.set_expand(True) separator.set_draw(False) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) self.set_dimension(None, 'length') self.show_all()
def __init__(self, handle): """Set up the Develop activity.""" self._dirty = False super(DevelopActivity, self).__init__(handle) self.max_participants = 1 self.current_theme = "light" logging.info(repr(handle.get_dict())) # Source buffer self.editor = sourceview_editor.GtkSourceview2Editor() self.editor.connect('tab-changed', self.__editor_tab_changed_cb) self.editor.connect('changed', self.__editor_changed_cb) # Show tabs after Welcome Page self.editor.set_show_tabs(False) toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbarbox.toolbar.insert(activity_button, 0) self.set_toolbar_box(toolbarbox) view_btn = ToolbarButton() view_toolbar = DevelopViewToolbar(self) view_btn.props.page = view_toolbar view_btn.props.icon_name = 'toolbar-view' view_btn.props.label = _('View') view_toolbar.connect('theme-changed', self.editor.theme_changed_cb) view_toolbar.connect('font-size-changed', self.editor.font_changed_cb) toolbarbox.toolbar.insert(view_btn, -1) self.view_toolbar = view_toolbar edit_btn = ToolbarButton() edit_btn.props.page = DevelopEditToolbar(self) edit_btn.props.icon_name = 'toolbar-edit' edit_btn.props.label = _('Edit') toolbarbox.toolbar.insert(edit_btn, -1) search_btn = ToolbarButton() search_btn.props.page = DevelopSearchToolbar(self) search_btn.props.icon_name = 'search' search_btn.props.label = _('Search') toolbarbox.toolbar.insert(search_btn, -1) toolbarbox.toolbar.insert(Gtk.SeparatorToolItem(), -1) show_files_btn = RadioToolButton() show_files_btn.props.icon_name = 'sources' show_files_btn.props.group = show_files_btn show_files_btn.set_active(True) show_files_btn.set_tooltip(_('Show source files')) toolbarbox.toolbar.insert(show_files_btn, -1) show_files_btn.connect('clicked', self._change_treenotebook_page, 0) show_symbols_btn = RadioToolButton() show_symbols_btn.props.icon_name = 'symbols' show_symbols_btn.props.group = show_files_btn show_symbols_btn.set_active(False) show_symbols_btn.set_tooltip(_('Show file symbols')) toolbarbox.toolbar.insert(show_symbols_btn, -1) show_symbols_btn.connect('clicked', self._explore_code) show_log_btn = RadioToolButton() show_log_btn.props.icon_name = 'logs' show_log_btn.props.group = show_files_btn show_log_btn.set_active(False) show_log_btn.set_tooltip(_('Show log files')) toolbarbox.toolbar.insert(show_log_btn, -1) show_log_btn.connect('clicked', self._change_treenotebook_page, 2) toolbarbox.toolbar.insert(Gtk.SeparatorToolItem(), -1) create_file_btn = ToolButton('text-x-generic') create_file_btn.set_tooltip(_('Create empty file')) toolbarbox.toolbar.insert(create_file_btn, -1) create_file_btn.show() create_file_btn.connect('clicked', self.__create_empty_file_cb) erase_btn = ToolButton('erase') erase_btn.set_tooltip(_('Remove file')) toolbarbox.toolbar.insert(erase_btn, -1) erase_btn.show() erase_btn.connect('clicked', self.__remove_file_cb) toolbarbox.toolbar.insert(Gtk.SeparatorToolItem(), -1) run_btn = ToolButton('activity-start') run_btn.set_tooltip(_('Run activity')) toolbarbox.toolbar.insert(run_btn, -1) run_btn.connect('clicked', self.__run_actvity_cb) separator = Gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) save_bundle_btn = ToolButton('save-as-bundle') save_bundle_btn.set_tooltip(_('Create bundle (.xo file)')) activity_button.get_page().insert(save_bundle_btn, -1) save_bundle_btn.connect('clicked', self.save_bundle) save_bundle_btn.show() toolbarbox.show_all() # Main layout. hbox = Gtk.HPaned() # The treeview and selected pane reflect each other. self.numb = False # Wait to save until first change, but save an unchanged # backup copy when that happens. self.save_unchanged = False # The sidebar sidebar = Gtk.VBox() self.treenotebook = notebook.Notebook(can_close_tabs=False) self.treenotebook.set_show_tabs(False) sidebar.pack_start(self.treenotebook, True, True, 0) self.activity_tree_view = FileViewer() self.treenotebook.add_page(_("Activity"), self.activity_tree_view) self.treenotebook.set_size_request(Gdk.Screen.width() / 5, -1) # Symbols tree self._symbolstree = SymbolsTree() self._symbolstree.connect('symbol-selected', self.editor.symbol_selected_cb) scrolled = Gtk.ScrolledWindow() scrolled.add(self._symbolstree) scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.treenotebook.add_page(_('Symbols Tree'), scrolled) hbox.pack1(sidebar, resize=True, shrink=False) # Show sidebar after welcome page ends # sidebar.show() self.sidebar = sidebar logging.info('finished check') self.editor.show() hbox.pack2(self.editor, resize=True, shrink=True) self.set_canvas(hbox) hbox.show() logging.critical('finished initialization') self.activity_dir = None self.show() if not handle.object_id or not self.metadata.get('source'): GObject.timeout_add(10, self._show_welcome)
def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 # CHART_OPTIONS self._font_option = TITLE_FONT self.x_label = '' self.y_label = '' self.chart_color = utils.get_user_fill_color('str') self.chart_line_color = utils.get_user_stroke_color('str') self.current_chart = None self.charts_area = None self.chart_data = [] self.chart_type_buttons = [] self._font_options = { 'titleColor': '#000000', 'titleFont': 'Sans', 'titleFontSize': 12, 'axis': { 'tickFont': 'Sans', 'tickFontSize': 12, 'tickColor': '#000000', 'labelFontSize': 14, 'labelColor': '#666666', 'labelFont': 'Sans', 'lineColor': '#b3b3b3'}} # TOOLBARS self._labels_font = RadioToolButton() self._title_font = RadioToolButton() toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_btn_toolbar = activity_button.page activity_btn_toolbar.title.connect('changed', self._set_chart_title) save_as_image = ToolButton('save-as-image') save_as_image.connect('clicked', self._save_as_image) save_as_image.set_tooltip(_('Save as image')) activity_btn_toolbar.insert(save_as_image, -1) save_as_image.show() import_stopwatch = ToolButton('import-stopwatch') import_stopwatch.connect('clicked', self.__import_stopwatch_cb) import_stopwatch.set_tooltip(_('Read StopWatch data')) activity_btn_toolbar.insert(import_stopwatch, -1) import_stopwatch.show() import_measure = ToolButton('import-measure') import_measure.set_tooltip(_('Read Measure data')) if utils.get_channels() == 1: import_measure.connect('clicked', self.__import_measure_cb, 1) else: import_measure.connect('clicked', self._measure_btn_clicked) self._create_measure_palette(import_measure) activity_btn_toolbar.insert(import_measure, -1) import_measure.show() toolbarbox.toolbar.insert(activity_button, 0) add_v = ToolButton('gtk-add') add_v.connect('clicked', self._add_value) add_v.set_tooltip(_('Add a value')) toolbarbox.toolbar.insert(add_v, -1) remove_v = ToolButton('gtk-remove') remove_v.connect('clicked', self._remove_value) remove_v.set_tooltip(_('Remove the selected value')) toolbarbox.toolbar.insert(remove_v, -1) self._remove_v = remove_v separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) # We create two sets: one for the main toolbar and one for the # chart toolbar. We choose which set to use based on the # screen width. self._create_chart_buttons(toolbarbox.toolbar) self._chart_button = ToolbarButton(icon_name='vbar') chart_toolbar = Gtk.Toolbar() self._create_chart_buttons(chart_toolbar) self._chart_button.props.page = chart_toolbar chart_toolbar.show_all() toolbarbox.toolbar.insert(self._chart_button, -1) separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) self._options_button = ToolbarButton(icon_name='preferences-system') options_toolbar = Gtk.Toolbar() self.chart_color_btn = ColorToolButton() self.chart_color_btn.set_color(_COLOR1) self.chart_color_btn.set_title(_('Chart Color')) options_toolbar.insert(self.chart_color_btn, -1) GObject.timeout_add(1000, self._connect_color_btn, self.chart_color_btn, self._set_chart_color) self.line_color_btn = ColorToolButton() self.line_color_btn.set_color(_COLOR2) self.line_color_btn.set_title(_('Line Color')) options_toolbar.insert(self.line_color_btn, -1) GObject.timeout_add(1000, self._connect_color_btn, self.line_color_btn, self._set_chart_line_color) separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) options_toolbar.insert(separator, -1) h_label_icon = Icon(icon_name='hlabel') h_label_tool_item = Gtk.ToolItem() h_label_tool_item.add(h_label_icon) options_toolbar.insert(h_label_tool_item, -1) self.h_label = Entry(_('Horizontal label...')) self.h_label.entry.connect('changed', self._set_h_label) options_toolbar.insert(self.h_label, -1) separator = Gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(False) options_toolbar.insert(separator, -1) v_label_icon = Icon(icon_name='vlabel') v_label_tool_item = Gtk.ToolItem() v_label_tool_item.add(v_label_icon) options_toolbar.insert(v_label_tool_item, -1) self.v_label = Entry(_('Vertical label...')) self.v_label.entry.connect('changed', self._set_v_label) options_toolbar.insert(self.v_label, -1) self._options_button.props.page = options_toolbar options_toolbar.show_all() toolbarbox.toolbar.insert(self._options_button, -1) text_toolbar_btn = ToolbarButton() text_toolbar_btn.props.icon_name = 'format-text' text_toolbar_btn.props.label = _('Text') toolbarbox.toolbar.insert(text_toolbar_btn, -1) self._text_options_btn = text_toolbar_btn texttoolbar = Gtk.Toolbar() self.font_name_combo = FontComboBox() self.font_name_combo.set_font_name('Sans') def set_font_name(w): self._set_chart_font_options(font=w.get_font_name()) self.font_name_combo.connect("changed", set_font_name) texttoolbar.insert(ToolComboBox(self.font_name_combo), -1) self.font_size = FontSize() def set_font_size(w): self._set_chart_font_options(size=w.get_font_size()) self.font_size.connect("changed", set_font_size) texttoolbar.insert(self.font_size, -1) self.text_color_btn = ColorToolButton() self.text_color_btn.set_color(style.COLOR_BLACK.get_gdk_color()) self.text_color_btn.set_title(_('Font Color')) texttoolbar.insert(self.text_color_btn, -1) GObject.timeout_add(1000, self._connect_color_btn, self.text_color_btn, self._set_text_color) # self._title_font created in the top of the file self._title_font.connect('clicked', self._set_font_option, TITLE_FONT) self._title_font.set_tooltip(_('Title font')) self._title_font.props.icon_name = 'title-font' op_group = self._title_font texttoolbar.insert(self._title_font, 0) # self._labels_font created in the top of the file self._labels_font.connect('clicked', self._set_font_option, LABELS_FONT) self._labels_font.set_tooltip(_('Labels font')) self._labels_font.props.icon_name = 'labels-font' self._labels_font.props.group = op_group texttoolbar.insert(self._labels_font, 1) tick_font = RadioToolButton() tick_font.connect('clicked', self._set_font_option, TICK_FONT) tick_font.set_tooltip(_('Tick font')) tick_font.props.icon_name = 'tick-font' tick_font.props.group = op_group texttoolbar.insert(tick_font, 2) separator = Gtk.SeparatorToolItem() texttoolbar.insert(separator, 3) text_toolbar_btn.props.page = texttoolbar texttoolbar.show_all() separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) self._fullscreen_button = ToolButton('view-fullscreen') self._fullscreen_button.set_tooltip(_("Fullscreen")) self._fullscreen_button.props.accelerator = '<Alt>Return' self._fullscreen_button.connect('clicked', self.__fullscreen_cb) toolbarbox.toolbar.insert(self._fullscreen_button, -1) charthelp.create_help(toolbarbox.toolbar) separator = Gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) # CANVAS paned = Gtk.HPaned() box = Gtk.VBox() self.box = box # Set the info box width to 1/3 of the screen: def size_allocate_cb(widget, allocation): paned.disconnect(self._setup_handle) box_width = allocation.width / 3 box.set_size_request(box_width, -1) self._setup_handle = paned.connect('size_allocate', size_allocate_cb) scroll = Gtk.ScrolledWindow() scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.labels_and_values = ChartData(self) scroll.add(self.labels_and_values) self.labels_and_values.connect('label-changed', self._label_changed) self.labels_and_values.connect('value-changed', self._value_changed) box.pack_start(scroll, True, True, 0) liststore_toolbar = Gtk.Toolbar() move_up = ToolButton('go-up') move_up.set_tooltip(_('Move up')) move_up.connect('clicked', self._move_up) move_down = ToolButton('go-down') move_down.set_tooltip(_('Move down')) move_down.connect('clicked', self._move_down) liststore_toolbar.insert(move_up, 0) liststore_toolbar.insert(move_down, 1) box.pack_end(liststore_toolbar, False, False, 0) paned.add1(box) # CHARTS AREA eventbox = Gtk.EventBox() self.charts_area = ChartArea(self) eventbox.modify_bg(Gtk.StateType.NORMAL, _WHITE) eventbox.add(self.charts_area) self._notebook = Gtk.Notebook() self._notebook.set_property('show-tabs', False) self._notebook.append_page(eventbox, Gtk.Label()) # EMPTY WIDGETS empty_widgets = Gtk.EventBox() empty_widgets.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color()) vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) mvbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.pack_start(mvbox, True, False, 0) image_icon = Icon(pixel_size=style.LARGE_ICON_SIZE, icon_name='chart', stroke_color=style.COLOR_BUTTON_GREY.get_svg(), fill_color=style.COLOR_TRANSPARENT.get_svg()) mvbox.pack_start(image_icon, False, False, style.DEFAULT_PADDING) label = Gtk.Label('<span foreground="%s"><b>%s</b></span>' % (style.COLOR_BUTTON_GREY.get_html(), _('No data'))) label.set_use_markup(True) mvbox.pack_start(label, False, False, style.DEFAULT_PADDING) hbox = Gtk.Box() open_image_btn = Gtk.Button() open_image_btn.connect('clicked', self._add_value) add_image = Gtk.Image.new_from_stock(Gtk.STOCK_ADD, Gtk.IconSize.BUTTON) buttonbox = Gtk.Box() buttonbox.pack_start(add_image, False, True, 0) buttonbox.pack_end(Gtk.Label(_('Add a value')), True, True, 5) open_image_btn.add(buttonbox) hbox.pack_start(open_image_btn, True, False, 0) mvbox.pack_start(hbox, False, False, style.DEFAULT_PADDING) empty_widgets.add(vbox) empty_widgets.show_all() self._notebook.append_page(empty_widgets, Gtk.Label()) paned.add2(self._notebook) self.set_canvas(paned) self.charts_area.connect('size_allocate', self._chart_size_allocate) self.show_all() Gdk.Screen.get_default().connect('size-changed', self._configure_cb) self._configure_cb()
def __init__(self, handle): """Set up the HelloWorld activity.""" activity.Activity.__init__(self, handle) # Change the following number to change max participants self.max_participants = 1 toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1) show_pictograms_btn = RadioToolButton(icon_name="pictograms") show_pictograms_btn.props.group = show_pictograms_btn show_pictograms_btn.set_active(True) show_pictograms_btn.set_tooltip(_("Show pictograms")) toolbar_box.toolbar.insert(show_pictograms_btn, -1) show_pictograms_btn.connect("clicked", self._change_treenotebook_page, 0) show_bords_btn = RadioToolButton(icon_name="boards") show_bords_btn.props.group = show_pictograms_btn show_bords_btn.set_active(False) show_bords_btn.set_tooltip(_("Show boards")) toolbar_box.toolbar.insert(show_bords_btn, -1) show_bords_btn.connect("clicked", self._change_treenotebook_page, 1) toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1) add_image_btn = ToolButton(icon_name="insert-picture") add_image_btn.set_tooltip(_("Add image from Journal")) toolbar_box.toolbar.insert(add_image_btn, -1) # add_image_btn.connect('clicked', self._change_treenotebook_page, 1) accept_board_btn = ToolButton(icon_name="dialog-ok") accept_board_btn.set_tooltip(_("Store board")) toolbar_box.toolbar.insert(accept_board_btn, -1) accept_board_btn.connect("clicked", self.__store_board_cb) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show() self._boards = [] background = Gtk.EventBox() background.modify_bg(Gtk.StateType.NORMAL, style.Color("#FFFFFF").get_gdk_color()) self.set_canvas(background) # canvas hbox = Gtk.HBox() background.add(hbox) self._treenotebook = Gtk.Notebook() self._treenotebook.set_show_tabs(False) hbox.pack_start(self._treenotebook, False, False, 0) # treeview with pictograms self._create_picto_treeview() scrolled = Gtk.ScrolledWindow() scrolled.props.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC scrolled.props.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC scrolled.set_size_request(Gdk.Screen.width() / 4, -1) scrolled.add_with_viewport(self._picto_tree_view) self._treenotebook.append_page(scrolled, None) # treeview with boards self._create_boards_treeview() scrolled = Gtk.ScrolledWindow() scrolled.props.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC scrolled.props.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC scrolled.set_size_request(Gdk.Screen.width() / 4, -1) scrolled.add_with_viewport(self._boards_tree_view) self._treenotebook.append_page(scrolled, None) self._board_edit_panel = BoardEditPanel() hbox.pack_start(self._board_edit_panel, True, True, 0) self._load_pictograms() self.show_all()
class ToolbarSpeed(Gtk.Toolbar): __gsignals__ = { "speed-changed": (GObject.SIGNAL_RUN_FIRST, None, [float]), } def __init__(self): Gtk.Toolbar.__init__(self) self.button = ToolbarButton(page=self, icon_name="media-playback-stop") self.playing = True self.speed = None self.stop_play = ToolButton("media-playback-stop") self.stop_play.set_tooltip(_("Stop")) self.stop_play.connect("clicked", self._stop_play) self.insert(self.stop_play, -1) self.slow_button = RadioToolButton(group=None, icon_name="slow-walk-milton-raposo") self.slow_button.set_tooltip(_("Run slow")) self.slow_button.connect("clicked", self._speed_changed_cb, Speed.SLOW) self.insert(self.slow_button, -1) self.normal_button = RadioToolButton(group=self.slow_button, icon_name="walking") self.normal_button.set_tooltip(_("Run Normal")) self.normal_button.connect("clicked", self._speed_changed_cb, Speed.NORMAL) self.insert(self.normal_button, -1) self.fast_button = RadioToolButton(group=self.slow_button, icon_name="running") self.fast_button.set_tooltip(_("Run fast")) self.fast_button.connect("clicked", self._speed_changed_cb, Speed.FAST) self.insert(self.fast_button, -1) self.slow_button.set_active(True) self.show_all() def _stop_play(self, button=None): self.playing = not self.playing if self.playing: self.stop_play.set_icon_name("media-playback-stop") self.stop_play.set_tooltip(_("Stop")) self.button.set_icon_name("media-playback-stop") if self.speed is None: self.speed = Speed.SLOW self.emit("speed-changed", self.speed) else: self.stop_play.set_icon_name("media-playback-start") self.stop_play.set_tooltip(_("Start")) self.button.set_icon_name("media-playback-start") self.emit("speed-changed", Speed.STOPPED) def _speed_changed_cb(self, button, speed): if not self.playing: self.speed = speed self._stop_play() else: self.emit("speed-changed", speed) self.speed = speed def enable(self): self.set_sensitive_buttons(True) def disable(self): self.set_sensitive_buttons(False) def set_sensitive_buttons(self, sensitive): self.stop_play.set_sensitive(sensitive) self.slow_button.set_sensitive(sensitive) self.normal_button.set_sensitive(sensitive) self.fast_button.set_sensitive(sensitive)
class ConvertActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 self.dic = {} # Canvas self._canvas = Gtk.VBox() hbox = Gtk.HBox() self._liststore = Gtk.ListStore(str) self.combo1 = Gtk.ComboBox.new_with_model_and_entry(self._liststore) cell = Gtk.CellRendererText() self.combo1.pack_start(cell, True) self.combo1.set_entry_text_column(0) self.combo1.connect('changed', self._call) flip_btn = Gtk.Button() flip_btn.connect('clicked', self._flip) flip_btn.add(Gtk.Image.new_from_file('icons/flip.svg')) self.combo2 = Gtk.ComboBox.new_with_model_and_entry(self._liststore) cell = Gtk.CellRendererText() self.combo2.pack_start(cell, True) self.combo2.set_entry_text_column(0) self.combo2.connect('changed', self._call) self.label_box = Gtk.HBox() self.adjustment = Gtk.Adjustment(1.0, 0, 10.00**10.00, 1.0, 1.0, 0) self.spin = Gtk.SpinButton() self.spin.set_adjustment(self.adjustment) self.spin.set_numeric(True) self.label = Gtk.Label() self.label.set_selectable(True) self.label._size = 12 self.label.connect('draw', self.resize_label) self.convert_btn = Gtk.Button(_('Convert')) self.convert_btn.connect('clicked', self._call) self._canvas.pack_start(hbox, False, False, 20) hbox.pack_start(self.combo1, False, True, 20) hbox.pack_start(flip_btn, True, False, 20) hbox.pack_end(self.combo2, False, True, 20) spin_box = Gtk.HBox() convert_box = Gtk.HBox() convert_box.pack_start(spin_box, True, False, 0) spin_box.pack_start(self.spin, False, False, 0) self._canvas.pack_start(convert_box, False, False, 5) self._canvas.pack_start(self.label_box, True, False, 0) self.label_box.add(self.label) spin_box.pack_start(self.convert_btn, False, False, 20) self.set_canvas(self._canvas) # Toolbar toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbarbox.toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() separator.set_expand(False) separator.set_draw(True) toolbarbox.toolbar.insert(separator, -1) # RadioToolButton self._length_btn = RadioToolButton() self._length_btn.connect('clicked', lambda w: self._update_combo(convert.length)) # TRANS: https://en.wikipedia.org/wiki/Length self._length_btn.set_tooltip(_('Length')) self._length_btn.props.icon_name = 'length' self._volume_btn = RadioToolButton() self._volume_btn.connect('clicked', lambda w: self._update_combo(convert.volume)) # TRANS: https://en.wikipedia.org/wiki/Volume self._volume_btn.set_tooltip(_('Volume')) self._volume_btn.props.icon_name = 'volume' self._volume_btn.props.group = self._length_btn self._area_btn = RadioToolButton() self._area_btn.connect('clicked', lambda w: self._update_combo(convert.area)) # TRANS: https://en.wikipedia.org/wiki/Area self._area_btn.set_tooltip(_('Area')) self._area_btn.props.icon_name = 'area' self._area_btn.props.group = self._length_btn self._weight_btn = RadioToolButton() self._weight_btn.connect('clicked', lambda w: self._update_combo(convert.weight)) # TRANS: https://en.wikipedia.org/wiki/Weight self._weight_btn.set_tooltip(_('Weight')) self._weight_btn.props.icon_name = 'weight' self._weight_btn.props.group = self._length_btn self._speed_btn = RadioToolButton() self._speed_btn.connect('clicked', lambda w: self._update_combo(convert.speed)) # TRANS: https://en.wikipedia.org/wiki/Speed self._speed_btn.set_tooltip(_('Speed')) self._speed_btn.props.icon_name = 'speed' self._speed_btn.props.group = self._length_btn self._time_btn = RadioToolButton() self._time_btn.connect('clicked', lambda w: self._update_combo(convert.time)) # TRANS: https://en.wikipedia.org/wiki/Time self._time_btn.set_tooltip(_('Time')) self._time_btn.props.icon_name = 'time' self._time_btn.props.group = self._length_btn self._temp_btn = RadioToolButton() self._temp_btn.connect('clicked', lambda w: self._update_combo(convert.temp)) # TRANS: https://en.wikipedia.org/wiki/Temperature self._temp_btn.set_tooltip(_('Temperature')) self._temp_btn.props.icon_name = 'temp' self._temp_btn.props.group = self._length_btn toolbarbox.toolbar.insert(self._length_btn, -1) toolbarbox.toolbar.insert(self._volume_btn, -1) toolbarbox.toolbar.insert(self._area_btn, -1) toolbarbox.toolbar.insert(self._weight_btn, -1) toolbarbox.toolbar.insert(self._speed_btn, -1) toolbarbox.toolbar.insert(self._time_btn, -1) toolbarbox.toolbar.insert(self._temp_btn, -1) separator = Gtk.SeparatorToolItem() separator.set_expand(True) separator.set_draw(False) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) self._update_combo(convert.length) self.show_all() def _update_label(self): try: spin_value = str(self.spin.get_value()) decimals = str(len(spin_value.split('.')[-1])) fmt = '%.' + decimals + 'f' new_value = locale.format(fmt, float(spin_value)) convert_value = str(self.convert()) decimals = str(len(convert_value.split('.')[-1])) fmt = '%.' + decimals + 'f' new_convert = locale.format(fmt, float(convert_value)) text = '%s ~ %s' % (new_value, new_convert) self.label.set_text(text) except KeyError: pass def _call(self, widget=None): self._update_label() self.show_all() def _update_combo(self, data): self._liststore.clear() self.dic = data keys = self.dic.keys() keys.sort() for x in keys: symbol = '' if len(self.dic[x]) == 3: symbol = self.dic[x][-1] symbol = '<sup><b>%s</b></sup>' % symbol self._liststore.append(['%s%s' % (x, symbol)]) self.combo1.set_active(-1) self.combo2.set_active(-1) self._call() self.show_all() def _get_active_text(self, combobox): active = combobox.get_active() keys = self.dic.keys() keys.sort() if active < 0: active = 0 text = keys[active] if '<sup>' in text: text = text.split('<b>')[1].split('</b>')[0] return text def _flip(self, widget): active_combo1 = self.combo1.get_active() active_combo2 = self.combo2.get_active() self.combo1.set_active(active_combo2) self.combo2.set_active(active_combo1) value = float(self.label.get_text().split(' ~ ')[1].replace(',', '.')) self.spin.set_value(value) self._call() def resize_label(self, widget, event): num_label = len(self.label.get_text()) try: size = str((60 * SCREEN_WIDTH / 100) / num_label) if not size == self.label._size: self.label.modify_font(Pango.FontDescription(size)) self.label._size = size except ZeroDivisionError: pass def convert(self): number = float(self.spin.get_text().replace(',', '.')) unit = self._get_active_text(self.combo1) to_unit = self._get_active_text(self.combo2) return convert.convert(number, unit, to_unit, self.dic)
def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.max_participants = 1 # CHART_OPTIONS self.x_label = "" self.y_label = "" self.chart_color = utils.get_user_fill_color('str') self.chart_line_color = utils.get_user_stroke_color('str') self.current_chart = None self.charts_area = None self.chart_data = [] # TOOLBARS toolbarbox = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_btn_toolbar = activity_button.page activity_btn_toolbar.title.connect('changed', self._set_chart_title) save_as_image = ToolButton("save-as-image") save_as_image.connect("clicked", self._save_as_image) save_as_image.set_tooltip(_("Save as image")) activity_btn_toolbar.insert(save_as_image, -1) save_as_image.show() toolbarbox.toolbar.insert(activity_button, 0) import_freespace = ToolButton("import-freespace") import_freespace.connect("clicked", self.__import_freespace_cb) import_freespace.set_tooltip(_("Read Freespace data")) toolbarbox.toolbar.insert(import_freespace, -1) import_freespace.show() import_journal = ToolButton('import-journal') import_journal.connect('clicked', self.__import_journal_cb) import_journal.set_tooltip(_('Read Journal data')) toolbarbox.toolbar.insert(import_journal, -1) import_journal.show() import_turtle = ToolButton('import-turtle') import_turtle.connect('clicked', self.__import_turtle_cb) import_turtle.set_tooltip(_('Read Turtle data')) toolbarbox.toolbar.insert(import_turtle, -1) import_turtle.show() separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) add_vbar_chart = RadioToolButton() add_vbar_chart.connect("clicked", self._add_chart_cb, "vbar") add_vbar_chart.set_tooltip(_("Vertical Bar Chart")) add_vbar_chart.props.icon_name = "vbar" charts_group = add_vbar_chart toolbarbox.toolbar.insert(add_vbar_chart, -1) add_hbar_chart = RadioToolButton() add_hbar_chart.connect("clicked", self._add_chart_cb, "hbar") add_hbar_chart.set_tooltip(_("Horizontal Bar Chart")) add_hbar_chart.props.icon_name = "hbar" add_hbar_chart.props.group = charts_group toolbarbox.toolbar.insert(add_hbar_chart, -1) add_line_chart = RadioToolButton() add_line_chart.connect("clicked", self._add_chart_cb, "line") add_line_chart.set_tooltip(_("Line Bar Chart")) add_line_chart.props.icon_name = "line" add_line_chart.props.group = charts_group toolbarbox.toolbar.insert(add_line_chart, -1) add_pie_chart = RadioToolButton() add_pie_chart.connect("clicked", self._add_chart_cb, "pie") add_pie_chart.set_tooltip(_("Pie Chart")) add_pie_chart.props.icon_name = "pie" add_pie_chart.props.group = charts_group add_pie_chart.set_active(True) toolbarbox.toolbar.insert(add_pie_chart, -1) self.chart_type_buttons = [ add_vbar_chart, add_hbar_chart, add_line_chart, add_pie_chart ] separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.set_expand(False) toolbarbox.toolbar.insert(separator, -1) fullscreen_btn = ToolButton('view-fullscreen') fullscreen_btn.set_tooltip(_('Fullscreen')) fullscreen_btn.connect("clicked", self.__fullscreen_cb) toolbarbox.toolbar.insert(fullscreen_btn, -1) charthelp.create_help(toolbarbox.toolbar) separator = Gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) toolbarbox.toolbar.insert(separator, -1) stopbtn = StopButton(self) toolbarbox.toolbar.insert(stopbtn, -1) self.set_toolbar_box(toolbarbox) # CANVAS paned = Gtk.HPaned() box = Gtk.VBox() self.box = box # Set the info box width to 1/3 of the screen: def size_allocate_cb(widget, allocation): paned.disconnect(self._setup_handle) box_width = allocation.width / 3 box.set_size_request(box_width, -1) self._setup_handle = paned.connect('size_allocate', size_allocate_cb) scroll = Gtk.ScrolledWindow() scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.labels_and_values = ChartData(self) scroll.add(self.labels_and_values) self.labels_and_values.connect("label-changed", self._label_changed) self.labels_and_values.connect("value-changed", self._value_changed) box.pack_start(scroll, True, True, 0) paned.add1(box) # CHARTS AREA eventbox = Gtk.EventBox() self.charts_area = ChartArea(self) self.charts_area.connect('size_allocate', self._chart_size_allocate) eventbox.modify_bg(Gtk.StateType.NORMAL, _WHITE) eventbox.add(self.charts_area) paned.add2(eventbox) self.set_canvas(paned) self.show_all()