def __init__(self, calc): Gtk.Toolbar.__init__(self) copy_tool = ToolButton('edit-copy') copy_tool.set_tooltip(_('Copy')) copy_tool.set_accelerator(_('<ctrl>c')) copy_tool.connect('clicked', lambda x: calc.text_copy()) self.insert(copy_tool, -1) menu_item = MenuItem(_('Cut')) try: menu_item.set_accelerator(_('<ctrl>x')) except AttributeError: pass menu_item.connect('activate', lambda x: calc.text_cut()) menu_item.show() copy_tool.get_palette().menu.append(menu_item) self.insert(IconToolButton('edit-paste', _('Paste'), lambda x: calc.text_paste(), alt_html='Paste'), -1) self.show_all()
def __init__(self, calc): Gtk.Toolbar.__init__(self) copy_tool = ToolButton('edit-copy') copy_tool.set_tooltip(_('Copy')) copy_tool.set_accelerator(_('<ctrl>c')) copy_tool.connect('clicked', lambda x: calc.text_copy()) self.insert(copy_tool, -1) menu_item = MenuItem(_('Cut')) try: menu_item.set_accelerator(_('<ctrl>x')) except AttributeError: pass menu_item.connect('activate', lambda x: calc.text_cut()) menu_item.show() copy_tool.get_palette().menu.append(menu_item) self.insert( IconToolButton('edit-paste', _('Paste'), lambda x: calc.text_paste(), alt_html='Paste'), -1) self.show_all()
def __init__(self, activity, **kwargs): GObject.GObject.__init__(self) description_button = ToolButton('edit-description') description_button.show() description_button.set_tooltip(_('Description')) self._palette = description_button.get_palette() description_box = Gtk.HBox() sw = Gtk.ScrolledWindow() sw.set_size_request(int(Gdk.Screen.width() / 2), 2 * style.GRID_CELL_SIZE) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self._text_view = Gtk.TextView() self._text_view.set_left_margin(style.DEFAULT_PADDING) self._text_view.set_right_margin(style.DEFAULT_PADDING) text_buffer = Gtk.TextBuffer() if 'description' in activity.metadata: text_buffer.set_text(activity.metadata['description']) self._text_view.set_buffer(text_buffer) self._text_view.connect('focus-out-event', self.__description_changed_cb, activity) sw.add(self._text_view) description_box.pack_start(sw, False, True, 0) self._palette.set_content(description_box) description_box.show_all() self.add(description_button) description_button.connect('clicked', self.__description_button_clicked_cb) activity.metadata.connect('updated', self.__jobject_updated_cb)
def __init__(self, **kwargs): Gtk.ToolItem.__init__(self) help_button = ToolButton('toolbar-help') help_button.set_tooltip(_('Ayuda / ÑepYsyrõ')) self.add(help_button) self._palette = help_button.get_palette() sw = Gtk.ScrolledWindow() sw.set_size_request(int(Gdk.Screen.width() / 2.8), 100) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self._max_text_width = int(Gdk.Screen.width() / 3) - 600 self._vbox = Gtk.Box() self._vbox.set_orientation(Gtk.Orientation.VERTICAL) self._vbox.set_homogeneous(False) self._vbox.set_border_width(10) hbox = Gtk.Box() hbox.pack_start(self._vbox, False, True, 0) sw.add_with_viewport(hbox) self._palette.set_content(sw) sw.show_all() help_button.connect('clicked', self.__help_button_clicked_cb)
def __init__(self, **kwargs): GObject.GObject.__init__(self) help_button = ToolButton("toolbar-help") help_button.set_tooltip( _("What should you know before using Solar System?")) self.add(help_button) self._palette = help_button.get_palette() sw = Gtk.ScrolledWindow() sw.set_size_request(int(Gdk.Screen.width() / 2.8), 310) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self._max_text_width = int(Gdk.Screen.width() / 3) - 600 self._vbox = Gtk.Box() self._vbox.set_orientation(Gtk.Orientation.VERTICAL) self._vbox.set_homogeneous(False) self._vbox.set_border_width(10) hbox = Gtk.Box() hbox.pack_start(self._vbox, False, True, 0) sw.add_with_viewport(hbox) self._palette.set_content(sw) sw.show_all() help_button.connect('clicked', self.__help_button_clicked_cb)
def __init__(self, **kwargs): GObject.GObject.__init__(self) help_button = ToolButton('toolbar-help') help_button.set_tooltip(_('Help')) self.add(help_button) self._palette = help_button.get_palette() sw = Gtk.ScrolledWindow() sw.set_size_request(int(Gdk.Screen.width() / 2.8), Gdk.Screen.height() - style.GRID_CELL_SIZE * 3) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self._max_text_width = int(Gdk.Screen.width() / 3) - 600 self._vbox = Gtk.Box() self._vbox.set_orientation(Gtk.Orientation.VERTICAL) self._vbox.set_homogeneous(False) self._vbox.set_border_width(10) hbox = Gtk.Box() hbox.pack_start(self._vbox, False, True, 0) sw.add_with_viewport(hbox) self._palette.set_content(sw) sw.show_all() help_button.connect('clicked', self.__help_button_clicked_cb)
def __init__(self, activity, **kwargs): Gtk.ToolItem.__init__(self) description_button = ToolButton('edit-description') description_button.show() description_button.set_tooltip(_('Description')) description_button.palette_invoker.props.toggle_palette = True description_button.props.hide_tooltip_on_click = False self._palette = description_button.get_palette() description_box = PaletteMenuBox() sw = Gtk.ScrolledWindow() sw.set_size_request(int(Gdk.Screen.width() / 2), 2 * style.GRID_CELL_SIZE) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self._text_view = Gtk.TextView() self._text_view.set_left_margin(style.DEFAULT_PADDING) self._text_view.set_right_margin(style.DEFAULT_PADDING) self._text_view.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) text_buffer = Gtk.TextBuffer() if 'description' in activity.metadata: text_buffer.set_text(activity.metadata['description']) self._text_view.set_buffer(text_buffer) self._text_view.connect('focus-out-event', self.__description_changed_cb, activity) sw.add(self._text_view) description_box.append_item(sw, vertical_padding=0) self._palette.set_content(description_box) description_box.show_all() self.add(description_button) activity.metadata.connect('updated', self.__jobject_updated_cb)
def __init__(self, **kwargs): GObject.GObject.__init__(self) help_button = ToolButton('toolbar-help') help_button.set_tooltip(_('Help')) self.add(help_button) self._palette = help_button.get_palette() sw = Gtk.ScrolledWindow() sw.set_size_request(int(Gdk.Screen.width() / 2.8), Gdk.Screen.height() - style.GRID_CELL_SIZE * 3) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self._max_text_width = int(Gdk.Screen.width() / 3) - 600 self._vbox = Gtk.Box() self._vbox.set_orientation(Gtk.Orientation.VERTICAL) self._vbox.set_homogeneous(False) sw.add_with_viewport(self._vbox) self._palette.set_content(sw) sw.show_all() help_button.connect('clicked', self.__help_button_clicked_cb)
def __init__(self, activity): self._activity = activity self._current_palette = 'turtle' Gtk.ToolItem.__init__(self) help_button = ToolButton('help-toolbar') help_button.set_tooltip(_('Help')) self.add(help_button) help_button.show() self._palette = help_button.get_palette() help_button.connect('clicked', self.__help_button_clicked_cb)
def _create_back_button(self): back = ToolButton('go-previous-paired') back.set_tooltip(_('Back')) back.props.sensitive = False palette = back.get_palette() previous_page = MenuItem(text_label=_("Previous page")) previous_page.show() previous_bookmark = MenuItem(text_label=_("Previous bookmark")) previous_bookmark.show() palette.menu.append(previous_page) palette.menu.append(previous_bookmark) back.connect('clicked', self.__go_back_cb) previous_page.connect('activate', self.__go_back_page_cb) previous_bookmark.connect('activate', self.__prev_bookmark_activate_cb) return back
def _create_forward_button(self): forward = ToolButton('go-next-paired') forward.set_tooltip(_('Forward')) forward.props.sensitive = False palette = forward.get_palette() next_page = MenuItem(text_label=_("Next page")) next_page.show() next_bookmark = MenuItem(text_label=_("Next bookmark")) next_bookmark.show() palette.menu.append(next_page) palette.menu.append(next_bookmark) forward.connect('clicked', self.__go_forward_cb) next_page.connect('activate', self.__go_forward_page_cb) next_bookmark.connect('activate', self.__next_bookmark_activate_cb) return forward
def __init__(self, handle): ''' Initiate activity. ''' super(AbacusActivity, self).__init__(handle) self._setting_up = True self.bead_colors = profile.get_color().to_string().split(',') # no sharing self.max_participants = 1 self.sep = [] self.abacus_toolbar = Gtk.Toolbar() custom_toolbar = Gtk.Toolbar() edit_toolbar = Gtk.Toolbar() toolbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() edit_toolbar_button = ToolbarButton(label=_('Edit'), page=edit_toolbar, icon_name='toolbar-edit') edit_toolbar_button.show() toolbox.toolbar.insert(edit_toolbar_button, -1) edit_toolbar_button.show() self.abacus_toolbar_button = ToolbarButton( page=self.abacus_toolbar, icon_name='abacus-list') self.abacus_toolbar.show() toolbox.toolbar.insert(self.abacus_toolbar_button, -1) self.abacus_toolbar_button.show() self.custom_toolbar_button = ToolbarButton( page=custom_toolbar, icon_name='view-source') custom_toolbar.show() toolbox.toolbar.insert(self.custom_toolbar_button, -1) self.custom_toolbar_button.show() separator_factory(toolbox.toolbar, False, True) button_factory('edit-delete', toolbox.toolbar, self._reset_cb, tooltip=_('Reset')) separator_factory(toolbox.toolbar, False, True) self._label = label_factory(NAMES['suanpan'], toolbox.toolbar) separator_factory(toolbox.toolbar, True, False) stop_button = StopButton(self) stop_button.props.accelerator = _('<Ctrl>Q') toolbox.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbox) toolbox.show() self.abacus_buttons = {} # Traditional self._add_abacus_button('decimal', None) self._add_abacus_button('soroban', self.abacus_buttons['decimal']) self._add_abacus_button('suanpan', self.abacus_buttons['decimal']) self.sep.append(separator_factory(self.abacus_toolbar)) # Bases other than 10 self._add_abacus_button('nepohualtzintzin', self.abacus_buttons['decimal']) self._add_abacus_button('hexadecimal', self.abacus_buttons['decimal']) self._add_abacus_button('binary', self.abacus_buttons['decimal']) self.sep.append(separator_factory(self.abacus_toolbar)) # Fractions self._add_abacus_button('schety', self.abacus_buttons['decimal']) # self._add_abacus_button('fraction', self.abacus_buttons['decimal']) self._add_abacus_button('caacupe', self.abacus_buttons['decimal']) self.sep.append(separator_factory(self.abacus_toolbar)) # Non-traditional self._add_abacus_button('cuisenaire', self.abacus_buttons['decimal']) self.sep.append(separator_factory(self.abacus_toolbar)) # Custom self._add_abacus_button('custom', self.abacus_buttons['decimal']) preferences_button = ToolButton('preferences-system') preferences_button.set_tooltip(_('Custom')) custom_toolbar.insert(preferences_button, -1) preferences_button.palette_invoker.props.toggle_palette = True preferences_button.palette_invoker.props.lock_palette = True preferences_button.props.hide_tooltip_on_click = False preferences_button.show() self._palette = preferences_button.get_palette() button_box = Gtk.VBox() # TRANS: Number of rods on the abacus self._rods_spin = add_spinner_and_label( 15, 1, MAX_RODS, _('Rods:'), self._rods_spin_cb, button_box) # TRANS: Number of beads in the top section of the abacus self._top_spin = add_spinner_and_label( 2, 0, MAX_TOP, _('Top:'), self._top_spin_cb, button_box) # TRANS: Number of beads in the bottom section of the abacus self._bottom_spin = add_spinner_and_label( 5, 0, MAX_BOT, _('Bottom:'), self._bottom_spin_cb, button_box) # TRANS: Scale factor between bottom and top beads self._value_spin = add_spinner_and_label( 5, 1, MAX_BOT + 1, _('Factor:'), self._value_spin_cb, button_box) # TRANS: Scale factor between rods self._base_spin = add_spinner_and_label( 10, 1, (MAX_TOP + 1) * MAX_BOT, _('Base:'), self._base_spin_cb, button_box) hbox = Gtk.HBox() hbox.pack_start(button_box, True, True, style.DEFAULT_SPACING) hbox.show_all() self._palette.set_content(hbox) separator_factory(custom_toolbar, False, False) self.custom_maker = button_factory('new-abacus', custom_toolbar, self._custom_cb, tooltip=_('Custom')) button_factory('edit-copy', edit_toolbar, self._copy_cb, tooltip=_('Copy'), accelerator='<Ctrl>c') button_factory('edit-paste', edit_toolbar, self._paste_cb, tooltip=_('Paste'), accelerator='<Ctrl>v') # Create a canvas canvas = Gtk.DrawingArea() canvas.set_size_request(Gdk.Screen.width(), Gdk.Screen.height()) self.set_canvas(canvas) canvas.show() self.show_all() # Initialize the canvas self.abacus = Abacus(canvas, self) self._setting_up = False # Read the current mode from the Journal if 'rods' in self.metadata: self._rods_spin.set_value(int(self.metadata['rods'])) if 'top' in self.metadata: self._top_spin.set_value(int(self.metadata['top'])) if 'bottom' in self.metadata: self._bottom_spin.set_value(int(self.metadata['bottom'])) if 'factor' in self.metadata: self._value_spin.set_value(int(self.metadata['factor'])) if 'base' in self.metadata: self._base_spin.set_value(int(self.metadata['base'])) if 'abacus' in self.metadata: if self.metadata['abacus'] in self.abacus_buttons: _logger.debug('restoring %s', self.metadata['abacus']) if self.metadata['abacus'] == 'custom': self._custom_cb() self.abacus_buttons[self.metadata['abacus']].set_active(True) else: # Default is Chinese self.abacus_buttons['suanpan'].set_active(True) if 'value' in self.metadata: _logger.debug('restoring value %s', self.metadata['value']) self.abacus.mode.set_value(self.metadata['value']) self.abacus.mode.label(self.abacus.generate_label()) self.abacus.init() # Start with abacus toolbar expanded and suanpan as default self.abacus_toolbar_button.set_expanded(True)
def __init__(self): super(PyApp, self).__init__() self.set_title('Palettes') self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) vbox = Gtk.VBox() toolbarbox = ToolbarBox() vbox.add(toolbarbox) toolbar = toolbarbox.toolbar color_button = ColorToolButton() toolbar.insert(color_button, -1) button = ToolButton('list-add') button.set_tooltip('Palette with widgets') toolbar.insert(button, -1) palette = button.get_palette() palette_box = Gtk.VBox() palette.set_content(palette_box) checkbutton1 = Gtk.CheckButton('Option 1') palette_box.pack_start(checkbutton1, False, False, 0) checkbutton2 = Gtk.CheckButton('Option 2') palette_box.pack_start(checkbutton2, False, False, 0) checkbutton3 = Gtk.CheckButton('Option 3') palette_box.pack_start(checkbutton3, False, False, 0) separator = Gtk.VSeparator() palette_box.pack_start(separator, False, False, 0) radio_button1 = Gtk.RadioButton('Option 1') palette_box.pack_start(radio_button1, False, False, 0) radio_button2 = Gtk.RadioButton('Option 2', group=radio_button1) palette_box.pack_start(radio_button2, False, False, 0) radio_button3 = Gtk.RadioButton('Option 3', group=radio_button1) palette_box.pack_start(radio_button3, False, False, 0) palette_box.show_all() button = ToolButton(icon_name='format-justify-fill') button.props.tooltip = 'Select list' button.props.hide_tooltip_on_click = False button.palette_invoker.props.toggle_palette = True toolbar.insert(button, -1) menu_box = PaletteMenuBox() button.props.palette.set_content(menu_box) menu_box.show() menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-fill') menu_box.append_item(menu_item) menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-center') menu_box.append_item(menu_item) menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-left') menu_box.append_item(menu_item) menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-right') menu_box.append_item(menu_item) self.add(vbox) self.show_all() self.connect('destroy', Gtk.main_quit)
def __init__(self, handle): activity.Activity.__init__(self, handle) self.set_title('FotoToon') self._max_participants = 1 self.page = None toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_toolbar = activity_button.page toolbar_box.toolbar.insert(activity_button, 0) edit_toolbar_btn = ToolbarButton() edit_toolbar = Gtk.Toolbar() edit_toolbar_btn.props.page = edit_toolbar edit_toolbar_btn.props.icon_name = 'toolbar-edit' edit_toolbar_btn.label = _('Edit') toolbar_box.toolbar.insert(edit_toolbar_btn, -1) view_toolbar_btn = ToolbarButton() view_toolbar = Gtk.Toolbar() view_toolbar_btn.props.page = view_toolbar view_toolbar_btn.props.icon_name = 'toolbar-view' view_toolbar_btn.label = _('View') toolbar_box.toolbar.insert(view_toolbar_btn, -1) slideview_btn = ToggleToolButton('slideshow') slideview_btn.set_tooltip(_('Slideshow')) slideview_btn.set_active(False) slideview_btn.connect('clicked', self._switch_view_mode, False) view_toolbar.insert(slideview_btn, -1) slideview_btn.show() slideview_timings_btn = ToggleToolButton('slideshow-stopwatch') slideview_timings_btn.set_tooltip(_('Slideshow with Timings')) slideview_timings_btn.set_active(False) slideview_timings_btn.connect('clicked', self._switch_view_mode, True) view_toolbar.insert(slideview_timings_btn, -1) slideview_timings_btn.show() time_button = ToolButton('stopwatch') time_button.set_tooltip(_('Set Image Duration in Slideshow (Seconds)')) view_toolbar.insert(time_button, -1) time_button.show() self._time_spin = Gtk.SpinButton.new_with_range(MIN_TIME, MAX_TIME, 1) self._time_spin.connect('value-changed', self.__time_spin_changed_cb) self._time_spin.props.value = DEFAULT_TIME self._time_spin.props.update_policy = \ Gtk.SpinButtonUpdatePolicy.IF_VALID palette = time_button.get_palette() palette.connect('popup', self.__time_button_popup_cb) time_button.connect( 'clicked', lambda *args: palette.popup(immediate=True, state=Palette.SECONDARY)) alignment = Gtk.Alignment() alignment.set_padding(style.DEFAULT_PADDING, style.DEFAULT_PADDING, style.DEFAULT_PADDING, style.DEFAULT_PADDING) alignment.add(self._time_spin) self._time_spin.show() palette.set_content(alignment) alignment.show() fullscreen_btn = ToolButton('view-fullscreen') fullscreen_btn.set_tooltip(_('Fullscreen')) fullscreen_btn.props.accelerator = '<Alt>Return' fullscreen_btn.connect('clicked', lambda w: self.fullscreen()) view_toolbar.insert(fullscreen_btn, -1) fullscreen_btn.show() self.set_toolbar_box(toolbar_box) toolbar = toolbar_box.toolbar self.page = Page() self.globes_manager = GlobesManager(toolbar, edit_toolbar, self) # fonts self._text_button = ToolbarButton() self._text_button.props.page = TextToolbar(self.page) self._text_button.props.icon_name = 'format-text-size' self._text_button.props.label = _('Text') self._toolbar_box.toolbar.insert(self._text_button, -1) reorder_img_btn = ToolButton('thumbs-view') reorder_img_btn.set_icon_name('thumbs-view') reorder_img_btn.set_tooltip(_('Change image order')) reorder_img_btn.connect('clicked', self.__image_order_cb) edit_toolbar.insert(reorder_img_btn, -1) reorder_img_btn.show() bgchange = ToolButton(icon_name='contract-coordinates') bgchange.set_tooltip(_('Edit background image')) bgchange.connect('clicked', self.__bgchange_clicked_cb) edit_toolbar.insert(bgchange, -1) bgchange.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) stop = StopButton(self) toolbar_box.toolbar.insert(stop, -1) toolbar_box.show_all() # add export button separator_2 = Gtk.SeparatorToolItem() separator_2.show() activity_toolbar.insert(separator_2, -1) self.bt_save_as_image = ToolButton() self.bt_save_as_image.props.icon_name = 'save-as-image' self.bt_save_as_image.connect('clicked', self.write_image) self.bt_save_as_image.set_tooltip(_('Save as Image')) activity_toolbar.insert(self.bt_save_as_image, -1) self.bt_save_as_image.show() save_as_pdf = ToolButton() save_as_pdf.props.icon_name = 'save-as-pdf' save_as_pdf.connect('clicked', self._save_as_pdf) save_as_pdf.set_tooltip(_('Save as a Book (PDF)')) activity_toolbar.insert(save_as_pdf, -1) save_as_pdf.show() save_as_ogg = ToolButton() save_as_ogg.props.icon_name = 'save-as-ogg' save_as_ogg.connect('clicked', self.__save_as_ogg_cb) save_as_ogg.set_tooltip(_('Save as a Movie (OGG)')) activity_toolbar.insert(save_as_ogg, -1) save_as_ogg.show() activity_button.page.title.connect("focus-in-event", self.on_title) scrolled = Gtk.ScrolledWindow() # scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS) scrolled.add_with_viewport(self.page) scrolled.set_kinetic_scrolling(False) scrolled.show_all() self._slideview = SlideView(self) self._slideview.show_all() self._notebook = Gtk.Notebook() self._notebook.set_show_tabs(False) self._notebook.append_page(scrolled, None) self._notebook.append_page(self._slideview, None) self._notebook.show_all() if self._jobject.file_path is None or self._jobject.file_path == '': empty_widget = EmptyWidget() empty_widget.connect('choose-image', self.__add_image) self.set_canvas(empty_widget) else: self.set_canvas(self._notebook) self.show() self.metadata['mime_type'] = 'application/x-fototoon-activity' self.page.empty_page = handle.object_id is None self._key_press_signal_id = None
class InsertToolbar(Gtk.Toolbar): def __init__(self, abiword_canvas): GObject.GObject.__init__(self) self._abiword_canvas = abiword_canvas self._table_btn = ToolButton('create-table') self._table_btn.set_tooltip(_('Create table')) self.insert(self._table_btn, -1) self._grid_create = GridCreateWidget() self._grid_create.show() self._grid_create.connect('create-table', self._create_table_cb) palette = self._table_btn.get_palette() palette.set_content(self._grid_create) self._table_btn.connect('clicked', self._table_btn_clicked_cb) self._table_rows_after = ToolButton('row-insert') self._table_rows_after.set_tooltip(_('Insert Row')) self._table_rows_after_id = self._table_rows_after.connect( 'clicked', self._table_rows_after_cb) self.insert(self._table_rows_after, -1) self._table_delete_rows = ToolButton('row-remove') self._table_delete_rows.set_tooltip(_('Delete Row')) self._table_delete_rows_id = self._table_delete_rows.connect( 'clicked', self._table_delete_rows_cb) self.insert(self._table_delete_rows, -1) self._table_cols_after = ToolButton('column-insert') self._table_cols_after.set_tooltip(_('Insert Column')) self._table_cols_after_id = self._table_cols_after.connect( 'clicked', self._table_cols_after_cb) self.insert(self._table_cols_after, -1) self._table_delete_cols = ToolButton('column-remove') self._table_delete_cols.set_tooltip(_('Delete Column')) self._table_delete_cols_id = self._table_delete_cols.connect( 'clicked', self._table_delete_cols_cb) self.insert(self._table_delete_cols, -1) self.show_all() self._abiword_canvas.connect('table-state', self._isTable_cb) #self._abiword_canvas.connect('image-selected', # self._image_selected_cb) def _table_btn_clicked_cb(self, button): button.get_palette().popup(True, button.get_palette().SECONDARY) def _create_table_cb(self, abi, rows, cols): self._abiword_canvas.insert_table(rows, cols) def _table_rows_after_cb(self, button): self._abiword_canvas.invoke_ex('insertRowsAfter', '', 0, 0) def _table_delete_rows_cb(self, button): self._abiword_canvas.invoke_ex('deleteRows', '', 0, 0) def _table_cols_after_cb(self, button): self._abiword_canvas.invoke_ex('insertColsAfter', '', 0, 0) def _table_delete_cols_cb(self, button): self._abiword_canvas.invoke_ex('deleteColumns', '', 0, 0) def _isTable_cb(self, abi, b): self._table_rows_after.set_sensitive(b) self._table_delete_rows.set_sensitive(b) self._table_cols_after.set_sensitive(b) self._table_delete_cols.set_sensitive(b)
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()
class PrimaryToolbar(ToolbarBase): __gtype_name__ = "PrimaryToolbar" __gsignals__ = { "add-link": (GObject.SignalFlags.RUN_FIRST, None, ([])), "go-home": (GObject.SignalFlags.RUN_FIRST, None, ([])), "set-home": (GObject.SignalFlags.RUN_FIRST, None, ([])), "reset-home": (GObject.SignalFlags.RUN_FIRST, None, ([])), "go-library": (GObject.SignalFlags.RUN_FIRST, None, ([])), "go-to-JSshell": (GObject.SignalFlags.RUN_FIRST, None, ([])), "get-shell-input": (GObject.SignalFlags.RUN_FIRST, None, ([])), } def __init__(self, tabbed_view, act): ToolbarBase.__init__(self) self._url_toolbar = UrlToolbar() self._activity = act self._tabbed_view = self._canvas = tabbed_view self._loading = False toolbar = self.toolbar activity_button = ActivityToolbarButton(self._activity) toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() save_as_pdf = ToolButton("save-as-pdf") save_as_pdf.set_tooltip(_("Save page as pdf")) save_as_pdf.connect("clicked", self.save_as_pdf) activity_button.props.page.insert(separator, -1) activity_button.props.page.insert(save_as_pdf, -1) separator.show() save_as_pdf.show() self._go_home = ToolButton("go-home") self._go_home.set_tooltip(_("Home page")) self._go_home.connect("clicked", self._go_home_cb) # add a menu to save the home page menu_box = PaletteMenuBox() self._go_home.props.palette.set_content(menu_box) menu_item = PaletteMenuItem() menu_item.set_label(_("Select as initial page")) menu_item.connect("activate", self._set_home_cb) menu_box.append_item(menu_item) self._reset_home_menu = PaletteMenuItem() self._reset_home_menu.set_label(_("Reset initial page")) self._reset_home_menu.connect("activate", self._reset_home_cb) menu_box.append_item(self._reset_home_menu) if os.path.isfile(LIBRARY_PATH): library_menu = PaletteMenuItem() library_menu.set_label(_("Library")) library_menu.connect("activate", self._go_library_cb) menu_box.append_item(library_menu) menu_box.show_all() # verify if the home page is configured client = GConf.Client.get_default() self._reset_home_menu.set_visible(client.get_string(HOME_PAGE_GCONF_KEY) is not None) toolbar.insert(self._go_home, -1) self._go_home.show() self.entry = WebEntry() self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, "entry-stop") self.entry.connect("icon-press", self._stop_and_reload_cb) self.entry.connect("activate", self._entry_activate_cb) self.entry.connect("focus-in-event", self.__focus_in_event_cb) self.entry.connect("focus-out-event", self.__focus_out_event_cb) self.entry.connect("key-press-event", self.__key_press_event_cb) self.entry.connect("changed", self.__changed_cb) self._entry_item = Gtk.ToolItem() self._entry_item.set_expand(True) self._entry_item.add(self.entry) self.entry.show() toolbar.insert(self._entry_item, -1) self._entry_item.show() self._back = ToolButton("go-previous-paired") self._back.set_tooltip(_("Back")) self._back.props.sensitive = False self._back.connect("clicked", self._go_back_cb) toolbar.insert(self._back, -1) self._back.show() palette = self._back.get_palette() self._back_box_menu = Gtk.VBox() self._back_box_menu.show() palette.set_content(self._back_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._forward = ToolButton("go-next-paired") self._forward.set_tooltip(_("Forward")) self._forward.props.sensitive = False self._forward.connect("clicked", self._go_forward_cb) toolbar.insert(self._forward, -1) self._forward.show() palette = self._forward.get_palette() self._forward_box_menu = Gtk.VBox() self._forward_box_menu.show() palette.set_content(self._forward_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._link_add = ToolButton("emblem-favorite") self._link_add.set_tooltip(_("Bookmark")) self._link_add.connect("clicked", self._link_add_clicked_cb) toolbar.insert(self._link_add, -1) self._link_add.show() self._toolbar_separator = Gtk.SeparatorToolItem() self._toolbar_separator.props.draw = False self._toolbar_separator.set_expand(True) self._go_to_JSshell = ToolButton("go-to-JSshell") self._go_to_JSshell.set_tooltip(_("Go to Interactive Javascript Shell")) self._go_to_JSshell.connect("clicked", self._go_to_JSshell_cb) # adding a button for the Interactive Javascript shell toolbar.insert(self._go_to_JSshell, -1) self._go_to_JSshell.show() self._get_shell_input = ToolButton("get-shell-input") self._get_shell_input.set_tooltip(_("Get Interactive Javascript Shell Input")) self._get_shell_input.connect("clicked", self._get_shell_input_cb) # adding a button for the Interactive Javascript shell toolbar.insert(self._get_shell_input, -1) self._get_shell_input.show() stop_button = StopButton(self._activity) toolbar.insert(stop_button, -1) self._progress_listener = None self._browser = None self._loading_changed_hid = None self._progress_changed_hid = None self._session_history_changed_hid = None self._uri_changed_hid = None self._security_status_changed_hid = None if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) tabbed_view.connect_after("switch-page", self.__switch_page_cb) tabbed_view.connect_after("page-added", self.__page_added_cb) Gdk.Screen.get_default().connect("size-changed", self.__screen_size_changed_cb) self._configure_toolbar() def __key_press_event_cb(self, entry, event): self._tabbed_view.current_browser.loading_uri = entry.props.text def __switch_page_cb(self, tabbed_view, page, page_num): if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) def __page_added_cb(self, notebook, child, pagenum): self.entry._search_popdown() def _configure_toolbar(self, screen=None): # Adapt the toolbars for portrait or landscape mode. if screen is None: screen = Gdk.Screen.get_default() if screen.get_width() < screen.get_height(): if self._entry_item in self._url_toolbar.toolbar.get_children(): return self.toolbar.remove(self._entry_item) self._url_toolbar.toolbar.insert(self._entry_item, -1) separator_pos = len(self.toolbar.get_children()) - 1 self.toolbar.insert(self._toolbar_separator, separator_pos) self._toolbar_separator.show() self.pack_end(self._url_toolbar, True, True, 0) self._url_toolbar.show() else: if self._entry_item in self.toolbar.get_children(): return self.toolbar.remove(self._toolbar_separator) position = len(self.toolbar.get_children()) - 4 self._url_toolbar.toolbar.remove(self._entry_item) self.toolbar.insert(self._entry_item, position) self._toolbar_separator.hide() self.remove(self._url_toolbar) def __screen_size_changed_cb(self, screen): self._configure_toolbar(screen) def _connect_to_browser(self, browser): if self._browser is not None: self._browser.disconnect(self._uri_changed_hid) self._browser.disconnect(self._progress_changed_hid) self._browser.disconnect(self._loading_changed_hid) self._browser.disconnect(self._security_status_changed_hid) self._browser = browser if not isinstance(self._browser, DummyBrowser): address = self._browser.props.uri or self._browser.loading_uri else: address = self._browser.props.uri self._set_address(address) self._set_progress(self._browser.props.progress) self._set_status(self._browser.props.load_status) self._set_security_status(self._browser.security_status) is_webkit_browser = isinstance(self._browser, Browser) self.entry.props.editable = is_webkit_browser self._uri_changed_hid = self._browser.connect("notify::uri", self.__uri_changed_cb) self._progress_changed_hid = self._browser.connect("notify::progress", self.__progress_changed_cb) self._loading_changed_hid = self._browser.connect("notify::load-status", self.__loading_changed_cb) self._security_status_changed_hid = self._browser.connect( "security-status-changed", self.__security_status_changed_cb ) self._update_navigation_buttons() def __loading_changed_cb(self, widget, param): self._set_status(widget.get_load_status()) def __security_status_changed_cb(self, widget): self._set_security_status(widget.security_status) def __progress_changed_cb(self, widget, param): self._set_progress(widget.get_progress()) def _set_status(self, status): self._set_loading(status < WebKit.LoadStatus.FINISHED) def _set_security_status(self, security_status): # Display security status as a lock icon in the left side of # the URL entry. if security_status is None: self.entry.set_icon_from_pixbuf(iconentry.ICON_ENTRY_PRIMARY, None) elif security_status == Browser.SECURITY_STATUS_SECURE: self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, "channel-secure-symbolic") elif security_status == Browser.SECURITY_STATUS_INSECURE: self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, "channel-insecure-symbolic") def _set_progress(self, progress): if progress == 1.0: self.entry.set_progress_fraction(0.0) else: self.entry.set_progress_fraction(progress) def _set_address(self, uri): if uri is None: self.entry.props.address = "" else: self.entry.props.address = uri def __changed_cb(self, iconentry): # The WebEntry can be changed when we click on a link, then we # have to show the clear icon only if is the user who has # changed the entry if self.entry.has_focus(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_in_event_cb(self, entry, event): if not self._tabbed_view.is_current_page_pdf(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_out_event_cb(self, entry, event): if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self._show_reload_icon() def _show_no_icon(self): self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY) def _show_stop_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, "entry-stop") def _show_reload_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, "entry-refresh") def _show_clear_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, "entry-cancel") def _update_navigation_buttons(self): can_go_back = self._browser.can_go_back() self._back.props.sensitive = can_go_back can_go_forward = self._browser.can_go_forward() self._forward.props.sensitive = can_go_forward is_webkit_browser = isinstance(self._browser, Browser) self._link_add.props.sensitive = is_webkit_browser self._go_home.props.sensitive = is_webkit_browser if is_webkit_browser: self._reload_session_history() def _entry_activate_cb(self, entry): url = entry.props.text effective_url = self._tabbed_view.normalize_or_autosearch_url(url) self._browser.load_uri(effective_url) self._browser.loading_uri = effective_url self.entry.props.address = effective_url self._browser.grab_focus() def _go_home_cb(self, button): self.emit("go-home") def _go_library_cb(self, button): self.emit("go-library") def _set_home_cb(self, button): self._reset_home_menu.set_visible(True) self.emit("set-home") def _reset_home_cb(self, button): self._reset_home_menu.set_visible(False) self.emit("reset-home") def _go_to_JSshell_cb(self, button): self.emit("go-to-JSshell") def _get_shell_input_cb(self, button): self.emit("get-shell-input") def _go_back_cb(self, button): self._browser.go_back() def _go_forward_cb(self, button): self._browser.go_forward() def __uri_changed_cb(self, widget, param): self._set_address(widget.get_uri()) self._update_navigation_buttons() filepicker.cleanup_temp_files() def _stop_and_reload_cb(self, entry, icon_pos, button): if entry.has_focus() and not self._tabbed_view.is_current_page_pdf(): entry.set_text("") else: if self._loading: self._browser.stop_loading() else: self._browser.reload() def _set_loading(self, loading): self._loading = loading if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self.set_sensitive(True) self._show_reload_icon() else: self.set_sensitive(False) self._show_no_icon() def _reload_session_history(self): back_forward_list = self._browser.get_back_forward_list() item_index = 0 # The index of the history item # Clear menus in palettes: for box_menu in (self._back_box_menu, self._forward_box_menu): for menu_item in box_menu.get_children(): box_menu.remove(menu_item) def create_menu_item(history_item, item_index): """Create a MenuItem for the back or forward palettes.""" title = history_item.get_title() if not isinstance(title, unicode): title = unicode(title, "utf-8") # This is a fix until the Sugar MenuItem is fixed: menu_item = PaletteMenuItem(text_label=title) menu_item.connect("activate", self._history_item_activated_cb, item_index) return menu_item back_list = back_forward_list.get_back_list_with_limit(_MAX_HISTORY_ENTRIES) back_list.reverse() for item in back_list: menu_item = create_menu_item(item, item_index) self._back_box_menu.pack_end(menu_item, False, False, 0) menu_item.show() item_index += 1 # Increment the item index to count the current page: item_index += 1 forward_list = back_forward_list.get_forward_list_with_limit(_MAX_HISTORY_ENTRIES) forward_list.reverse() for item in forward_list: menu_item = create_menu_item(item, item_index) self._forward_box_menu.pack_start(menu_item, False, False, 0) menu_item.show() item_index += 1 def _history_item_activated_cb(self, menu_item, index): self._back.get_palette().popdown(immediate=True) self._forward.get_palette().popdown(immediate=True) self._browser.set_history_index(index) def _link_add_clicked_cb(self, button): self.emit("add-link") def save_as_pdf(self, widget): tmp_dir = os.path.join(self._activity.get_activity_root(), "tmp") fd, file_path = tempfile.mkstemp(dir=tmp_dir) os.close(fd) page = self._canvas.get_current_page() webview = self._canvas.get_children()[page].get_children()[0] operation = Gtk.PrintOperation.new() operation.set_export_filename(file_path) webview.get_main_frame().print_full(operation, Gtk.PrintOperationAction.EXPORT) client = GConf.Client.get_default() jobject = datastore.create() color = client.get_string("/desktop/sugar/user/color") try: jobject.metadata["title"] = _("Browse activity as PDF") jobject.metadata["icon-color"] = color jobject.metadata["mime_type"] = "application/pdf" jobject.file_path = file_path datastore.write(jobject) finally: self.__pdf_alert(jobject.object_id) jobject.destroy() del jobject def __pdf_alert(self, object_id): alert = Alert() alert.props.title = _("Page saved") alert.props.msg = _("The page has been saved as PDF to journal") alert.add_button(Gtk.ResponseType.APPLY, _("Show in Journal"), Icon(icon_name="zoom-activity")) alert.add_button(Gtk.ResponseType.OK, _("Ok"), Icon(icon_name="dialog-ok")) # Remove other alerts for alert in self._activity._alerts: self._activity.remove_alert(alert) self._activity.add_alert(alert) alert.connect("response", self.__pdf_response_alert, object_id) alert.show_all() def __pdf_response_alert(self, alert, response_id, object_id): if response_id is Gtk.ResponseType.APPLY: activity.show_object_in_journal(object_id) self._activity.remove_alert(alert)
class TextAttributesToolbar(Gtk.Toolbar): def __init__(self, main_area): Gtk.Toolbar.__init__(self) self._main_area = main_area self._font_list = ['ABC123', 'Sans', 'Serif', 'Monospace', 'Symbol'] self._font_sizes = ['8', '9', '10', '11', '12', '14', '16', '20', '22', '24', '26', '28', '36', '48', '72'] self.font_button = ToolButton('font-text') self.font_button.set_tooltip(_('Select font')) self.font_button.connect('clicked', self.__font_selection_cb) self.insert(self.font_button, -1) self._setup_font_palette() self.insert(Gtk.SeparatorToolItem(), -1) self.font_size_up = ToolButton('resize+') self.font_size_up.set_tooltip(_('Bigger')) self.font_size_up.connect('clicked', self.__font_sizes_cb, True) self.insert(self.font_size_up, -1) if len(self._main_area.selected) > 0: font_size = self._main_area.font_size else: font_size = utils.default_font_size self.size_label = Gtk.Label(str(font_size)) self.size_label.show() toolitem = Gtk.ToolItem() toolitem.add(self.size_label) toolitem.show() self.insert(toolitem, -1) self.font_size_down = ToolButton('resize-') self.font_size_down.set_tooltip(_('Smaller')) self.font_size_down.connect('clicked', self.__font_sizes_cb, False) self.insert(self.font_size_down, -1) self.insert(Gtk.SeparatorToolItem(), -1) self.bold = ToolButton('bold-text') self.bold.set_tooltip(_('Bold')) self.bold.connect('clicked', self.__bold_cb) self.insert(self.bold, -1) self.italics = ToolButton('italics-text') self.italics.set_tooltip(_('Italics')) self.italics.connect('clicked', self.__italics_cb) self.insert(self.italics, -1) self.underline = ToolButton('underline-text') self.underline.set_tooltip(_('Underline')) self.underline.connect('clicked', self.__underline_cb) self.insert(self.underline, -1) foreground_color = ColorToolButton() foreground_color.set_title(_('Set font color')) foreground_color.connect('color-set', self.__foreground_color_cb) self.insert(foreground_color, -1) bakground_color = ColorToolButton() bakground_color.set_title(_('Set background color')) bakground_color.connect('color-set', self.__background_color_cb) bakground_color.set_color(Gdk.Color(65535, 65535, 65535)) self.insert(bakground_color, -1) self.show_all() def __font_selection_cb(self, widget): if self._font_palette: if not self._font_palette.is_up(): self._font_palette.popup(immediate=True, state=self._font_palette.SECONDARY) else: self._font_palette.popdown(immediate=True) return def _init_font_list(self): self._font_white_list = [] self._font_white_list.extend(DEFAULT_FONTS) # check if there are a user configuration file if not os.path.exists(USER_FONTS_FILE_PATH): # verify if exists a file in /etc if os.path.exists(GLOBAL_FONTS_FILE_PATH): shutil.copy(GLOBAL_FONTS_FILE_PATH, USER_FONTS_FILE_PATH) if os.path.exists(USER_FONTS_FILE_PATH): # get the font names in the file to the white list fonts_file = open(USER_FONTS_FILE_PATH) # get the font names in the file to the white list for line in fonts_file: self._font_white_list.append(line.strip()) # monitor changes in the file gio_fonts_file = Gio.File.new_for_path(USER_FONTS_FILE_PATH) self.monitor = gio_fonts_file.monitor_file(0, None) self.monitor.set_rate_limit(5000) self.monitor.connect('changed', self._reload_fonts) def _reload_fonts(self, monitor, gio_file, other_file, event): if event != Gio.FileMonitorEvent.CHANGES_DONE_HINT: return self._font_white_list = [] self._font_white_list.extend(DEFAULT_FONTS) fonts_file = open(USER_FONTS_FILE_PATH) for line in fonts_file: self._font_white_list.append(line.strip()) # update the menu for child in self._font_palette.menu.get_children(): self._font_palette.menu.remove(child) child = None context = self.get_pango_context() tmp_list = [] for family in context.list_families(): name = family.get_name() if name in self._font_white_list: tmp_list.append(name) for font in sorted(tmp_list): menu_item = MyMenuItem(image=FontImage(font.replace(' ', '-')), text_label=font) menu_item.connect('activate', self.__font_selected_cb, font) self._font_palette.menu.append(menu_item) menu_item.show() return False def _setup_font_palette(self): self._init_font_list() context = self._main_area.pango_context for family in context.list_families(): name = Pango.FontDescription(family.get_name()).to_string() if name not in self._font_list and \ name in self._font_white_list: self._font_list.append(name) self._font_palette = self.font_button.get_palette() for font in sorted(self._font_list): menu_item = MyMenuItem(image=FontImage(font.replace(' ', '-')), text_label=font) menu_item.connect('activate', self.__font_selected_cb, font) self._font_palette.menu.append(menu_item) menu_item.show() def __font_selected_cb(self, widget, font_name): if not hasattr(self._main_area, 'font_name'): return if len(self._main_area.selected) > 0: font_size = self._main_area.font_size else: font_size = utils.default_font_size self._main_area.set_font(font_name, font_size) self._main_area.font_name = font_name self._main_area.font_size = font_size def __attribute_values(self): thought = self._main_area.selected[0] return thought.attributes.copy() def __font_sizes_cb(self, button, increase): if not hasattr(self._main_area, 'font_size'): return if len(self._main_area.selected) < 1: return font_size = self._main_area.font_size if font_size in self._font_sizes: i = self._font_sizes.index(font_size) if increase: if i < len(self._font_sizes) - 2: i += 1 else: if i > 0: i -= 1 else: i = self._font_sizes.index(utils.default_font_size) font_size = self._font_sizes[i] self.size_label.set_text(str(font_size)) self.font_size_down.set_sensitive(i != 0) self.font_size_up.set_sensitive(i < len(self._font_sizes) - 2) self._main_area.set_font(self._main_area.font_name, font_size) def __bold_cb(self, button): if len(self._main_area.selected) < 1: return value = not self.__attribute_values()["bold"] self._main_area.set_bold(value) def __italics_cb(self, button): if len(self._main_area.selected) < 1: return value = not self.__attribute_values()["italic"] self._main_area.set_italics(value) def __underline_cb(self, button): if len(self._main_area.selected) < 1: return value = not self.__attribute_values()["underline"] self._main_area.set_underline(value) def __foreground_color_cb(self, button): color = button.get_color() self._main_area.set_foreground_color(color) def __background_color_cb(self, button): color = button.get_color() self._parent._main_area.set_background_color(color) def change_active_font(self): # TODO: update the toolbar return
class ReadSDComics(activity.Activity): __gsignals__ = { 'go-fullscreen': (GObject.SignalFlags.RUN_FIRST, None, ([])) } def __init__(self, handle): "The entry point to the Activity" activity.Activity.__init__(self, handle) self._object_id = handle.object_id self.zoom_image_to_fit = True self.total_pages = 0 self.connect("draw", self.__draw_cb) self.connect("delete_event", self.delete_cb) if _NEW_TOOLBAR_SUPPORT: self.create_new_toolbar() else: self.create_old_toolbar() self.scrolled = Gtk.ScrolledWindow() self.scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self.scrolled.props.shadow_type = Gtk.ShadowType.NONE self.image = Gtk.Image() self.eventbox = Gtk.EventBox() self.eventbox.add(self.image) self.image.show() self.eventbox.show() self.scrolled.add_with_viewport(self.eventbox) self.eventbox.set_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.BUTTON_PRESS_MASK) self.eventbox.set_can_focus(True) self.eventbox.connect("key_press_event", self.keypress_cb) self.eventbox.connect("button_press_event", self.buttonpress_cb) self._filechooser = Gtk.FileChooserWidget( action=Gtk.FileChooserAction.OPEN) filter = Gtk.FileFilter() filter.add_mime_type('application/zip') filter.add_mime_type('application/x-cbz') self._filechooser.set_filter(filter) self._filechooser.set_current_folder("/media") self.copy_button = Gtk.Button(_("Read Comic")) self.copy_button.connect('clicked', self.select_comic_path) self.copy_button.show() self._filechooser.set_extra_widget(self.copy_button) preview = Gtk.Image() self._filechooser.set_preview_widget(preview) self._filechooser.connect("update-preview", self.update_preview_cb, preview) vbox = Gtk.VBox() vbox.pack_start(self.scrolled, True, True, 0) vbox.pack_end(self._filechooser, True, True, 0) self.set_canvas(vbox) if self._object_id is None: self.scrolled.hide() self._filechooser.show() else: self.scrolled.show() self._filechooser.hide() vbox.show() self.page = 0 self.saved_screen_width = 0 self.eventbox.grab_focus() self.hidden_cursor = Gdk.Cursor.new(Gdk.CursorType.BLANK_CURSOR) self.cursor_visible = True self.link = None self._close_requested = False def select_comic_path(self, widget, data=None): filename = self._filechooser.get_filename() self._filechooser.hide() self.scrolled.show() self.link = filename self.metadata['title'] = self.make_new_filename(self.link) self._load_document(filename) def create_old_toolbar(self): toolbox = activity.ActivityToolbox(self) activity_toolbar = toolbox.get_activity_toolbar() activity_toolbar.keep.props.visible = False activity_toolbar.share.props.visible = False self.read_toolbar = ReadToolbar() toolbox.add_toolbar(_('Read'), self.read_toolbar) self.read_toolbar.show() self.read_toolbar.set_activity(self) self.view_toolbar = ViewToolbar() toolbox.add_toolbar(_('View'), self.view_toolbar) self.view_toolbar.set_activity(self) self.view_toolbar.connect('go-fullscreen', self.__view_toolbar_go_fullscreen_cb) self.view_toolbar.show() self.set_toolbox(toolbox) toolbox.show() # start on the read toolbar self.toolbox.set_current_toolbar(_TOOLBAR_READ) def update_preview_cb(self, file_chooser, preview): filename = file_chooser.get_preview_filename() try: file_mimetype = mime.get_for_file(filename) if file_mimetype == 'application/x-cbz' or file_mimetype == 'application/zip': fname = self.extract_image(filename) pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(fname, style.zoom(320), style.zoom(240)) preview.set_from_pixbuf(pixbuf) have_preview = True os.remove(fname) else: have_preview = False except: have_preview = False file_chooser.set_preview_widget_active(have_preview) return def extract_image(self, filename): zf = zipfile.ZipFile(filename, 'r') image_files = zf.namelist() image_files.sort() file_to_extract = image_files[0] extract_new_filename = self.make_new_filename(file_to_extract) if extract_new_filename is None or extract_new_filename == '': # skip over directory name if the images are in a subdirectory. file_to_extract = image_files[1] extract_new_filename = self.make_new_filename(file_to_extract) if len(image_files) > 0: if self.save_extracted_file(zf, file_to_extract): fname = os.path.join(self.get_activity_root(), 'instance', extract_new_filename) return fname def create_new_toolbar(self): toolbar_box = ToolbarBox() activity_button = MyActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() self.connect('go-fullscreen', \ self.__view_toolbar_go_fullscreen_cb) self.back = ToolButton('go-previous') self.back.set_tooltip(_('Back')) self.back.props.sensitive = False palette = self.back.get_palette() self.menu_prev_page = MenuItem(text_label= _("Previous page")) palette.menu.append(self.menu_prev_page) self.menu_prev_page.show_all() self.back.connect('clicked', self.go_back_cb) self.menu_prev_page.connect('activate', self.go_back_cb) toolbar_box.toolbar.insert(self.back, -1) self.back.show() self.forward = ToolButton('go-next') self.forward.set_tooltip(_('Forward')) self.forward.props.sensitive = False palette = self.forward.get_palette() self.menu_next_page = MenuItem(text_label= _("Next page")) palette.menu.append(self.menu_next_page) self.menu_next_page.show_all() self.forward.connect('clicked', self.go_forward_cb) self.menu_next_page.connect('activate', self.go_forward_cb) toolbar_box.toolbar.insert(self.forward, -1) self.forward.show() num_page_item = Gtk.ToolItem() self.num_page_entry = Gtk.Entry() self.num_page_entry.set_text('0') self.num_page_entry.set_alignment(1) self.num_page_entry.connect('insert-text', self.__new_num_page_entry_insert_text_cb) self.num_page_entry.connect('activate', self.__new_num_page_entry_activate_cb) self.num_page_entry.set_width_chars(4) num_page_item.add(self.num_page_entry) self.num_page_entry.show() toolbar_box.toolbar.insert(num_page_item, -1) num_page_item.show() total_page_item = Gtk.ToolItem() self.total_page_label = Gtk.Label() self.total_page_label.set_text(' / 0') total_page_item.add(self.total_page_label) self.total_page_label.show() toolbar_box.toolbar.insert(total_page_item, -1) total_page_item.show() spacer = Gtk.SeparatorToolItem() toolbar_box.toolbar.insert(spacer, -1) spacer.show() self._zoom_out = ToolButton('zoom-out') self._zoom_out.set_tooltip(_('Zoom out')) self._zoom_out.connect('clicked', self._zoom_out_cb) toolbar_box.toolbar.insert(self._zoom_out, -1) self._zoom_out.props.sensitive = False self._zoom_out.show() self._zoom_in = ToolButton('zoom-in') self._zoom_in.set_tooltip(_('Zoom in')) self._zoom_in.connect('clicked', self._zoom_in_cb) toolbar_box.toolbar.insert(self._zoom_in, -1) self._zoom_in.props.sensitive = True self._zoom_in.show() self._fullscreen = ToolButton('view-fullscreen') self._fullscreen.set_tooltip(_('Fullscreen')) self._fullscreen.connect('clicked', self._fullscreen_cb) toolbar_box.toolbar.insert(self._fullscreen, -1) self._fullscreen.show() 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() def _zoom_in_cb(self, button): self._zoom_in.props.sensitive = False self._zoom_out.props.sensitive = True self.zoom_to_width() def _zoom_out_cb(self, button): self._zoom_in.props.sensitive = True self._zoom_out.props.sensitive = False self.zoom_to_fit() def enable_zoom_in(self): self._zoom_in.props.sensitive = True self._zoom_out.props.sensitive = False def enable_zoom_out(self): self._zoom_in.props.sensitive = False self._zoom_out.props.sensitive = True def _fullscreen_cb(self, button): self.emit('go-fullscreen') def __new_num_page_entry_insert_text_cb(self, entry, text, length, position): for char in text: if not re.match('[0-9,-.]', char): entry.emit_stop_by_name('insert-text') return True return False def __new_num_page_entry_activate_cb(self, entry): if entry.props.text: page = int(entry.props.text) - 1 else: page = 0 if page >= self.total_pages: page = self.total_pages - 1 elif page < 0: page = 0 self.set_current_page(page) self.show_page(page) entry.props.text = str(page + 1) self.update_nav_buttons() def go_back_cb(self, button): self.previous_page() def go_forward_cb(self, button): self.next_page() def update_nav_buttons(self): current_page = self.page self.back.props.sensitive = current_page > 0 self.forward.props.sensitive = \ current_page < self.total_pages - 1 self.num_page_entry.props.text = str(current_page + 1) self.total_page_label.props.label = \ ' / ' + str(self.total_pages) def set_total_pages(self, pages): self.total_pages = pages def setToggleButtonState(self,button,b,id): button.handler_block(id) button.set_active(b) button.handler_unblock(id) def buttonpress_cb(self, widget, event): widget.grab_focus() def __view_toolbar_go_fullscreen_cb(self, view_toolbar): self.fullscreen() def zoom_to_width(self): self.zoom_image_to_fit = False self.show_page(self.page) def zoom_to_fit(self): self.zoom_image_to_fit = True self.show_page(self.page) def keypress_cb(self, widget, event): "Respond when the user presses Escape or one of the arrow keys" keyname = Gdk.keyval_name(event.keyval) if keyname == 'Page_Up': self.previous_page() return True if keyname == 'Page_Down' : self.next_page() return True if keyname == 'KP_Right': self.scroll_down() return True if keyname == 'Down' or keyname == 'KP_Down': self.scroll_down() return True if keyname == 'Up' or keyname == 'KP_Up': self.scroll_up() return True if keyname == 'KP_Left': self.scroll_up() return True if keyname == 'KP_Home': if self.cursor_visible: self.window.set_cursor(self.hidden_cursor) self.cursor_visible = False else: self.window.set_cursor(None) self.cursor_visible = True return True if keyname == 'plus': self.view_toolbar.enable_zoom_out() self.zoom_to_width() return True if keyname == 'minus': self.view_toolbar.enable_zoom_in() self.zoom_to_fit() return True return False def scroll_down(self): v_adjustment = self.scrolled.get_vadjustment() if v_adjustment.value == v_adjustment.upper - v_adjustment.page_size: self.next_page() return if v_adjustment.value < v_adjustment.upper - v_adjustment.page_size: new_value = v_adjustment.value + v_adjustment.step_increment if new_value > v_adjustment.upper - v_adjustment.page_size: new_value = v_adjustment.upper - v_adjustment.page_size v_adjustment.value = new_value def scroll_up(self): v_adjustment = self.scrolled.get_vadjustment() if v_adjustment.value == v_adjustment.lower: self.previous_page() return if v_adjustment.value > v_adjustment.lower: new_value = v_adjustment.value - v_adjustment.step_increment if new_value < v_adjustment.lower: new_value = v_adjustment.lower v_adjustment.value = new_value def previous_page(self): page = self.page page=page-1 if page < 0: page=0 if self.save_extracted_file(self.zf, self.image_files[page]) == True: fname = os.path.join(self.get_activity_root(), 'instance', self.make_new_filename(self.image_files[page])) self.show_image(fname) os.remove(fname) v_adjustment = self.scrolled.get_vadjustment() v_adjustment.value = v_adjustment.upper - v_adjustment.page_size if _NEW_TOOLBAR_SUPPORT: self.set_current_page(page) else: self.read_toolbar.set_current_page(page) self.page = page def set_current_page(self, page): self.page = page if _NEW_TOOLBAR_SUPPORT: self.update_nav_buttons() def next_page(self): page = self.page page = page + 1 if page >= len(self.image_files): page=len(self.image_files) - 1 if self.save_extracted_file(self.zf, self.image_files[page]) == True: fname = os.path.join(self.get_activity_root(), 'instance', self.make_new_filename(self.image_files[page])) self.show_image(fname) os.remove(fname) v_adjustment = self.scrolled.get_vadjustment() v_adjustment.value = v_adjustment.lower if _NEW_TOOLBAR_SUPPORT: self.set_current_page(page) else: self.read_toolbar.set_current_page(page) self.page = page def __draw_cb(self, widget, cr): screen_width = Gdk.Screen.width() screen_height = Gdk.Screen.height() if self.saved_screen_width != screen_width and self.saved_screen_width != 0: self.show_page(self.page) self.saved_screen_width = screen_width return False def show_page(self, page): if self.save_extracted_file(self.zf, self.image_files[page]) == True: fname = os.path.join(self.get_activity_root(), 'instance', self.make_new_filename(self.image_files[page])) self.show_image(fname) os.remove(fname) def show_image(self, filename): "display a resized image in a full screen window" TOOLBOX_HEIGHT = 60 BORDER_WIDTH = 30 # get the size of the fullscreen display screen_width = Gdk.Screen.width() screen_width = screen_width - BORDER_WIDTH screen_height = Gdk.Screen.height() screen_height = screen_height - TOOLBOX_HEIGHT # get the size of the image. im = pygame.image.load(filename) image_width, image_height = im.get_size() getcontext().prec = 7 s_a_ratio = Decimal(screen_height) / Decimal(screen_width) i_a_ratio = Decimal(image_height) / Decimal(image_width) new_width = image_width new_height = image_height if self.zoom_image_to_fit == True: if s_a_ratio >= i_a_ratio: new_width = screen_width new_height = image_height * screen_width if image_width > 1: new_height /= image_width if new_height > screen_width: new_height *= screen_width if new_width > 1: new_height /= new_width new_width = screen_width else: new_height = screen_height new_width = image_width * screen_height if image_height > 1: new_width /= image_height if new_width > screen_height: new_width *= screen_height if new_height > 1: new_width /= new_height new_height = screen_height else: new_width = screen_width new_height = image_height * screen_width if image_width > 1: new_height /= image_width if new_height > screen_width: new_height *= screen_width if new_width > 1: new_height /= new_width new_width = screen_width pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename) scaled_buf = pixbuf.scale_simple(new_width, new_height, GdkPixbuf.InterpType.BILINEAR) self.image.set_from_pixbuf(scaled_buf) self.image.show() def save_extracted_file(self, zipfile, filename): "Extract the file to a temp directory for viewing" try: filebytes = zipfile.read(filename) except BadZipfile, err: print 'Error opening the zip file: %s' % (err) return False except KeyError, err: self._alert('Key Error', 'Zipfile key not found: ' + str(filename)) return
class PrimaryToolbar(ToolbarBase): __gtype_name__ = 'PrimaryToolbar' __gsignals__ = { 'add-link': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'remove-link': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'set-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'reset-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'go-library': (GObject.SignalFlags.RUN_FIRST, None, ([])), } def __init__(self, tabbed_view, act): ToolbarBase.__init__(self) self._url_toolbar = UrlToolbar() self._activity = act self.model = act.model self.model.link_removed_signal.connect(self.__link_removed_cb) self._tabbed_view = self._canvas = tabbed_view self._loading = False self._download_running_hid = None toolbar = self.toolbar activity_button = ActivityToolbarButton(self._activity) toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() ''' Disabled since the python gi bindings don't expose the critical WebKit2.PrintOperation.print function save_as_pdf = ToolButton('save-as-pdf') save_as_pdf.set_tooltip(_('Save page as pdf')) save_as_pdf.connect('clicked', self.save_as_pdf) activity_button.props.page.insert(separator, -1) activity_button.props.page.insert(save_as_pdf, -1) separator.show() save_as_pdf.show() ''' inspect_view = ToolButton('emblem-view-source') inspect_view.set_tooltip(_('Show Web Inspector')) inspect_view.connect('clicked', self.inspect_view) activity_button.props.page.insert(separator, -1) activity_button.props.page.insert(inspect_view, -1) separator.show() inspect_view.show() self._go_home = ToolButton('go-home') self._go_home.set_tooltip(_('Home page')) self._go_home.connect('clicked', self._go_home_cb) # add a menu to save the home page menu_box = PaletteMenuBox() self._go_home.props.palette.set_content(menu_box) menu_item = PaletteMenuItem() menu_item.set_label(_('Select as initial page')) menu_item.connect('activate', self._set_home_cb) menu_box.append_item(menu_item) self._reset_home_menu = PaletteMenuItem() self._reset_home_menu.set_label(_('Reset initial page')) self._reset_home_menu.connect('activate', self._reset_home_cb) menu_box.append_item(self._reset_home_menu) if os.path.isfile(LIBRARY_PATH): library_menu = PaletteMenuItem() library_menu.set_label(_('Library')) library_menu.connect('activate', self._go_library_cb) menu_box.append_item(library_menu) menu_box.show_all() # verify if the home page is configured client = GConf.Client.get_default() self._reset_home_menu.set_visible( client.get_string(HOME_PAGE_GCONF_KEY) is not None) toolbar.insert(self._go_home, -1) self._go_home.show() self.entry = WebEntry() self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-stop') self.entry.connect('icon-press', self._stop_and_reload_cb) self.entry.connect('activate', self._entry_activate_cb) self.entry.connect('focus-in-event', self.__focus_in_event_cb) self.entry.connect('focus-out-event', self.__focus_out_event_cb) self.entry.connect('key-press-event', self.__key_press_event_cb) self.entry.connect('changed', self.__changed_cb) # In an event box so that it can render the background entry_box = Gtk.EventBox() entry_box.add(self.entry) entry_box.show() self._entry_item = Gtk.ToolItem() self._entry_item.set_expand(True) self._entry_item.add(entry_box) self.entry.show() toolbar.insert(self._entry_item, -1) self._entry_item.show() self._back = ToolButton('go-previous-paired', accelerator='<ctrl>Left') self._back.set_tooltip(_('Back')) self._back.props.sensitive = False self._back.connect('clicked', self._go_back_cb) toolbar.insert(self._back, -1) self._back.show() palette = self._back.get_palette() self._back_box_menu = Gtk.VBox() self._back_box_menu.show() palette.set_content(self._back_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._forward = ToolButton('go-next-paired', accelerator='<ctrl>Right') self._forward.set_tooltip(_('Forward')) self._forward.props.sensitive = False self._forward.connect('clicked', self._go_forward_cb) toolbar.insert(self._forward, -1) self._forward.show() palette = self._forward.get_palette() self._forward_box_menu = Gtk.VBox() self._forward_box_menu.show() palette.set_content(self._forward_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._download_icon = ProgressToolButton( icon_name='emblem-downloads', tooltip=_('No Downloads Running')) toolbar.insert(self._download_icon, -1) self._download_icon.show() downloadmanager.connect_download_started(self.__download_started_cb) self._link_add = ToggleToolButton('emblem-favorite') self._link_add.set_accelerator('<ctrl>d') self._link_add.set_tooltip(_('Bookmark')) self._link_add_toggled_hid = \ self._link_add.connect('toggled', self.__link_add_toggled_cb) toolbar.insert(self._link_add, -1) self._link_add.show() self._toolbar_separator = Gtk.SeparatorToolItem() self._toolbar_separator.props.draw = False self._toolbar_separator.set_expand(True) self._stop_button = StopButton(self._activity) toolbar.insert(self._stop_button, -1) self._progress_listener = None self._browser = None self._loading_changed_hid = None self._progress_changed_hid = None self._session_history_changed_hid = None self._uri_changed_hid = None self._load_changed_hid = None self._security_status_changed_hid = None if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) tabbed_view.connect_after('switch-page', self.__switch_page_cb) tabbed_view.connect_after('page-added', self.__page_added_cb) Gdk.Screen.get_default().connect('size-changed', self.__screen_size_changed_cb) self._configure_toolbar() def __download_started_cb(self): if self._download_running_hid is None: self._download_running_hid = GLib.timeout_add( 80, self.__download_running_cb) def __download_running_cb(self): progress = downloadmanager.overall_downloads_progress() self._download_icon.update(progress) if downloadmanager.num_downloads() > 0: self._download_icon.props.tooltip = \ _('{}% Downloaded').format(int(progress*100)) return True else: self._download_running_hid = None self._download_icon.props.tooltip = _('No Downloads Running') return False def __key_press_event_cb(self, entry, event): self._tabbed_view.current_browser.loading_uri = entry.props.text def __switch_page_cb(self, tabbed_view, page, page_num): if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) def __page_added_cb(self, notebook, child, pagenum): self.entry._search_popdown() def _configure_toolbar(self, screen=None): # Adapt the toolbars for portrait or landscape mode. if screen is None: screen = Gdk.Screen.get_default() if screen.get_width() < screen.get_height(): if self._entry_item in self._url_toolbar.toolbar.get_children(): return self.toolbar.remove(self._entry_item) self._url_toolbar.toolbar.insert(self._entry_item, -1) separator_pos = len(self.toolbar.get_children()) - 1 self.toolbar.insert(self._toolbar_separator, separator_pos) self._toolbar_separator.show() self.pack_end(self._url_toolbar, True, True, 0) self._url_toolbar.show() else: if self._entry_item in self.toolbar.get_children(): return self.toolbar.remove(self._toolbar_separator) position = len(self.toolbar.get_children()) - 4 self._url_toolbar.toolbar.remove(self._entry_item) self.toolbar.insert(self._entry_item, position) self._toolbar_separator.hide() self.remove(self._url_toolbar) def __screen_size_changed_cb(self, screen): self._configure_toolbar(screen) def _connect_to_browser(self, browser): if self._browser is not None: self._browser.disconnect(self._uri_changed_hid) self._browser.disconnect(self._load_changed_hid) self._browser.disconnect(self._progress_changed_hid) self._browser.disconnect(self._security_status_changed_hid) self._browser = browser if not isinstance(self._browser, DummyBrowser): address = self._browser.props.uri or self._browser.loading_uri else: address = self._browser.props.uri self._set_address(address) self._set_progress(self._browser.props.estimated_load_progress) self._set_loading(self._browser.props.estimated_load_progress < 1.0) self._set_security_status(self._browser.security_status) is_webkit_browser = isinstance(self._browser, Browser) self.entry.props.editable = is_webkit_browser self._uri_changed_hid = self._browser.connect( 'notify::uri', self.__uri_changed_cb) self._load_changed_hid = self._browser.connect( 'load-changed', self.__load_changed_cb) self._progress_changed_hid = self._browser.connect( 'notify::estimated-load-progress', self.__progress_changed_cb) self._security_status_changed_hid = self._browser.connect( 'security-status-changed', self.__security_status_changed_cb) self._update_navigation_buttons() def __security_status_changed_cb(self, widget): self._set_security_status(widget.security_status) def __progress_changed_cb(self, widget, param): self._set_progress(widget.props.estimated_load_progress) self._set_loading(widget.props.estimated_load_progress < 1.0) def _set_security_status(self, security_status): # Display security status as a lock icon in the left side of # the URL entry. if security_status is None: self.entry.set_icon_from_pixbuf( iconentry.ICON_ENTRY_PRIMARY, None) elif security_status == Browser.SECURITY_STATUS_SECURE: self.entry.set_icon_from_name( iconentry.ICON_ENTRY_PRIMARY, 'channel-secure-symbolic') elif security_status == Browser.SECURITY_STATUS_INSECURE: self.entry.set_icon_from_name( iconentry.ICON_ENTRY_PRIMARY, 'channel-insecure-symbolic') def _set_progress(self, progress): if progress == 1.0: self.entry.set_progress_fraction(0.0) else: self.entry.set_progress_fraction(progress) def _set_address(self, uri): if uri is None: self.entry.props.address = '' else: self.entry.props.address = uri def __changed_cb(self, iconentry): # The WebEntry can be changed when we click on a link, then we # have to show the clear icon only if is the user who has # changed the entry if self.entry.has_focus(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_in_event_cb(self, entry, event): if not self._tabbed_view.is_current_page_pdf(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_out_event_cb(self, entry, event): if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self._show_reload_icon() def _show_no_icon(self): self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY) def _show_stop_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-stop') def _show_reload_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-refresh') def _show_clear_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-cancel') def _update_navigation_buttons(self): can_go_back = self._browser.can_go_back() self._back.props.sensitive = can_go_back can_go_forward = self._browser.can_go_forward() self._forward.props.sensitive = can_go_forward is_webkit_browser = isinstance(self._browser, Browser) self._go_home.props.sensitive = is_webkit_browser if is_webkit_browser: self._reload_session_history() with self._link_add.handler_block(self._link_add_toggled_hid): uri = self._browser.get_uri() self._link_add.props.active = self.model.has_link(uri) def __link_removed_cb(self, model): self._update_navigation_buttons() def _entry_activate_cb(self, entry): url = entry.props.text effective_url = self._tabbed_view.normalize_or_autosearch_url(url) self._browser.load_uri(effective_url) self._browser.loading_uri = effective_url self.entry.props.address = effective_url self._browser.grab_focus() def _go_home_cb(self, button): self.emit('go-home') def _go_library_cb(self, button): self.emit('go-library') def _set_home_cb(self, button): self._reset_home_menu.set_visible(True) self.emit('set-home') def _reset_home_cb(self, button): self._reset_home_menu.set_visible(False) self.emit('reset-home') def _go_back_cb(self, button): self._browser.go_back() def _go_forward_cb(self, button): self._browser.go_forward() def __uri_changed_cb(self, widget, param): self._set_address(widget.get_uri()) self._update_navigation_buttons() filepicker.cleanup_temp_files() def __load_changed_cb(self, widget, event): self._update_navigation_buttons() def _stop_and_reload_cb(self, entry, icon_pos, button): if entry.has_focus() and \ not self._tabbed_view.is_current_page_pdf(): entry.set_text('') else: if self._loading: self._browser.stop_loading() else: self._browser.reload() def _set_loading(self, loading): self._loading = loading if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self._set_sensitive(True) self._show_reload_icon() else: self._set_sensitive(False) self._show_no_icon() def _set_sensitive(self, value): for widget in self.toolbar: if widget not in (self._stop_button, self._link_add): widget.set_sensitive(value) def _reload_session_history(self): back_forward_list = self._browser.get_back_forward_list() item_index = 0 # The index of the history item # Clear menus in palettes: for box_menu in (self._back_box_menu, self._forward_box_menu): for menu_item in box_menu.get_children(): box_menu.remove(menu_item) def create_menu_item(history_item): """Create a MenuItem for the back or forward palettes.""" title = history_item.get_title() or _('No Title') if not isinstance(title, unicode): title = unicode(title, 'utf-8') # This is a fix until the Sugar MenuItem is fixed: menu_item = PaletteMenuItem(text_label=title) menu_item.connect('activate', self._history_item_activated_cb, history_item) return menu_item back_list = back_forward_list.get_back_list_with_limit( _MAX_HISTORY_ENTRIES) back_list.reverse() for item in back_list: menu_item = create_menu_item(item) self._back_box_menu.pack_end(menu_item, False, False, 0) menu_item.show() item_index += 1 # Increment the item index to count the current page: item_index += 1 forward_list = back_forward_list.get_forward_list_with_limit( _MAX_HISTORY_ENTRIES) forward_list.reverse() for item in forward_list: menu_item = create_menu_item(item) self._forward_box_menu.pack_start(menu_item, False, False, 0) menu_item.show() item_index += 1 def _history_item_activated_cb(self, menu_item, history_item): self._back.get_palette().popdown(immediate=True) self._forward.get_palette().popdown(immediate=True) # self._browser.set_history_index(index) self._browser.go_to_back_forward_list_item(history_item) def __link_add_toggled_cb(self, button): if button.props.active: self.emit('add-link') else: self.emit('remove-link') def inspect_view(self, button): page = self._canvas.get_current_page() webview = self._canvas.get_children()[page].props.browser # If get_inspector returns None, it is not a real WebView inspector = webview.get_inspector() if inspector is not None: # Inspector window will be blank if disabled web_settings = webview.get_settings() web_settings.props.enable_developer_extras = True inspector.show() inspector.attach() '''
class TuningToolbar(Gtk.Toolbar): ''' The toolbar for tuning instruments ''' def __init__(self, activity): super(type(self), self).__init__() self.activity = activity self._show_tuning_line = False self._updating_note = True self._tuning_tool = None self._instrument_button = ToolButton('instruments') self._instrument_button.set_tooltip(_('Tune an instrument.')) self._instrument_button.connect('clicked', self._button_selection_cb) self.insert(self._instrument_button, -1) self._setup_instrument_palette() separator = Gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._note = 'A' self._notes_button = ToolButton('notes') self._notes_button.set_tooltip(_('Notes')) self._notes_button.connect('clicked', self._button_selection_cb) self.insert(self._notes_button, -1) self._setup_notes_palette() self._octave = 4 self._octaves_button = ToolButton('octaves') self._octaves_button.set_tooltip(_('Octaves')) self._octaves_button.connect('clicked', self._button_selection_cb) self.insert(self._octaves_button, -1) self._setup_octaves_palette() # The entry is used to display a note or for direct user input self._freq_entry = Gtk.Entry() self._freq_entry.set_text('440') # A self._freq_entry_changed_id = self._freq_entry.connect( 'changed', self._update_freq_entry) if hasattr(self._freq_entry, 'set_tooltip_text'): self._freq_entry.set_tooltip_text( _('Enter a frequency to display.')) self._freq_entry.set_width_chars(8) self._freq_entry.show() toolitem = Gtk.ToolItem() toolitem.add(self._freq_entry) self.insert(toolitem, -1) toolitem.show() self._new_tuning_line = ToolButton('tuning-tools') self._new_tuning_line.show() self.insert(self._new_tuning_line, -1) self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._new_tuning_line.connect('clicked', self.tuning_line_cb) separator = Gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._harmonic = ToolButton('harmonics') self._harmonic.show() self.insert(self._harmonic, -1) self._harmonic.set_tooltip(_('Show harmonics.')) self._harmonic.connect('clicked', self.harmonic_cb) separator = Gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._play_tone = ToolButton('media-playback-start') self._play_tone.show() self.insert(self._play_tone, -1) self._play_tone.set_tooltip(_('Play a note.')) self._play_tone.connect('clicked', self.play_cb) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.insert(separator, -1) self.label = Gtk.Label(label='') self.label.set_use_markup(True) self.label.show() toolitem = Gtk.ToolItem() toolitem.add(self.label) self.insert(toolitem, -1) toolitem.show() self.show_all() def _update_note(self): ''' Calculate the frequency based on note and octave ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar return i = self._octave * 12 + NOTES.index(self._note) freq = A0 * pow(TWELTHROOT2, i) self._updating_note = True self._freq_entry.set_text('%0.3f' % (freq)) self.label.set_markup(SPAN % (style.COLOR_WHITE.get_html(), self._note + str(self._octave))) if self._show_tuning_line: self.activity.wave.tuning_line = freq return def _update_freq_entry(self, widget): # Calculate a note from a frequency if not self._updating_note: # Only if user types in a freq. try: freq = float(self._freq_entry.get_text()) # Only consider notes in piano range if freq < A0 * 0.97: self.label.set_text('< A0') return if freq > C8 * 1.03: self.label.set_text('> C8') return self.label.set_markup(freq_note(freq, flatsharp=True)) except ValueError: return self._updating_note = False def _button_selection_cb(self, widget): palette = widget.get_palette() if palette: if not palette.is_up(): palette.popup(immediate=True) else: palette.popdown(immediate=True) return def _setup_notes_palette(self): self._notes_palette = self._notes_button.get_palette() for note in NOTES: menu_item = MenuItem(icon_name='', text_label=note) menu_item.connect('activate', self._note_selected_cb, note) self._notes_palette.menu.append(menu_item) menu_item.show() def _note_selected_cb(self, widget, note): self._note = note self._update_note() def _setup_octaves_palette(self): self._octaves_palette = self._octaves_button.get_palette() for octave in range(9): menu_item = MenuItem(icon_name='', text_label=str(octave)) menu_item.connect('activate', self._octave_selected_cb, octave) self._octaves_palette.menu.append(menu_item) menu_item.show() def _octave_selected_cb(self, widget, octave): self._octave = octave self._update_note() def _setup_instrument_palette(self): self.instrument_palette = self._instrument_button.get_palette() self.instrument = [] for k in INSTRUMENT_DICT.keys(): self.instrument.append(k) menu_item = MenuItem(icon_name='', text_label=k) menu_item.connect('activate', self.instrument_selected_cb, k) self.instrument_palette.menu.append(menu_item) menu_item.show() def instrument_selected_cb(self, button, instrument): ''' Callback for instrument control ''' logging.debug(instrument) if self._tuning_tool is not None: self.remove(self._tuning_tool) if instrument == _('None'): self.activity.wave.instrument = None # Remove any previous tuning button if hasattr(self, '_tuning_button'): self._tuning_button.destroy() # Restore the notes, octaves buttons if hasattr(self, '_notes_button'): self.insert(self._notes_button, 2) self.insert(self._octaves_button, 3) return self.remove(self._notes_button) self.remove(self._octaves_button) self.activity.wave.instrument = instrument # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Add a Tuning palette for this instrument self._tuning_button = ToolButton('notes') self._tuning_button.set_tooltip(instrument) self._tuning_button.connect('clicked', self._button_selection_cb) self.insert(self._tuning_button, 1) self._setup_tuning_palette(instrument) def _setup_tuning_palette(self, instrument): self._tuning_palette = self._tuning_button.get_palette() self.tuning = [] self.tuning.append(_('All notes')) menu_item = MenuItem(icon_name='', text_label=_('All notes')) menu_item.connect('activate', self._tuning_selected_cb, instrument, -1) self._tuning_palette.menu.append(menu_item) menu_item.show() for i, f in enumerate(INSTRUMENT_DICT[instrument]): self.tuning.append(freq_note(f)) menu_item = MenuItem(icon_name='', text_label=freq_note(f)) menu_item.connect('activate', self._tuning_selected_cb, instrument, i) self._tuning_palette.menu.append(menu_item) menu_item.show() self.show_all() def _tuning_selected_cb(self, widget, instrument, fidx): ''' Update note ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar? return if instrument not in INSTRUMENT_DICT: return if fidx == -1: # All notes self.activity.wave.instrument = instrument self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: freq = INSTRUMENT_DICT[instrument][fidx] self.activity.wave.instrument = None self.activity.wave.tuning_line = freq self._new_tuning_line.set_icon('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True self._updating_note = False def harmonic_cb(self, *args): ''' Callback for harmonics control ''' self.activity.wave.harmonics = not self.activity.wave.harmonics if self.activity.wave.harmonics: self._harmonic.set_icon_name('harmonics-off') self._harmonic.set_tooltip(_('Hide harmonics.')) if self.activity.wave.instrument is None and \ self.activity.wave.tuning_line == 0.0: self._load_tuning_line() else: self._harmonic.set_icon_name('harmonics') self._harmonic.set_tooltip(_('Show harmonics.')) def tuning_line_cb(self, *args): ''' Callback for tuning insert ''' if self._show_tuning_line: self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon_name('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: self._load_tuning_line() def _load_tuning_line(self): ''' Read the freq entry and use value to set tuning line ''' freq = self._freq_entry.get_text() try: self.activity.wave.tuning_line = float(freq) if freq < 0: freq = -freq self._new_tuning_line.set_icon_name('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True except ValueError: self.activity.wave.tuning_line = 0.0 self._freq_entry.set_text('0') # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() def play_cb(self, *args): ''' Save settings, turn off display, and then play a tone at the current frequency ''' channels = [] for c in range(self.activity.audiograb.channels): channels.append(self.activity.wave.get_visibility(channel=c)) self.activity.wave.set_visibility(False, channel=c) wave_status = self.activity.wave.get_active() self.activity.wave.set_context_off() self.activity.wave.set_active(False) if self.activity.hw in [XO4, XO175]: self.activity.audiograb.stop_grabbing() freq = float(self._freq_entry.get_text()) GLib.timeout_add(200, self.play_sound, freq, channels, wave_status) def play_sound(self, freq, channels, wave_status): ''' Play the sound and then restore wave settings ''' self._play_sinewave(freq, 5000, 1) if self.activity.hw in [XO4, XO175]: self.activity.sensor_toolbar.set_mode('sound') self.activity.sensor_toolbar.set_sound_context() self.activity.audiograb.start_grabbing() for c in range(self.activity.audiograb.channels): self.activity.wave.set_visibility(channels[c], channel=c) self.activity.wave.set_context_on() self.activity.wave.set_active(wave_status) def _play_sinewave(self, pitch, amplitude=5000, duration=1): """ Create a Csound score to play a sine wave. """ self.orchlines = [] self.scorelines = [] self.instrlist = [] try: pitch = abs(float(pitch)) amplitude = abs(float(amplitude)) duration = abs(float(duration)) except ValueError: logging.error('bad args to _play_sinewave') return self._prepare_sinewave(pitch, amplitude, duration) path = os.path.join(self.activity.get_activity_root(), 'instance', 'tmp.csd') # Create a csound file from the score. self._audio_write(path) # Play the csound file. check_output(['csound', path], 'call to csound failed?') def _prepare_sinewave(self, pitch, amplitude, duration, starttime=0, pitch_envelope=99, amplitude_envelope=100, instrument=1): pitenv = pitch_envelope ampenv = amplitude_envelope if 1 not in self.instrlist: self.orchlines.append("instr 1\n") self.orchlines.append("kpitenv oscil 1, 1/p3, p6\n") self.orchlines.append("aenv oscil 1, 1/p3, p7\n") self.orchlines.append("asig oscil p5*aenv, p4*kpitenv, p8\n") self.orchlines.append("out asig\n") self.orchlines.append("endin\n\n") self.instrlist.append(1) self.scorelines.append("i1 %s %s %s %s %s %s %s\n" % (str(starttime), str(duration), str(pitch), str(amplitude), str(pitenv), str(ampenv), str(instrument))) def _audio_write(self, file): """ Compile a .csd file. """ csd = open(file, "w") csd.write("<CsoundSynthesizer>\n\n") csd.write("<CsOptions>\n") csd.write("-+rtaudio=alsa -odevaudio -m0 -d -b256 -B512\n") csd.write("</CsOptions>\n\n") csd.write("<CsInstruments>\n\n") csd.write("sr=16000\n") csd.write("ksmps=50\n") csd.write("nchnls=1\n\n") for line in self.orchlines: csd.write(line) csd.write("\n</CsInstruments>\n\n") csd.write("<CsScore>\n\n") csd.write("f1 0 2048 10 1\n") csd.write("f2 0 2048 10 1 0 .33 0 .2 0 .143 0 .111\n") csd.write("f3 0 2048 10 1 .5 .33 .25 .2 .175 .143 .125 .111 .1\n") csd.write("f10 0 2048 10 1 0 0 .3 0 .2 0 0 .1\n") csd.write("f99 0 2048 7 1 2048 1\n") csd.write("f100 0 2048 7 0. 10 1. 1900 1. 132 0.\n") csd.write(self.scorelines.pop()) csd.write("e\n") csd.write("\n</CsScore>\n") csd.write("\n</CsoundSynthesizer>") csd.close()
class InstrumentToolbar(Gtk.Toolbar): ''' The toolbar for adding new instruments ''' def __init__(self, activity): super(type(self), self).__init__() self.activity = activity self.new_instruments = [] self._name_entry = Gtk.Entry() self._name_entry.set_text(_('my instrument')) self._name_entry_changed_id = self._name_entry.connect( 'changed', self.update_name_entry) if hasattr(self._name_entry, 'set_tooltip_text'): self._name_entry.set_tooltip_text( _('Enter instrument name.')) self._name_entry.set_width_chars(24) self._name_entry.show() toolitem = Gtk.ToolItem() toolitem.add(self._name_entry) self.insert(toolitem, -1) toolitem.show() self._note = 'A' self._notes_button = ToolButton('notes') self._notes_button.set_tooltip(_('Notes')) self._notes_button.connect('clicked', self._button_selection_cb) self.insert(self._notes_button, -1) self._setup_notes_palette() self._notes_button.show() self._octave = 4 self._octaves_button = ToolButton('octaves') self._octaves_button.set_tooltip(_('Octaves')) self._octaves_button.connect('clicked', self._button_selection_cb) self.insert(self._octaves_button, -1) self._setup_octaves_palette() self._octaves_button.show() self._new_note = ToolButton('list-add') self._new_note.show() self.insert(self._new_note, -1) self._new_note.set_tooltip(_('Add a new note.')) self._new_note.connect('clicked', self.new_note_cb) self._new_note.show() def _button_selection_cb(self, widget): palette = widget.get_palette() if palette: if not palette.is_up(): palette.popup(immediate=True) else: palette.popdown(immediate=True) return def _setup_notes_palette(self): self._notes_palette = self._notes_button.get_palette() for note in NOTES: menu_item = MenuItem(icon_name='', text_label=note) menu_item.connect('activate', self._note_selected_cb, note) self._notes_palette.menu.append(menu_item) menu_item.show() def _note_selected_cb(self, widget, note): self._note = note def _setup_octaves_palette(self): self._octaves_palette = self._octaves_button.get_palette() for octave in range(9): menu_item = MenuItem(icon_name='', text_label=str(octave)) menu_item.connect('activate', self._octave_selected_cb, octave) self._octaves_palette.menu.append(menu_item) menu_item.show() def _octave_selected_cb(self, widget, octave): self._octave = octave def update_name_entry(self, *args): ''' Add name to INSTRUMENT_DICT and combo box ''' # Wait until a note has been added... return def new_note_cb(self, *args): ''' Add a new note to instrument tuning list ''' name = self._name_entry.get_text() if name not in INSTRUMENT_DICT: INSTRUMENT_DICT[name] = [] self.activity.tuning_toolbar.instrument.append(name) menu_item = MenuItem(icon_name='', text_label=name) menu_item.connect( 'activate', self.activity.tuning_toolbar.instrument_selected_cb, name) self.activity.tuning_toolbar.instrument_palette.menu.append( menu_item) menu_item.show() self.new_instruments.append(name) freq = A0 * pow(TWELTHROOT2, self._octave * 12 + NOTES.index(self._note)) if freq not in INSTRUMENT_DICT[name]: INSTRUMENT_DICT[name].append(freq)
def __init__(self): super(PyApp, self).__init__() self.set_title('Palettes') self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) vbox = Gtk.VBox() toolbarbox = ToolbarBox() vbox.add(toolbarbox) toolbar = toolbarbox.toolbar color_button = ColorToolButton() toolbar.insert(color_button, -1) button = ToolButton('list-add') button.set_tooltip('Palette with widgets') toolbar.insert(button, -1) palette = button.get_palette() palette_box = Gtk.VBox() palette.set_content(palette_box) checkbutton1 = Gtk.CheckButton(label='Option 1') palette_box.pack_start(checkbutton1, False, False, 0) checkbutton2 = Gtk.CheckButton(label='Option 2') palette_box.pack_start(checkbutton2, False, False, 0) checkbutton3 = Gtk.CheckButton(label='Option 3') palette_box.pack_start(checkbutton3, False, False, 0) separator = Gtk.VSeparator() palette_box.pack_start(separator, False, False, 0) radio_button1 = Gtk.RadioButton(label='Option 1') palette_box.pack_start(radio_button1, False, False, 0) radio_button2 = Gtk.RadioButton(label='Option 2', group=radio_button1) palette_box.pack_start(radio_button2, False, False, 0) radio_button3 = Gtk.RadioButton(label='Option 3', group=radio_button1) palette_box.pack_start(radio_button3, False, False, 0) palette_box.show_all() button = ToolButton(icon_name='format-justify-fill') button.props.tooltip = 'Select list' button.props.hide_tooltip_on_click = False button.palette_invoker.props.toggle_palette = True toolbar.insert(button, -1) menu_box = PaletteMenuBox() button.props.palette.set_content(menu_box) menu_box.show() menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-fill') menu_box.append_item(menu_item) menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-center') menu_box.append_item(menu_item) menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-left') menu_box.append_item(menu_item) menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-right') menu_box.append_item(menu_item) self.add(vbox) self.show_all() self.connect('destroy', Gtk.main_quit)
class ViewToolbar(Gtk.Toolbar): __gtype_name__ = 'ViewToolbar' __gsignals__ = { 'go-fullscreen': (GObject.SignalFlags.RUN_FIRST, None, ([])), } def __init__(self): Gtk.Toolbar.__init__(self) self._view = None self._bookmarkmanager = None self._update_offset = True self._zoom_out = ToolButton('zoom-out') self._zoom_out.set_tooltip(_('Zoom out')) self._zoom_out.connect('clicked', self._zoom_out_cb) self.insert(self._zoom_out, -1) self._zoom_out.show() self._zoom_in = ToolButton('zoom-in') self._zoom_in.set_tooltip(_('Zoom in')) self._zoom_in.connect('clicked', self._zoom_in_cb) self.insert(self._zoom_in, -1) self._zoom_in.show() self._zoom_to_width = ToolButton('zoom-best-fit') self._zoom_to_width.set_tooltip(_('Zoom to width')) self._zoom_to_width.connect('clicked', self._zoom_to_width_cb) self.insert(self._zoom_to_width, -1) self._zoom_to_width.show() palette = self._zoom_to_width.get_palette() menu_item = MenuItem(_('Zoom to fit')) menu_item.connect('activate', self._zoom_to_fit_menu_item_activate_cb) palette.menu.append(menu_item) menu_item.show() menu_item = MenuItem(_('Actual size')) menu_item.connect('activate', self._actual_size_menu_item_activate_cb) palette.menu.append(menu_item) menu_item.show() tool_item = Gtk.ToolItem() self.insert(tool_item, -1) tool_item.show() self._zoom_spin = Gtk.SpinButton() self._zoom_spin.set_range(5.409, 400) self._zoom_spin.set_increments(1, 10) self._zoom_spin_notify_value_handler = self._zoom_spin.connect( 'notify::value', self._zoom_spin_notify_value_cb) tool_item.add(self._zoom_spin) self._zoom_spin.show() zoom_perc_label = Gtk.Label(_("%")) zoom_perc_label.show() tool_item_zoom_perc_label = Gtk.ToolItem() tool_item_zoom_perc_label.add(zoom_perc_label) self.insert(tool_item_zoom_perc_label, -1) tool_item_zoom_perc_label.show() spacer = Gtk.SeparatorToolItem() spacer.props.draw = False self.insert(spacer, -1) spacer.show() self._fullscreen = ToolButton('view-fullscreen') self._fullscreen.set_tooltip(_('Fullscreen')) self._fullscreen.connect('clicked', self._fullscreen_cb) self.insert(self._fullscreen, -1) self._fullscreen.show() self._view_notify_zoom_handler = None def set_view(self, view): self._view = view def set_bookmarkmanager(self, bookmarkmanager): self._bookmarkmanager = bookmarkmanager def _zoom_spin_notify_value_cb(self, zoom_spin, pspec): self._view.set_zoom(zoom_spin.props.value) def _view_notify_zoom_cb(self, model, pspec): self._zoom_spin.disconnect(self._zoom_spin_notify_value_handler) try: self._zoom_spin.props.value = round(self._view.get_zoom()) finally: self._zoom_spin_notify_value_handler = self._zoom_spin.connect( 'notify::value', self._zoom_spin_notify_value_cb) def __set_progress_if_applicable(self): if (self._view.show_progress_bar() is True) and \ (self._update_offset is True): self._view.get_maximum_offset_possible() def zoom_in(self, zoom_amount): self._view.zoom_in(zoom_amount) self._view._main_instance.window.force_ui_updates() self.__set_progress_if_applicable() def _zoom_in_cb(self, button, zoom_amount = 1): if self._view.can_zoom_in(): self.zoom_in(zoom_amount) self._view._number_of_times_zoomed = \ self._view._number_of_times_zoomed + zoom_amount def zoom_out(self, zoom_amount): self._view.zoom_out(zoom_amount) self._view._main_instance.window.force_ui_updates() self.__set_progress_if_applicable() def _zoom_out_cb(self, button, zoom_amount = 1): if self._view.can_zoom_out(): self.zoom_out(zoom_amount) self._view._number_of_times_zoomed = \ self._view._number_of_times_zoomed - zoom_amount def update_offset(self, update): self._update_offset = update def zoom_to_width(self): self._view.zoom_to_width() def _zoom_to_width_cb(self, button): self.zoom_to_width() def _zoom_to_fit_menu_item_activate_cb(self, menu_item): self._view.zoom_to_best_fit() def _actual_size_menu_item_activate_cb(self, menu_item): self._view.zoom_to_actual_size() def _fullscreen_cb(self, button): self.emit('go-fullscreen')
class PrimaryToolbar(ToolbarBase): __gtype_name__ = 'PrimaryToolbar' __gsignals__ = { 'add-link': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'remove-link': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'set-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'reset-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'go-library': (GObject.SignalFlags.RUN_FIRST, None, ([])), } def __init__(self, tabbed_view, act): ToolbarBase.__init__(self) self._url_toolbar = UrlToolbar() self._activity = act self.model = act.model self.model.link_removed_signal.connect(self.__link_removed_cb) self._tabbed_view = self._canvas = tabbed_view self._loading = False self._download_running_hid = None toolbar = self.toolbar activity_button = ActivityToolbarButton(self._activity) toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() ''' Disabled since the python gi bindings don't expose the critical WebKit2.PrintOperation.print function save_as_pdf = ToolButton('save-as-pdf') save_as_pdf.set_tooltip(_('Save page as pdf')) save_as_pdf.connect('clicked', self.save_as_pdf) activity_button.props.page.insert(separator, -1) activity_button.props.page.insert(save_as_pdf, -1) separator.show() save_as_pdf.show() ''' inspect_view = ToolButton('emblem-view-source') inspect_view.set_tooltip(_('Show Web Inspector')) inspect_view.connect('clicked', self.inspect_view) activity_button.props.page.insert(separator, -1) activity_button.props.page.insert(inspect_view, -1) separator.show() inspect_view.show() self._go_home = ToolButton('go-home') self._go_home.set_tooltip(_('Home page')) self._go_home.connect('clicked', self._go_home_cb) # add a menu to save the home page menu_box = PaletteMenuBox() self._go_home.props.palette.set_content(menu_box) menu_item = PaletteMenuItem() menu_item.set_label(_('Select as initial page')) menu_item.connect('activate', self._set_home_cb) menu_box.append_item(menu_item) self._reset_home_menu = PaletteMenuItem() self._reset_home_menu.set_label(_('Reset initial page')) self._reset_home_menu.connect('activate', self._reset_home_cb) menu_box.append_item(self._reset_home_menu) if os.path.isfile(LIBRARY_PATH): library_menu = PaletteMenuItem() library_menu.set_label(_('Library')) library_menu.connect('activate', self._go_library_cb) menu_box.append_item(library_menu) menu_box.show_all() # verify if the home page is configured client = GConf.Client.get_default() self._reset_home_menu.set_visible( client.get_string(HOME_PAGE_GCONF_KEY) is not None) toolbar.insert(self._go_home, -1) self._go_home.show() self.entry = WebEntry() self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-stop') self.entry.connect('icon-press', self._stop_and_reload_cb) self.entry.connect('activate', self._entry_activate_cb) self.entry.connect('focus-in-event', self.__focus_in_event_cb) self.entry.connect('focus-out-event', self.__focus_out_event_cb) self.entry.connect('key-press-event', self.__key_press_event_cb) self.entry.connect('changed', self.__changed_cb) # In an event box so that it can render the background entry_box = Gtk.EventBox() entry_box.add(self.entry) entry_box.show() self._entry_item = Gtk.ToolItem() self._entry_item.set_expand(True) self._entry_item.add(entry_box) self.entry.show() toolbar.insert(self._entry_item, -1) self._entry_item.show() self._back = ToolButton('go-previous-paired', accelerator='<ctrl>Left') self._back.set_tooltip(_('Back')) self._back.props.sensitive = False self._back.connect('clicked', self._go_back_cb) toolbar.insert(self._back, -1) self._back.show() palette = self._back.get_palette() self._back_box_menu = Gtk.VBox() self._back_box_menu.show() palette.set_content(self._back_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._forward = ToolButton('go-next-paired', accelerator='<ctrl>Right') self._forward.set_tooltip(_('Forward')) self._forward.props.sensitive = False self._forward.connect('clicked', self._go_forward_cb) toolbar.insert(self._forward, -1) self._forward.show() palette = self._forward.get_palette() self._forward_box_menu = Gtk.VBox() self._forward_box_menu.show() palette.set_content(self._forward_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._download_icon = ProgressToolButton( icon_name='emblem-downloads', tooltip=_('No Downloads Running')) toolbar.insert(self._download_icon, -1) self._download_icon.show() downloadmanager.connect_donwload_started(self.__download_started_cb) self._link_add = ToggleToolButton('emblem-favorite') self._link_add.set_accelerator('<ctrl>d') self._link_add.set_tooltip(_('Bookmark')) self._link_add_toggled_hid = \ self._link_add.connect('toggled', self.__link_add_toggled_cb) toolbar.insert(self._link_add, -1) self._link_add.show() self._toolbar_separator = Gtk.SeparatorToolItem() self._toolbar_separator.props.draw = False self._toolbar_separator.set_expand(True) self._stop_button = StopButton(self._activity) toolbar.insert(self._stop_button, -1) self._progress_listener = None self._browser = None self._loading_changed_hid = None self._progress_changed_hid = None self._session_history_changed_hid = None self._uri_changed_hid = None self._load_changed_hid = None self._security_status_changed_hid = None if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) tabbed_view.connect_after('switch-page', self.__switch_page_cb) tabbed_view.connect_after('page-added', self.__page_added_cb) Gdk.Screen.get_default().connect('size-changed', self.__screen_size_changed_cb) self._configure_toolbar() def __download_started_cb(self): if self._download_running_hid is None: self._download_running_hid = GLib.timeout_add( 80, self.__download_running_cb) def __download_running_cb(self): print('__DLR') progress = downloadmanager.overall_downloads_progress() self._download_icon.update(progress) if downloadmanager.num_downloads() > 0: self._download_icon.props.tooltip = \ _('{}% Downloaded').format(int(progress*100)) self._download_icon.props.xo_color = XoColor(None) return True else: GLib.source_remove(self._download_running_hid) self._download_running_hid = None self._download_icon.props.tooltip = _('No Downloads Running') self._download_icon.props.xo_color = XoColor('insensitive') return False def __key_press_event_cb(self, entry, event): self._tabbed_view.current_browser.loading_uri = entry.props.text def __switch_page_cb(self, tabbed_view, page, page_num): if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) def __page_added_cb(self, notebook, child, pagenum): self.entry._search_popdown() def _configure_toolbar(self, screen=None): # Adapt the toolbars for portrait or landscape mode. if screen is None: screen = Gdk.Screen.get_default() if screen.get_width() < screen.get_height(): if self._entry_item in self._url_toolbar.toolbar.get_children(): return self.toolbar.remove(self._entry_item) self._url_toolbar.toolbar.insert(self._entry_item, -1) separator_pos = len(self.toolbar.get_children()) - 1 self.toolbar.insert(self._toolbar_separator, separator_pos) self._toolbar_separator.show() self.pack_end(self._url_toolbar, True, True, 0) self._url_toolbar.show() else: if self._entry_item in self.toolbar.get_children(): return self.toolbar.remove(self._toolbar_separator) position = len(self.toolbar.get_children()) - 4 self._url_toolbar.toolbar.remove(self._entry_item) self.toolbar.insert(self._entry_item, position) self._toolbar_separator.hide() self.remove(self._url_toolbar) def __screen_size_changed_cb(self, screen): self._configure_toolbar(screen) def _connect_to_browser(self, browser): if self._browser is not None: self._browser.disconnect(self._uri_changed_hid) self._browser.disconnect(self._load_changed_hid) self._browser.disconnect(self._progress_changed_hid) self._browser.disconnect(self._security_status_changed_hid) self._browser = browser if not isinstance(self._browser, DummyBrowser): address = self._browser.props.uri or self._browser.loading_uri else: address = self._browser.props.uri self._set_address(address) self._set_progress(self._browser.props.estimated_load_progress) self._set_loading(self._browser.props.estimated_load_progress < 1.0) self._set_security_status(self._browser.security_status) is_webkit_browser = isinstance(self._browser, Browser) self.entry.props.editable = is_webkit_browser self._uri_changed_hid = self._browser.connect('notify::uri', self.__uri_changed_cb) self._load_changed_hid = self._browser.connect('load-changed', self.__load_changed_cb) self._progress_changed_hid = self._browser.connect( 'notify::estimated-load-progress', self.__progress_changed_cb) self._security_status_changed_hid = self._browser.connect( 'security-status-changed', self.__security_status_changed_cb) self._update_navigation_buttons() def __security_status_changed_cb(self, widget): self._set_security_status(widget.security_status) def __progress_changed_cb(self, widget, param): self._set_progress(widget.props.estimated_load_progress) self._set_loading(widget.props.estimated_load_progress < 1.0) def _set_security_status(self, security_status): # Display security status as a lock icon in the left side of # the URL entry. if security_status is None: self.entry.set_icon_from_pixbuf(iconentry.ICON_ENTRY_PRIMARY, None) elif security_status == Browser.SECURITY_STATUS_SECURE: self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, 'channel-secure-symbolic') elif security_status == Browser.SECURITY_STATUS_INSECURE: self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, 'channel-insecure-symbolic') def _set_progress(self, progress): if progress == 1.0: self.entry.set_progress_fraction(0.0) else: self.entry.set_progress_fraction(progress) def _set_address(self, uri): if uri is None: self.entry.props.address = '' else: self.entry.props.address = uri def __changed_cb(self, iconentry): # The WebEntry can be changed when we click on a link, then we # have to show the clear icon only if is the user who has # changed the entry if self.entry.has_focus(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_in_event_cb(self, entry, event): if not self._tabbed_view.is_current_page_pdf(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_out_event_cb(self, entry, event): if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self._show_reload_icon() def _show_no_icon(self): self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY) def _show_stop_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-stop') def _show_reload_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-refresh') def _show_clear_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-cancel') def _update_navigation_buttons(self): can_go_back = self._browser.can_go_back() self._back.props.sensitive = can_go_back can_go_forward = self._browser.can_go_forward() self._forward.props.sensitive = can_go_forward is_webkit_browser = isinstance(self._browser, Browser) self._go_home.props.sensitive = is_webkit_browser if is_webkit_browser: self._reload_session_history() with self._link_add.handler_block(self._link_add_toggled_hid): uri = self._browser.get_uri() print(self.model.has_link(uri), uri) self._link_add.props.active = self.model.has_link(uri) def __link_removed_cb(self, model): self._update_navigation_buttons() def _entry_activate_cb(self, entry): url = entry.props.text effective_url = self._tabbed_view.normalize_or_autosearch_url(url) self._browser.load_uri(effective_url) self._browser.loading_uri = effective_url self.entry.props.address = effective_url self._browser.grab_focus() def _go_home_cb(self, button): self.emit('go-home') def _go_library_cb(self, button): self.emit('go-library') def _set_home_cb(self, button): self._reset_home_menu.set_visible(True) self.emit('set-home') def _reset_home_cb(self, button): self._reset_home_menu.set_visible(False) self.emit('reset-home') def _go_back_cb(self, button): self._browser.go_back() def _go_forward_cb(self, button): self._browser.go_forward() def __uri_changed_cb(self, widget, param): self._set_address(widget.get_uri()) self._update_navigation_buttons() filepicker.cleanup_temp_files() def __load_changed_cb(self, widget, event): self._update_navigation_buttons() def _stop_and_reload_cb(self, entry, icon_pos, button): if entry.has_focus() and \ not self._tabbed_view.is_current_page_pdf(): entry.set_text('') else: if self._loading: self._browser.stop_loading() else: self._browser.reload() def _set_loading(self, loading): self._loading = loading if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self._set_sensitive(True) self._show_reload_icon() else: self._set_sensitive(False) self._show_no_icon() def _set_sensitive(self, value): for widget in self.toolbar: if widget not in (self._stop_button, self._link_add): widget.set_sensitive(value) def _reload_session_history(self): back_forward_list = self._browser.get_back_forward_list() item_index = 0 # The index of the history item # Clear menus in palettes: for box_menu in (self._back_box_menu, self._forward_box_menu): for menu_item in box_menu.get_children(): box_menu.remove(menu_item) def create_menu_item(history_item): """Create a MenuItem for the back or forward palettes.""" title = history_item.get_title() or _('No Title') if not isinstance(title, unicode): title = unicode(title, 'utf-8') # This is a fix until the Sugar MenuItem is fixed: menu_item = PaletteMenuItem(text_label=title) menu_item.connect('activate', self._history_item_activated_cb, history_item) return menu_item back_list = back_forward_list.get_back_list_with_limit( _MAX_HISTORY_ENTRIES) back_list.reverse() for item in back_list: menu_item = create_menu_item(item) self._back_box_menu.pack_end(menu_item, False, False, 0) menu_item.show() item_index += 1 # Increment the item index to count the current page: item_index += 1 forward_list = back_forward_list.get_forward_list_with_limit( _MAX_HISTORY_ENTRIES) forward_list.reverse() for item in forward_list: menu_item = create_menu_item(item) self._forward_box_menu.pack_start(menu_item, False, False, 0) menu_item.show() item_index += 1 def _history_item_activated_cb(self, menu_item, history_item): self._back.get_palette().popdown(immediate=True) self._forward.get_palette().popdown(immediate=True) # self._browser.set_history_index(index) self._browser.go_to_back_forward_list_item(history_item) def __link_add_toggled_cb(self, button): if button.props.active: self.emit('add-link') else: self.emit('remove-link') def inspect_view(self, button): page = self._canvas.get_current_page() webview = self._canvas.get_children()[page].props.browser # If get_inspector returns None, it is not a real WebView inspector = webview.get_inspector() if inspector is not None: # Inspector window will be blank if disabled web_settings = webview.get_settings() web_settings.props.enable_developer_extras = True inspector.show() inspector.attach() '''
class ReadToolbar(Gtk.Toolbar): __gtype_name__ = 'ReadToolbar' def __init__(self): GObject.GObject.__init__(self) self.back = ToolButton('go-previous') self.back.set_tooltip(_('Back')) self.back.props.sensitive = False palette = self.back.get_palette() self.prev_page = MenuItem(text_label= _("Previous page")) palette.menu.append(self.prev_page) self.prev_page.show_all() self.back.connect('clicked', self.go_back_cb) self.prev_page.connect('activate', self.go_back_cb) self.insert(self.back, -1) self.back.show() self.forward = ToolButton('go-next') self.forward.set_tooltip(_('Forward')) self.forward.props.sensitive = False palette = self.forward.get_palette() self.next_page = MenuItem(text_label= _("Next page")) palette.menu.append(self.next_page) self.next_page.show_all() self.forward.connect('clicked', self.go_forward_cb) self.next_page.connect('activate', self.go_forward_cb) self.insert(self.forward, -1) self.forward.show() num_page_item = Gtk.ToolItem() self._num_page_entry = Gtk.Entry() self._num_page_entry.set_text('0') self._num_page_entry.set_alignment(1) self._num_page_entry.connect('insert-text', self._num_page_entry_insert_text_cb) self._num_page_entry.connect('activate', self._num_page_entry_activate_cb) self._num_page_entry.set_width_chars(4) num_page_item.add(self._num_page_entry) self._num_page_entry.show() self.insert(num_page_item, -1) num_page_item.show() total_page_item = Gtk.ToolItem() self._total_page_label = Gtk.Label() self._total_page_label.set_text(' / 0') total_page_item.add(self._total_page_label) self._total_page_label.show() self.insert(total_page_item, -1) total_page_item.show() def _num_page_entry_insert_text_cb(self, entry, text, length, position): if not re.match('[0-9]', text): entry.emit_stop_by_name('insert-text') return True return False def _num_page_entry_activate_cb(self, entry): if entry.props.text: page = int(entry.props.text) - 1 else: page = 0 if page >= self.total_pages: page = self.total_pages - 1 elif page < 0: page = 0 self.current_page = page self.activity.set_current_page(page) self.activity.show_page(page) entry.props.text = str(page + 1) self._update_nav_buttons() def go_back_cb(self, button): self.activity.previous_page() def go_forward_cb(self, button): self.activity.next_page() def _update_nav_buttons(self): current_page = self.current_page self.back.props.sensitive = current_page > 0 self.forward.props.sensitive = \ current_page < self.total_pages - 1 self._num_page_entry.props.text = str(current_page + 1) self._total_page_label.props.label = \ ' / ' + str(self.total_pages) def set_total_pages(self, pages): self.total_pages = pages def set_current_page(self, page): self.current_page = page self._update_nav_buttons() def set_activity(self, activity): self.activity = activity def setToggleButtonState(self,button,b,id): button.handler_block(id) button.set_active(b) button.handler_unblock(id)
class DetailToolbox(ToolbarBox): __gsignals__ = { 'volume-error': (GObject.SignalFlags.RUN_FIRST, None, ([str, str])), } def __init__(self, journalactivity): ToolbarBox.__init__(self) self._journalactivity = journalactivity self._metadata = None self._temp_file_path = None self._refresh = None self._resume = ToolButton('activity-start') self._resume.connect('clicked', self._resume_clicked_cb) self.toolbar.insert(self._resume, -1) self._resume.show() self._resume_menu = None color = profile.get_color() self._copy = ToolButton() icon = Icon(icon_name='edit-copy', xo_color=color) self._copy.set_icon_widget(icon) icon.show() self._copy.set_tooltip(_('Copy to')) self._copy.connect('clicked', self._copy_clicked_cb) self.toolbar.insert(self._copy, -1) self._copy.show() self._duplicate = ToolButton() icon = Icon(icon_name='edit-duplicate', xo_color=color) self._duplicate.set_icon_widget(icon) self._duplicate.set_tooltip(_('Duplicate')) self._duplicate.connect('clicked', self._duplicate_clicked_cb) self.toolbar.insert(self._duplicate, -1) if accountsmanager.has_configured_accounts(): self._refresh = ToolButton('entry-refresh') self._refresh.set_tooltip(_('Refresh')) self._refresh.connect('clicked', self._refresh_clicked_cb) self.toolbar.insert(self._refresh, -1) self._refresh.show() separator = Gtk.SeparatorToolItem() self.toolbar.insert(separator, -1) separator.show() erase_button = ToolButton('list-remove') erase_button.set_tooltip(_('Erase')) erase_button.connect('clicked', self._erase_button_clicked_cb) self.toolbar.insert(erase_button, -1) erase_button.show() def set_metadata(self, metadata): self._metadata = metadata self._refresh_copy_palette() self._refresh_duplicate_palette() self._refresh_refresh_palette() self._refresh_resume_palette() def _resume_clicked_cb(self, button): if not misc.can_resume(self._metadata): palette = self._resume.get_palette() palette.popup(immediate=True) misc.resume(self._metadata, alert_window=journalwindow.get_journal_window()) def _copy_clicked_cb(self, button): button.palette.popup(immediate=True) def _refresh_clicked_cb(self, button): button.palette.popup(immediate=True) def _duplicate_clicked_cb(self, button): try: model.copy(self._metadata, '/') except IOError as e: logging.exception('Error while copying the entry.') self.emit('volume-error', _('Error while copying the entry. %s') % (e.strerror, ), _('Error')) def _erase_button_clicked_cb(self, button): alert = Alert() erase_string = _('Erase') alert.props.title = erase_string alert.props.msg = _('Do you want to permanently erase \"%s\"?') \ % self._metadata['title'] icon = Icon(icon_name='dialog-cancel') alert.add_button(Gtk.ResponseType.CANCEL, _('Cancel'), icon) icon.show() ok_icon = Icon(icon_name='dialog-ok') alert.add_button(Gtk.ResponseType.OK, erase_string, ok_icon) ok_icon.show() alert.connect('response', self.__erase_alert_response_cb) journalwindow.get_journal_window().add_alert(alert) alert.show() def __erase_alert_response_cb(self, alert, response_id): journalwindow.get_journal_window().remove_alert(alert) if response_id is Gtk.ResponseType.OK: registry = bundleregistry.get_registry() bundle = misc.get_bundle(self._metadata) if bundle is not None and registry.is_installed(bundle): registry.uninstall(bundle) model.delete(self._metadata['uid']) def _resume_menu_item_activate_cb(self, menu_item, service_name): misc.resume(self._metadata, service_name, alert_window=journalwindow.get_journal_window()) def _refresh_copy_palette(self): palette = self._copy.get_palette() # Use the menu defined in CopyMenu for menu_item in palette.menu.get_children(): palette.menu.remove(menu_item) menu_item.destroy() CopyMenuBuilder(self._journalactivity, self.__get_uid_list_cb, self.__volume_error_cb, palette.menu) def __get_uid_list_cb(self): return [self._metadata['uid']] def _refresh_duplicate_palette(self): color = misc.get_icon_color(self._metadata) self._copy.get_icon_widget().props.xo_color = color if self._metadata['mountpoint'] == '/': self._duplicate.show() icon = self._duplicate.get_icon_widget() icon.props.xo_color = color icon.show() else: self._duplicate.hide() def _refresh_refresh_palette(self): if self._refresh is None: return color = misc.get_icon_color(self._metadata) self._refresh.get_icon_widget().props.xo_color = color palette = self._refresh.get_palette() for menu_item in palette.menu.get_children(): palette.menu.remove(menu_item) for account in accountsmanager.get_configured_accounts(): if hasattr(account, 'get_shared_journal_entry'): entry = account.get_shared_journal_entry() if hasattr(entry, 'get_refresh_menu'): menu = entry.get_refresh_menu() palette.menu.append(menu) menu.set_metadata(self._metadata) def __volume_error_cb(self, menu_item, message, severity): self.emit('volume-error', message, severity) def _refresh_resume_palette(self): if self._metadata.get('activity_id', ''): # TRANS: Action label for resuming an activity. self._resume.set_tooltip(_('Resume')) else: # TRANS: Action label for starting an entry. self._resume.set_tooltip(_('Start')) palette = self._resume.get_palette() if self._resume_menu is not None: self._resume_menu.destroy() self._resume_menu = PaletteMenuBox() palette.set_content(self._resume_menu) self._resume_menu.show() for activity_info in misc.get_activities(self._metadata): menu_item = PaletteMenuItem(file_name=activity_info.get_icon(), text_label=activity_info.get_name()) menu_item.connect('activate', self._resume_menu_item_activate_cb, activity_info.get_bundle_id()) self._resume_menu.append_item(menu_item) menu_item.show() if not misc.can_resume(self._metadata): self._resume.set_tooltip(_('No activity to start entry'))
def __init__(self, handle): activity.Activity.__init__(self, handle) # abiword uses the current directory for all its file dialogs os.chdir(os.path.expanduser('~')) # create our main abiword canvas self.abiword_canvas = DocumentView() self._new_instance = True toolbar_box = ToolbarBox() self.activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(self.activity_button, -1) separator = Gtk.SeparatorToolItem() separator.show() self.activity_button.props.page.insert(separator, 2) ExportButtonFactory(self, self.abiword_canvas) self.activity_button.show() edit_toolbar = ToolbarButton() edit_toolbar.props.page = EditToolbar(self, toolbar_box) edit_toolbar.props.icon_name = 'toolbar-edit' edit_toolbar.props.label = _('Edit') toolbar_box.toolbar.insert(edit_toolbar, -1) view_toolbar = ToolbarButton() view_toolbar.props.page = ViewToolbar(self.abiword_canvas) view_toolbar.props.icon_name = 'toolbar-view' view_toolbar.props.label = _('View') toolbar_box.toolbar.insert(view_toolbar, -1) # due to http://bugzilla.abisource.com/show_bug.cgi?id=13585 if self.abiword_canvas.get_version() != '3.0': self.speech_toolbar_button = ToolbarButton(icon_name='speak') toolbar_box.toolbar.insert(self.speech_toolbar_button, -1) self._init_speech() separator = Gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) text_toolbar = ToolbarButton() text_toolbar.props.page = TextToolbar(self.abiword_canvas) text_toolbar.props.icon_name = 'format-text' text_toolbar.props.label = _('Text') toolbar_box.toolbar.insert(text_toolbar, -1) para_toolbar = ToolbarButton() para_toolbar.props.page = ParagraphToolbar(self.abiword_canvas) para_toolbar.props.icon_name = 'paragraph-bar' para_toolbar.props.label = _('Paragraph') toolbar_box.toolbar.insert(para_toolbar, -1) insert_toolbar = ToolbarButton() insert_toolbar.props.page = InsertToolbar(self.abiword_canvas) insert_toolbar.props.icon_name = 'insert-table' insert_toolbar.props.label = _('Table') toolbar_box.toolbar.insert(insert_toolbar, -1) image = ToolButton('insert-picture') image.set_tooltip(_('Insert Image')) self._image_id = image.connect('clicked', self.__image_cb) toolbar_box.toolbar.insert(image, -1) palette = image.get_palette() box = PaletteMenuBox() palette.set_content(box) box.show() menu_item = PaletteMenuItem(_('Floating')) menu_item.connect('activate', self.__image_cb, True) box.append_item(menu_item) menu_item.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_size_request(0, -1) separator.set_expand(True) separator.show() toolbar_box.toolbar.insert(separator, -1) stop = StopButton(self) toolbar_box.toolbar.insert(stop, -1) toolbar_box.show_all() self.set_toolbar_box(toolbar_box) # add a overlay to be able to show a icon while joining a shared doc overlay = Gtk.Overlay() overlay.add(self.abiword_canvas) overlay.show() self._connecting_box = ConnectingBox() overlay.add_overlay(self._connecting_box) self.set_canvas(overlay) # we want a nice border so we can select paragraphs easily self.abiword_canvas.set_show_margin(True) # Set default font face and size self._default_font_face = 'Sans' self._default_font_size = 12 # activity sharing self.participants = {} self.joined = False self.connect('shared', self._shared_cb) if self.shared_activity: # we are joining the activity logger.debug('We are joining an activity') # display a icon while joining self._connecting_box.show() # disable the abi widget self.abiword_canvas.set_sensitive(False) self._new_instance = False self.connect('joined', self._joined_cb) self.shared_activity.connect('buddy-joined', self._buddy_joined_cb) self.shared_activity.connect('buddy-left', self._buddy_left_cb) if self.get_shared(): self._joined_cb(self) else: # we are creating the activity logger.debug("We are creating an activity") self.abiword_canvas.zoom_width() self.abiword_canvas.show() self.connect_after('map-event', self.__map_activity_event_cb) self.abiword_canvas.connect('size-allocate', self.size_allocate_cb)
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)
class ReadToolbar(Gtk.Toolbar): __gtype_name__ = 'ReadToolbar' def __init__(self): Gtk.Toolbar.__init__(self) self.back = ToolButton('go-previous') self.back.set_tooltip(_('Back')) self.back.props.sensitive = False palette = self.back.get_palette() self.prev_page = MenuItem(text_label=_("Previous page")) palette.menu.append(self.prev_page) self.prev_page.show_all() self.prev_bookmark = MenuItem(text_label=_("Previous bookmark")) palette.menu.append(self.prev_bookmark) self.prev_bookmark.show_all() self.back.connect('clicked', self.go_back_cb) self.prev_page.connect('activate', self.go_back_cb) self.prev_bookmark.connect('activate', self.prev_bookmark_activate_cb) self.insert(self.back, -1) self.back.show() self.forward = ToolButton('go-next') self.forward.set_tooltip(_('Forward')) self.forward.props.sensitive = False palette = self.forward.get_palette() self.next_page = MenuItem(text_label=_("Next page")) palette.menu.append(self.next_page) self.next_page.show_all() self.next_bookmark = MenuItem(text_label=_("Next bookmark")) palette.menu.append(self.next_bookmark) self.next_bookmark.show_all() self.forward.connect('clicked', self.go_forward_cb) self.next_page.connect('activate', self.go_forward_cb) self.next_bookmark.connect('activate', self.next_bookmark_activate_cb) self.insert(self.forward, -1) self.forward.show() num_page_item = Gtk.ToolItem() self.num_page_entry = Gtk.Entry() self.num_page_entry.set_text('0') self.num_page_entry.set_alignment(1) self.num_page_entry.connect('insert-text', self.num_page_entry_insert_text_cb) self.num_page_entry.connect('activate', self.num_page_entry_activate_cb) self.num_page_entry.set_width_chars(4) num_page_item.add(self.num_page_entry) self.num_page_entry.show() self.insert(num_page_item, -1) num_page_item.show() total_page_item = Gtk.ToolItem() self.total_page_label = Gtk.Label() self.total_page_label.set_markup( "<span size='14000' foreground='black'>") self.total_page_label.set_text(' / 0') total_page_item.add(self.total_page_label) self.total_page_label.show() self.insert(total_page_item, -1) total_page_item.show() spacer = Gtk.SeparatorToolItem() self.insert(spacer, -1) spacer.show() bookmarkitem = Gtk.ToolItem() self.bookmarker = ToggleToolButton('emblem-favorite') self.bookmarker.set_tooltip(_('Toggle Bookmark')) self.bookmarker_handler_id = self.bookmarker.connect( 'clicked', self.bookmarker_clicked_cb) bookmarkitem.add(self.bookmarker) self.insert(bookmarkitem, -1) bookmarkitem.show_all() underline_item = Gtk.ToolItem() self.underline = ToggleToolButton('format-text-underline') self.underline.set_tooltip(_('Underline')) self.underline.props.sensitive = False self.underline_id = self.underline.connect('clicked', self.underline_cb) underline_item.add(self.underline) self.insert(underline_item, -1) underline_item.show_all() def num_page_entry_insert_text_cb(self, entry, text, length, position): if not re.match('[0-9]', text): entry.emit_stop_by_name('insert-text') return True return False def num_page_entry_activate_cb(self, entry): if entry.props.text: page = int(entry.props.text) - 1 else: page = 0 if page >= self.total_pages: page = self.total_pages - 1 elif page < 0: page = 0 self.current_page = page self.activity.set_current_page(page) self.activity.show_page(page) entry.props.text = str(page + 1) self.update_nav_buttons() def go_back_cb(self, button): self.activity.page_previous() def go_forward_cb(self, button): self.activity.page_next() def update_nav_buttons(self): current_page = self.current_page self.back.props.sensitive = current_page > 0 self.forward.props.sensitive = \ current_page < self.total_pages - 1 self.num_page_entry.props.text = str(current_page + 1) self.total_page_label.props.label = \ ' / ' + str(self.total_pages) def set_total_pages(self, pages): self.total_pages = pages def set_current_page(self, page): self.current_page = page self.update_nav_buttons() def set_activity(self, activity): self.activity = activity def prev_bookmark_activate_cb(self, menuitem): self.activity.prev_bookmark() def next_bookmark_activate_cb(self, menuitem): self.activity.next_bookmark() def bookmarker_clicked_cb(self, button): self.activity.bookmarker_clicked(button) def underline_cb(self, button): self.activity.underline_clicked(button) def setToggleButtonState(self, button, b, id): button.handler_block(id) button.set_active(b) button.handler_unblock(id) def update_underline_button(self, state): self.setToggleButtonState(self.underline, state, self.underline_id) def update_bookmark_button(self, state): self.setToggleButtonState(self.bookmarker, state, self.bookmarker_handler_id)
class OneSupportActivity(activity.Activity): ''' An activity for sending bug reports ''' def __init__(self, handle): ''' Initialize the toolbar ''' try: super(OneSupportActivity, self).__init__(handle) except dbus.exceptions.DBusException as e: _logger.error(str(e)) self.connect('realize', self.__realize_cb) if hasattr(self, 'metadata') and 'font_size' in self.metadata: self.font_size = int(self.metadata['font_size']) else: self.font_size = 8 self.zoom_level = self.font_size / float(len(FONT_SIZES)) _logger.debug('zoom level is %f' % self.zoom_level) # _check_gconf_settings() # For debugging purposes self._setup_toolbars() self.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color()) self.bundle_path = activity.get_bundle_path() self.tmp_path = os.path.join(activity.get_activity_root(), 'tmp') self._copy_entry = None self._paste_entry = None self._about_panel_visible = False self._webkit = None self._clipboard_text = '' self._fixed = None self._notify_transfer_status = False get_power_manager().inhibit_suspend() self._launch_task_master() def can_close(self): get_power_manager().restore_suspend() return True 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 _launch_task_master(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 = 3 * style.GRID_CELL_SIZE dy2 = 2 * style.GRID_CELL_SIZE self._progress_area = Gtk.Alignment.new(0.5, 0, 0, 0) self._progress_area.set_size_request(Gdk.Screen.width(), -1) self._fixed.put(self._progress_area, 0, Gdk.Screen.height() - dy2) self._progress_area.show() self._button_area = Gtk.Alignment.new(0.5, 0, 0, 0) self._button_area.set_size_request(Gdk.Screen.width(), -1) self._fixed.put(self._button_area, 0, Gdk.Screen.height() - dy1) 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, 0) self._scrolled_window.show() self._task_master = TaskMaster(self) self._task_master.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._task_master.set_events(Gdk.EventMask.KEY_PRESS_MASK) self._task_master.connect('key_press_event', self._task_master.keypress_cb) self._task_master.set_can_focus(True) self._task_master.grab_focus() self.set_canvas(self._fixed) self._fixed.show() self._task_master.task_master() 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_progress_area(self, widget): self._progress_area.add(widget) def _load_intro_graphics(self, file_name='generic-problem.html', message=None): center_in_panel = Gtk.Alignment.new(0.5, 0, 0, 0) url = os.path.join(self.bundle_path, 'html-content', file_name) graphics = Graphics() if message is None: graphics.add_uri('file://' + url) else: graphics.add_uri('file://' + url + '?MSG=' + utils.get_safe_text(message)) graphics.set_zoom_level(0.667) center_in_panel.add(graphics) graphics.show() self.set_canvas(center_in_panel) center_in_panel.show() 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._task_master.reload_graphics() def _resize_canvas(self, widget, fullscreen=False): # When a toolbar is expanded or collapsed, resize the canvas # to ensure that the progress bar is still visible. if hasattr(self, '_task_master'): if self.toolbar_expanded(): dy1 = 4 * style.GRID_CELL_SIZE dy2 = 3 * style.GRID_CELL_SIZE else: dy1 = 3 * style.GRID_CELL_SIZE dy2 = 2 * 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() - dy1) self._fixed.move(self._progress_area, 0, Gdk.Screen.height() - dy2) self._fixed.move(self._button_area, 0, Gdk.Screen.height() - dy1) 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 write_file(self, file_path): self.metadata['font_size'] = str(self.font_size) def _setup_toolbars(self): ''' Setup the toolbars. ''' self.max_participants = 1 # No sharing 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) self._zoom_in = ToolButton('zoom-in') self._zoom_in.set_tooltip(_('Increase size')) view_toolbar.insert(self._zoom_in, -1) self._zoom_in.show() self._zoom_in.connect('clicked', self._zoom_in_cb) self._zoom_out = ToolButton('zoom-out') self._zoom_out.set_tooltip(_('Decrease size')) view_toolbar.insert(self._zoom_out, -1) self._zoom_out.show() self._zoom_out.connect('clicked', self._zoom_out_cb) self._zoom_eq = ToolButton('zoom-original') self._zoom_eq.set_tooltip(_('Restore original size')) view_toolbar.insert(self._zoom_eq, -1) self._zoom_eq.show() self._zoom_eq.connect('clicked', self._zoom_eq_cb) self._set_zoom_buttons_sensitivity() 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) self._about_button = ToolButton('computer') self._about_button.set_tooltip(_('About my computer')) self._toolbox.toolbar.insert(self._about_button, -1) self._about_button.palette_invoker.props.lock_palette = True self._about_button.set_sensitive(True) self._about_button.show() self._about_button.connect('clicked', self._about_cb) about_panel = AboutPanel() about_panel.show() self._about_palette = self._about_button.get_palette() self._about_palette.set_content(about_panel) 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 __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 _about_cb(self, button): if not self._about_palette.is_up() and not self._about_panel_visible: self._about_palette.popup( immediate=True, state=self._about_palette.SECONDARY) self._about_panel_visible = True else: self._about_palette.popdown(immediate=True) self._about_panel_visible = False def _fullscreen_cb(self, button): ''' Hide the Sugar toolbars. ''' self.fullscreen() def _set_zoom_buttons_sensitivity(self): if self.font_size < len(FONT_SIZES) - 1: self._zoom_in.set_sensitive(True) else: self._zoom_in.set_sensitive(False) if self.font_size > 0: self._zoom_out.set_sensitive(True) else: self._zoom_out.set_sensitive(False) if hasattr(self, '_scrolled_window'): self._set_scroll_policy() def _set_scroll_policy(self): if Gdk.Screen.width() < Gdk.Screen.height() or self.zoom_level > 0.667: self._scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) else: self._scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) def _zoom_eq_cb(self, button): self.font_size = 8 self.zoom_level = 0.667 self._set_zoom_buttons_sensitivity() self._task_master.reload_graphics() def _zoom_in_cb(self, button): if self.font_size < len(FONT_SIZES) - 1: self.font_size += 1 self.zoom_level *= 1.1 self._set_zoom_buttons_sensitivity() self._task_master.reload_graphics() def _zoom_out_cb(self, button): if self.font_size > 0: self.font_size -= 1 self.zoom_level /= 1.1 self._set_zoom_buttons_sensitivity() self._task_master.reload_graphics() 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 _reboot_alert_cb(self, alert, response_id): self.remove_alert(alert) if response_id is Gtk.ResponseType.OK: try: utils.reboot() except Exception as e: _logger.error('Cannot reboot: %s' % e) def _mount_added_cb(self, volume_monitor, device): _logger.error('mount added') if self.check_volume_data(): _logger.debug('launching') self._launcher() def _mount_removed_cb(self, volume_monitor, device): _logger.error('mount removed') if self.check_volume_data(): _logger.debug('launching') self._launcher()
class TuningToolbar(Gtk.Toolbar): ''' The toolbar for tuning instruments ''' def __init__(self, activity): super(type(self), self).__init__() self.activity = activity self._show_tuning_line = False self._updating_note = True self._tuning_tool = None self._instrument_button = ToolButton('instruments') self._instrument_button.set_tooltip(_('Tune an instrument.')) self._instrument_button.connect('clicked', self._button_selection_cb) self.insert(self._instrument_button, -1) self._setup_instrument_palette() separator = Gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._note = 'A' self._notes_button = ToolButton('notes') self._notes_button.set_tooltip(_('Notes')) self._notes_button.connect('clicked', self._button_selection_cb) self.insert(self._notes_button, -1) self._setup_notes_palette() self._octave = 4 self._octaves_button = ToolButton('octaves') self._octaves_button.set_tooltip(_('Octaves')) self._octaves_button.connect('clicked', self._button_selection_cb) self.insert(self._octaves_button, -1) self._setup_octaves_palette() # The entry is used to display a note or for direct user input self._freq_entry = Gtk.Entry() self._freq_entry.set_text('440') # A self._freq_entry_changed_id = self._freq_entry.connect( 'changed', self._update_freq_entry) if hasattr(self._freq_entry, 'set_tooltip_text'): self._freq_entry.set_tooltip_text( _('Enter a frequency to display.')) self._freq_entry.set_width_chars(8) self._freq_entry.show() toolitem = Gtk.ToolItem() toolitem.add(self._freq_entry) self.insert(toolitem, -1) toolitem.show() self._new_tuning_line = ToolButton('tuning-tools') self._new_tuning_line.show() self.insert(self._new_tuning_line, -1) self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._new_tuning_line.connect('clicked', self.tuning_line_cb) separator = Gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._harmonic = ToolButton('harmonics') self._harmonic.show() self.insert(self._harmonic, -1) self._harmonic.set_tooltip(_('Show harmonics.')) self._harmonic.connect('clicked', self.harmonic_cb) separator = Gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._play_tone = ToolButton('media-playback-start') self._play_tone.show() self.insert(self._play_tone, -1) self._play_tone.set_tooltip(_('Play a note.')) self._play_tone.connect('clicked', self.play_cb) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.insert(separator, -1) self.label = Gtk.Label(label='') self.label.set_use_markup(True) self.label.show() toolitem = Gtk.ToolItem() toolitem.add(self.label) self.insert(toolitem, -1) toolitem.show() self.show_all() def _update_note(self): ''' Calculate the frequency based on note and octave ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar return i = self._octave * 12 + NOTES.index(self._note) freq = A0 * pow(TWELTHROOT2, i) self._updating_note = True self._freq_entry.set_text('%0.3f' % (freq)) self.label.set_markup( SPAN % (style.COLOR_WHITE.get_html(), self._note + str(self._octave))) if self._show_tuning_line: self.activity.wave.tuning_line = freq return def _update_freq_entry(self, widget): # Calculate a note from a frequency if not self._updating_note: # Only if user types in a freq. try: freq = float(self._freq_entry.get_text()) # Only consider notes in piano range if freq < A0 * 0.97: self.label.set_text('< A0') return if freq > C8 * 1.03: self.label.set_text('> C8') return self.label.set_markup(freq_note(freq, flatsharp=True)) except ValueError: return self._updating_note = False def _button_selection_cb(self, widget): palette = widget.get_palette() if palette: if not palette.is_up(): palette.popup(immediate=True) else: palette.popdown(immediate=True) return def _setup_notes_palette(self): self._notes_palette = self._notes_button.get_palette() for note in NOTES: menu_item = MenuItem(icon_name='', text_label=note) menu_item.connect('activate', self._note_selected_cb, note) self._notes_palette.menu.append(menu_item) menu_item.show() def _note_selected_cb(self, widget, note): self._note = note self._update_note() def _setup_octaves_palette(self): self._octaves_palette = self._octaves_button.get_palette() for octave in range(9): menu_item = MenuItem(icon_name='', text_label=str(octave)) menu_item.connect('activate', self._octave_selected_cb, octave) self._octaves_palette.menu.append(menu_item) menu_item.show() def _octave_selected_cb(self, widget, octave): self._octave = octave self._update_note() def _setup_instrument_palette(self): self.instrument_palette = self._instrument_button.get_palette() self.instrument = [] for k in INSTRUMENT_DICT.keys(): self.instrument.append(k) menu_item = MenuItem(icon_name='', text_label=k) menu_item.connect('activate', self.instrument_selected_cb, k) self.instrument_palette.menu.append(menu_item) menu_item.show() def instrument_selected_cb(self, button, instrument): ''' Callback for instrument control ''' logging.debug(instrument) if self._tuning_tool is not None: self.remove(self._tuning_tool) # Always remove previous buttons if hasattr(self, '_tuning_button'): self.remove(self._tuning_button) self.remove(self._notes_button) self.remove(self._octaves_button) if instrument == _('None'): self.activity.wave.instrument = None # Restore the notes, octaves buttons if hasattr(self, '_notes_button'): self.insert(self._notes_button, 2) self.insert(self._octaves_button, 3) return self.activity.wave.instrument = instrument # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Add a Tuning palette for this instrument self._tuning_button = ToolButton('notes') self._tuning_button.set_tooltip(instrument) self._tuning_button.connect('clicked', self._button_selection_cb) self.insert(self._tuning_button, 2) self._setup_tuning_palette(instrument) def _setup_tuning_palette(self, instrument): self._tuning_palette = self._tuning_button.get_palette() self.tuning = [] self.tuning.append(_('All notes')) menu_item = MenuItem(icon_name='', text_label=_('All notes')) menu_item.connect('activate', self._tuning_selected_cb, instrument, -1) self._tuning_palette.menu.append(menu_item) menu_item.show() for i, f in enumerate(INSTRUMENT_DICT[instrument]): self.tuning.append(freq_note(f)) menu_item = MenuItem(icon_name='', text_label=freq_note(f)) menu_item.connect('activate', self._tuning_selected_cb, instrument, i) self._tuning_palette.menu.append(menu_item) menu_item.show() self.show_all() def _tuning_selected_cb(self, widget, instrument, fidx): ''' Update note ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar? return if instrument not in INSTRUMENT_DICT: return if fidx == -1: # All notes self.activity.wave.instrument = instrument self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon_name('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: freq = INSTRUMENT_DICT[instrument][fidx] self.activity.wave.instrument = None self.activity.wave.tuning_line = freq self._new_tuning_line.set_icon_name('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True # For consistency, update the freq_entry to make it audible too self._freq_entry.set_text(str(self.activity.wave.tuning_line)) self._updating_note = False def harmonic_cb(self, *args): ''' Callback for harmonics control ''' self.activity.wave.harmonics = not self.activity.wave.harmonics if self.activity.wave.harmonics: self._harmonic.set_icon_name('harmonics-off') self._harmonic.set_tooltip(_('Hide harmonics.')) if self.activity.wave.instrument is None and \ self.activity.wave.tuning_line == 0.0: self._load_tuning_line() else: self._harmonic.set_icon_name('harmonics') self._harmonic.set_tooltip(_('Show harmonics.')) def tuning_line_cb(self, *args): ''' Callback for tuning insert ''' if self._show_tuning_line: self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon_name('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: self._load_tuning_line() def _load_tuning_line(self): ''' Read the freq entry and use value to set tuning line ''' freq = self._freq_entry.get_text() try: self.activity.wave.tuning_line = float(freq) if freq < 0: freq = -freq self._new_tuning_line.set_icon_name('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True except ValueError: self.activity.wave.tuning_line = 0.0 self._freq_entry.set_text('0') # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() def play_cb(self, *args): ''' Save settings, turn off display, and then play a tone at the current frequency ''' channels = [] for c in range(self.activity.audiograb.channels): channels.append(self.activity.wave.get_visibility(channel=c)) self.activity.wave.set_visibility(False, channel=c) wave_status = self.activity.wave.get_active() self.activity.wave.set_context_off() self.activity.wave.set_active(False) if self.activity.hw in [XO4, XO175]: self.activity.audiograb.stop_grabbing() freq = float(self._freq_entry.get_text()) GLib.timeout_add(200, self.play_sound, freq, channels, wave_status) def play_sound(self, freq, channels, wave_status): ''' Play the sound and then restore wave settings ''' self._play_sinewave(freq, 5000, 1) if self.activity.hw in [XO4, XO175]: self.activity.sensor_toolbar.set_mode('sound') self.activity.sensor_toolbar.set_sound_context() self.activity.audiograb.start_grabbing() for c in range(self.activity.audiograb.channels): self.activity.wave.set_visibility(channels[c], channel=c) self.activity.wave.set_context_on() self.activity.wave.set_active(wave_status) def _play_sinewave(self, pitch, amplitude=5000, duration=1): """ Create a Csound score to play a sine wave. """ self.orchlines = [] self.scorelines = [] self.instrlist = [] try: pitch = abs(float(pitch)) amplitude = abs(float(amplitude)) duration = abs(float(duration)) except ValueError: logging.error('bad args to _play_sinewave') return self._prepare_sinewave(pitch, amplitude, duration) path = os.path.join(self.activity.get_activity_root(), 'instance', 'tmp.csd') # Create a csound file from the score. self._audio_write(path) # Play the csound file. check_output(['csound', path], 'call to csound failed?') def _prepare_sinewave(self, pitch, amplitude, duration, starttime=0, pitch_envelope=99, amplitude_envelope=100, instrument=1): pitenv = pitch_envelope ampenv = amplitude_envelope if 1 not in self.instrlist: self.orchlines.append("instr 1\n") self.orchlines.append("kpitenv oscil 1, 1/p3, p6\n") self.orchlines.append("aenv oscil 1, 1/p3, p7\n") self.orchlines.append("asig oscil p5*aenv, p4*kpitenv, p8\n") self.orchlines.append("out asig\n") self.orchlines.append("endin\n\n") self.instrlist.append(1) self.scorelines.append( "i1 %s %s %s %s %s %s %s\n" % (str(starttime), str(duration), str(pitch), str(amplitude), str(pitenv), str(ampenv), str(instrument))) def _audio_write(self, file): """ Compile a .csd file. """ csd = open(file, "w") csd.write("<CsoundSynthesizer>\n\n") csd.write("<CsOptions>\n") csd.write("-+rtaudio=alsa -odevaudio -m0 -d -b256 -B512\n") csd.write("</CsOptions>\n\n") csd.write("<CsInstruments>\n\n") csd.write("sr=16000\n") csd.write("ksmps=50\n") csd.write("nchnls=1\n\n") for line in self.orchlines: csd.write(line) csd.write("\n</CsInstruments>\n\n") csd.write("<CsScore>\n\n") csd.write("f1 0 2048 10 1\n") csd.write("f2 0 2048 10 1 0 .33 0 .2 0 .143 0 .111\n") csd.write("f3 0 2048 10 1 .5 .33 .25 .2 .175 .143 .125 .111 .1\n") csd.write("f10 0 2048 10 1 0 0 .3 0 .2 0 0 .1\n") csd.write("f99 0 2048 7 1 2048 1\n") csd.write("f100 0 2048 7 0. 10 1. 1900 1. 132 0.\n") csd.write(self.scorelines.pop()) csd.write("e\n") csd.write("\n</CsScore>\n") csd.write("\n</CsoundSynthesizer>") csd.close()
class TextAttributesToolbar(Gtk.Toolbar): def __init__(self, main_area): Gtk.Toolbar.__init__(self) self._main_area = main_area self._font_list = ['ABC123', 'Sans', 'Serif', 'Monospace', 'Symbol'] self._font_sizes = [ '8', '9', '10', '11', '12', '14', '16', '20', '22', '24', '26', '28', '36', '48', '72' ] self.font_button = ToolButton('font-text') self.font_button.set_tooltip(_('Select font')) self.font_button.connect('clicked', self.__font_selection_cb) self.insert(self.font_button, -1) self._setup_font_palette() self.insert(Gtk.SeparatorToolItem(), -1) self.font_size_up = ToolButton('resize+') self.font_size_up.set_tooltip(_('Bigger')) self.font_size_up.connect('clicked', self.__font_sizes_cb, True) self.insert(self.font_size_up, -1) if len(self._main_area.selected) > 0: font_size = self._main_area.font_size else: font_size = utils.default_font_size self.size_label = Gtk.Label(str(font_size)) self.size_label.show() toolitem = Gtk.ToolItem() toolitem.add(self.size_label) toolitem.show() self.insert(toolitem, -1) self.font_size_down = ToolButton('resize-') self.font_size_down.set_tooltip(_('Smaller')) self.font_size_down.connect('clicked', self.__font_sizes_cb, False) self.insert(self.font_size_down, -1) self.insert(Gtk.SeparatorToolItem(), -1) self.bold = ToolButton('bold-text') self.bold.set_tooltip(_('Bold')) self.bold.connect('clicked', self.__bold_cb) self.insert(self.bold, -1) self.italics = ToolButton('italics-text') self.italics.set_tooltip(_('Italics')) self.italics.connect('clicked', self.__italics_cb) self.insert(self.italics, -1) self.underline = ToolButton('underline-text') self.underline.set_tooltip(_('Underline')) self.underline.connect('clicked', self.__underline_cb) self.insert(self.underline, -1) foreground_color = ColorToolButton() foreground_color.set_title(_('Set font color')) foreground_color.connect('color-set', self.__foreground_color_cb) self.insert(foreground_color, -1) bakground_color = ColorToolButton() bakground_color.set_title(_('Set background color')) bakground_color.connect('color-set', self.__background_color_cb) bakground_color.set_color(Gdk.Color(65535, 65535, 65535)) self.insert(bakground_color, -1) self.show_all() def __font_selection_cb(self, widget): if self._font_palette: if not self._font_palette.is_up(): self._font_palette.popup(immediate=True, state=self._font_palette.SECONDARY) else: self._font_palette.popdown(immediate=True) return def _init_font_list(self): self._font_white_list = [] self._font_white_list.extend(DEFAULT_FONTS) # check if there are a user configuration file if not os.path.exists(USER_FONTS_FILE_PATH): # verify if exists a file in /etc if os.path.exists(GLOBAL_FONTS_FILE_PATH): shutil.copy(GLOBAL_FONTS_FILE_PATH, USER_FONTS_FILE_PATH) if os.path.exists(USER_FONTS_FILE_PATH): # get the font names in the file to the white list fonts_file = open(USER_FONTS_FILE_PATH) # get the font names in the file to the white list for line in fonts_file: self._font_white_list.append(line.strip()) # monitor changes in the file gio_fonts_file = Gio.File.new_for_path(USER_FONTS_FILE_PATH) self.monitor = gio_fonts_file.monitor_file(0, None) self.monitor.set_rate_limit(5000) self.monitor.connect('changed', self._reload_fonts) def _reload_fonts(self, monitor, gio_file, other_file, event): if event != Gio.FileMonitorEvent.CHANGES_DONE_HINT: return self._font_white_list = [] self._font_white_list.extend(DEFAULT_FONTS) fonts_file = open(USER_FONTS_FILE_PATH) for line in fonts_file: self._font_white_list.append(line.strip()) # update the menu for child in self._font_palette.menu.get_children(): self._font_palette.menu.remove(child) child = None context = self.get_pango_context() tmp_list = [] for family in context.list_families(): name = family.get_name() if name in self._font_white_list: tmp_list.append(name) for font in sorted(tmp_list): menu_item = MyMenuItem(image=FontImage(font.replace(' ', '-')), text_label=font) menu_item.connect('activate', self.__font_selected_cb, font) self._font_palette.menu.append(menu_item) menu_item.show() return False def _setup_font_palette(self): self._init_font_list() context = self._main_area.pango_context for family in context.list_families(): name = Pango.FontDescription(family.get_name()).to_string() if name not in self._font_list and \ name in self._font_white_list: self._font_list.append(name) self._font_palette = self.font_button.get_palette() for font in sorted(self._font_list): menu_item = MyMenuItem(image=FontImage(font.replace(' ', '-')), text_label=font) menu_item.connect('activate', self.__font_selected_cb, font) self._font_palette.menu.append(menu_item) menu_item.show() def __font_selected_cb(self, widget, font_name): if not hasattr(self._main_area, 'font_name'): return if len(self._main_area.selected) > 0: font_size = self._main_area.font_size else: font_size = utils.default_font_size self._main_area.set_font(font_name, font_size) self._main_area.font_name = font_name self._main_area.font_size = font_size def __attribute_values(self): thought = self._main_area.selected[0] return thought.attributes.copy() def __font_sizes_cb(self, button, increase): if not hasattr(self._main_area, 'font_size'): return if len(self._main_area.selected) < 1: return font_size = self._main_area.font_size if font_size in self._font_sizes: i = self._font_sizes.index(font_size) if increase: if i < len(self._font_sizes) - 2: i += 1 else: if i > 0: i -= 1 else: i = self._font_sizes.index(utils.default_font_size) font_size = self._font_sizes[i] self.size_label.set_text(str(font_size)) self.font_size_down.set_sensitive(i != 0) self.font_size_up.set_sensitive(i < len(self._font_sizes) - 2) self._main_area.set_font(self._main_area.font_name, font_size) def __bold_cb(self, button): if len(self._main_area.selected) < 1: return value = not self.__attribute_values()["bold"] self._main_area.set_bold(value) def __italics_cb(self, button): if len(self._main_area.selected) < 1: return value = not self.__attribute_values()["italic"] self._main_area.set_italics(value) def __underline_cb(self, button): if len(self._main_area.selected) < 1: return value = not self.__attribute_values()["underline"] self._main_area.set_underline(value) def __foreground_color_cb(self, button): color = button.get_color() self._main_area.set_foreground_color(color) def __background_color_cb(self, button): color = button.get_color() self._parent._main_area.set_background_color(color) def change_active_font(self): # TODO: update the toolbar return
class GNUChessActivity(activity.Activity): ''' Gnuchess interface from Sugar ''' def __init__(self, handle): ''' Initialize the toolbars and the gnuchess ''' try: super(GNUChessActivity, self).__init__(handle) except dbus.exceptions.DBusException as e: _logger.error(str(e)) self.game_data = None self.playing_white = True self.playing_mode = 'easy' self.playing_robot = True self.showing_game_history = False self._restoring = True self.stopwatch_running = False self.time_interval = None self.timer_panel_visible = False self.nick = profile.get_nick_name() if profile.get_color() is not None: self.colors = profile.get_color().to_string().split(',') else: self.colors = ['#A0FFA0', '#FF8080'] self.buddy = None self.opponent_colors = None self.hardware = get_hardware() self._setup_toolbars() self._setup_dispatch_table() # Create a canvas canvas = Gtk.DrawingArea() canvas.set_size_request(Gdk.Screen.width(), Gdk.Screen.height()) self.set_canvas(canvas) canvas.show() self.show_all() self.old_cursor = self.get_window().get_cursor() self._gnuchess = Gnuchess(canvas, parent=self, path=activity.get_bundle_path(), colors=self.colors) self.connect('shared', self._shared_cb) self.connect('joined', self._joined_cb) self._restoring = False self.collab = CollabWrapper(self) self.collab.connect('message', self._message_cb) self.collab.connect('joined', self._joined_cb) self.collab.setup() # Send the nick to our opponent if not self.collab.props.leader: self.send_nick() # And let the sharer know we've joined self.send_join() if self.game_data is not None: # 'saved_game' in self.metadata: self._restore() else: self._gnuchess.new_game() def set_data(self, data): pass def get_data(self): return None def _alert_cancel_cb(self, alert, response_id): self.remove_alert(alert) def restore_cursor(self): ''' No longer thinking, so restore standard cursor. ''' self.get_window().set_cursor(self.old_cursor) def set_thinking_cursor(self): ''' Thinking, so set watch cursor. ''' self.old_cursor = self.get_window().get_cursor() Watch = Gdk.Cursor(Gdk.CursorType.WATCH) self.get_window().set_cursor(Watch) def _setup_toolbars(self): ''' Setup the toolbars. ''' self.max_participants = 2 self.edit_toolbar = Gtk.Toolbar() self.view_toolbar = Gtk.Toolbar() self.adjust_toolbar = Gtk.Toolbar() self.custom_toolbar = Gtk.Toolbar() toolbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() edit_toolbar_button = ToolbarButton(label=_("Edit"), page=self.edit_toolbar, icon_name='toolbar-edit') self.edit_toolbar.show() toolbox.toolbar.insert(edit_toolbar_button, -1) edit_toolbar_button.show() view_toolbar_button = ToolbarButton(label=_("View"), page=self.view_toolbar, icon_name='toolbar-view') self.view_toolbar.show() toolbox.toolbar.insert(view_toolbar_button, -1) view_toolbar_button.show() adjust_toolbar_button = ToolbarButton(label=_('Adjust'), page=self.adjust_toolbar, icon_name='preferences-system') self.adjust_toolbar.show() toolbox.toolbar.insert(adjust_toolbar_button, -1) adjust_toolbar_button.show() custom_toolbar_button = ToolbarButton(label=_("Custom"), page=self.custom_toolbar, icon_name='view-source') self.custom_toolbar.show() toolbox.toolbar.insert(custom_toolbar_button, -1) custom_toolbar_button.show() self.set_toolbar_box(toolbox) toolbox.show() self.toolbar = toolbox.toolbar adjust_toolbar_button.set_expanded(True) button_factory('edit-copy', self.edit_toolbar, self._copy_cb, tooltip=_('Copy'), accelerator='<Ctrl>c') button_factory('edit-paste', self.edit_toolbar, self._paste_cb, tooltip=_('Paste'), accelerator='<Ctrl>v') button_factory('view-fullscreen', self.view_toolbar, self.do_fullscreen_cb, tooltip=_('Fullscreen'), accelerator='<Alt>Return') button_factory('media-playback-start', self.view_toolbar, self._play_history_cb, tooltip=_('Play game history')) self.history_button = button_factory('list-numbered', self.view_toolbar, self._show_history_cb, tooltip=_('Show game history')) separator_factory(self.view_toolbar, False, True) label_factory(self.view_toolbar, _('White: ')) self.white_entry = entry_factory('', self.view_toolbar, tooltip=_("White's move")) separator_factory(self.view_toolbar, False, False) label_factory(self.view_toolbar, _('Black: ')) self.black_entry = entry_factory('', self.view_toolbar, tooltip=_("Black's move")) separator_factory(self.view_toolbar, False, True) skin_button1 = radio_factory('white-knight', self.view_toolbar, self.do_default_skin_cb, tooltip=_('Default pieces'), group=None) skin_button2 = radio_factory('white-knight-sugar', self.view_toolbar, self.do_sugar_skin_cb, tooltip=_('Sugar-style pieces'), group=skin_button1) xocolors = XoColor(','.join(self.colors)) icon = Icon(icon_name='white-knight-sugar', xo_color=xocolors) icon.show() skin_button2.set_icon_widget(icon) self.skin_button3 = radio_factory('white-knight-custom', self.view_toolbar, self.do_custom_skin_cb, tooltip=_('Custom pieces'), group=skin_button1) skin_button1.set_active(True) self.play_white_button = radio_factory('white-rook', self.adjust_toolbar, self._play_white_cb, group=None, tooltip=_('Play White')) self.play_black_button = radio_factory('black-rook', self.adjust_toolbar, self._play_black_cb, group=self.play_white_button, tooltip=_('Play Black')) self.play_white_button.set_active(True) separator_factory(self.adjust_toolbar, False, True) self.easy_button = radio_factory('beginner', self.adjust_toolbar, self._easy_cb, group=None, tooltip=_('Beginner')) self.hard_button = radio_factory('expert', self.adjust_toolbar, self._hard_cb, group=self.easy_button, tooltip=_('Expert')) self.easy_button.set_active(True) separator_factory(self.adjust_toolbar, False, True) self.robot_button = radio_factory( 'robot', self.adjust_toolbar, self._robot_cb, group=None, tooltip=_('Play against the computer')) self.human_button = radio_factory('human', self.adjust_toolbar, self._human_cb, group=self.robot_button, tooltip=_('Play against a person')) separator_factory(self.adjust_toolbar, False, False) self.opponent = label_factory(self.adjust_toolbar, '') separator_factory(self.adjust_toolbar, False, True) self.timer_button = ToolButton('timer-0') self.timer_button.set_tooltip(_('Timer')) self.timer_button.connect('clicked', self._timer_button_cb) self.toolbar.insert(self.timer_button, -1) self._setup_timer_palette() self.timer_button.show() self.timer_button.set_sensitive(True) self.robot_button.set_active(True) button_factory('new-game', self.toolbar, self._new_gnuchess_cb, tooltip=_('New game')) button_factory('edit-undo', self.toolbar, self._undo_cb, tooltip=_('Undo')) button_factory('hint', self.toolbar, self._hint_cb, tooltip=_('Hint')) separator_factory(self.toolbar, False, False) self.status = label_factory(self.toolbar, '', width=150) self.status.set_label(_("It is White's move.")) separator_factory(toolbox.toolbar, True, False) stop_button = StopButton(self) stop_button.props.accelerator = '<Ctrl>q' toolbox.toolbar.insert(stop_button, -1) stop_button.show() for piece in list(PIECES.keys()): for color in ['white', 'black']: button_factory('%s-%s' % (color, piece), self.custom_toolbar, self._reskin_cb, cb_arg='%s_%s' % (color, piece), tooltip=PIECES[piece][color]) def do_default_skin_cb(self, button=None): for piece in list(PIECES.keys()): for color in ['white', 'black']: self._gnuchess.reskin_from_file( '%s_%s' % (color, piece), '%s/icons/%s-%s.svg' % (activity.get_bundle_path(), color, piece)) def _black_pieces(self, colors): for piece in list(PIECES.keys()): self._gnuchess.reskin_from_svg('black_%s' % piece, colors, bw='#000000') def _white_pieces(self, colors): for piece in list(PIECES.keys()): self._gnuchess.reskin_from_svg('white_%s' % piece, colors, bw='#ffffff') def do_sugar_skin_cb(self, button=None): colors = self.colors if not self._gnuchess.we_are_sharing: self._black_pieces(colors) self._white_pieces(colors) else: if self.playing_white: self._white_pieces(colors) if self.opponent_colors is not None: colors = self.opponent_colors self._black_pieces(colors) else: self._black_pieces(colors) if self.opponent_colors is not None: colors = self.opponent_colors self._white_pieces(colors) def do_custom_skin_cb(self, button=None): for piece in list(PIECES.keys()): for color in ['white', 'black']: name = '%s_%s' % (color, piece) if name in self.metadata: id = self.metadata[name] jobject = datastore.get(id) if jobject is not None and jobject.file_path is not None: self._do_reskin(name, jobject.file_path) def _do_reskin(self, name, file_path): ''' If we are sharing, only reskin pieces of your color ''' if self._gnuchess.we_are_sharing and self.buddy is not None: if 'white' in name and self.playing_white: pixbuf = self._gnuchess.reskin_from_file(name, file_path, return_pixbuf=True) self.send_piece(name, pixbuf) elif 'black' in name and not self.playing_white: pixbuf = self._gnuchess.reskin_from_file(name, file_path, return_pixbuf=True) self.send_piece(name, pixbuf) else: self._gnuchess.reskin_from_file(name, file_path) return def _timer_button_cb(self, button): if not self.timer_palette.is_up() and not self.timer_panel_visible: self.timer_palette.popup(immediate=True) self.timer_panel_visible = True else: self.timer_palette.popdown(immediate=True) self.timer_panel_visible = False def _setup_timer_palette(self): self.timer_values = [None, 30, 180, 600] self.timer_tooltips = [ '', _('30 seconds'), _('3 minutes'), _('10 minutes') ] self.timer_labels = [ _('Disabled'), # TRANS: Lightning chess 30 seconds between moves _('Lightning: %d seconds') % (30), # TRANS: Blitz chess 3 minutes between moves _('Blitz: %d minutes') % (3), # TRANS: Tournament chess 10 minutes between moves _('Tournament: %d minutes') % (10) ] self.timer_palette = self.timer_button.get_palette() for i, label in enumerate(self.timer_labels): menu_item = MenuItem(icon_name='timer-%d' % (i), text_label=label) menu_item.connect('activate', self._timer_selected_cb, i) self.timer_palette.menu.append(menu_item) menu_item.show() def _timer_selected_cb(self, button, index): game_already_started = 0 if self.time_interval is not None: game_already_started = 1 self.time_interval = self.timer_values[index] if self.time_interval is None: self.timer_button.set_tooltip(_('Timer off')) else: self.timer_button.set_tooltip( _('Timer') + ' (' + self.timer_tooltips[index] + ')') if game_already_started: self.alert_reset(self.timer_labels[index]) if self.time_interval and self.time_interval is not None: self.stopwatch(self.time_interval, self.alert_time) else: GLib.source_remove(self.stopwatch_timer) else: self._gnuchess.new_game() def _reskin_cb(self, button, piece): object_id, file_path = self._choose_skin() if file_path is not None: self._do_reskin(piece, file_path) self.metadata[piece] = str(object_id) def do_fullscreen_cb(self, button): ''' Hide the Sugar toolbars. ''' self.fullscreen() def _play_history_cb(self, button): self._gnuchess.play_game_history() return def _show_history_cb(self, button): self._gnuchess.show_game_history(self.tag_pairs()) if self.showing_game_history: self.history_button.set_icon_name('checkerboard') self.history_button.set_tooltip(_('Show game board')) else: self.history_button.set_icon_name('list-numbered') self.history_button.set_tooltip(_('Show game history')) return def _copy_cb(self, *args): clipboard = Gtk.Clipboard() clipboard.set_text(self.tag_pairs() + self._gnuchess.copy_game()) def _paste_cb(self, *args): ''' Pasting ''' clipboard = Gtk.Clipboard() move_list = self._parse_move_list(clipboard.wait_for_text()) if move_list is not None: self._gnuchess.restore_game(move_list) def _parse_move_list(self, text): ''' Take a standard game description and return a move list ''' # Assuming of form ... 1. e4 e6 2. ... move_list = [] found_one = False comment = False for move in text.split(): if move[0] == '{': comment = True elif move[-1] == '}': comment = False if not comment: if move == '1.': found_one = True number = True white = False elif found_one: if not number: number = True elif not white: move_list.append(move) white = True else: move_list.append(move) number = False white = False return move_list def _undo_cb(self, *args): # No undo while sharing if self.collab.props.leader is None: self._gnuchess.undo() def _hint_cb(self, *args): self._gnuchess.hint() def _play_white_cb(self, *args): if not self.play_white_button.get_active(): return if not self._restoring: self._new_game_alert('white') return True def _play_black_cb(self, *args): if not self.play_black_button.get_active(): return if not self._restoring: self._new_game_alert('black') return True def _easy_cb(self, *args): if not self.easy_button.get_active(): return if not self._restoring: self._new_game_alert('easy') return True def _hard_cb(self, *args): if not self.hard_button.get_active(): return if not self._restoring: self._new_game_alert('hard') return True def _robot_cb(self, *args): if not self.robot_button.get_active(): return if not self._restoring: self._new_game_alert('robot') return True def _human_cb(self, *args): if not self.human_button.get_active(): return if not self._restoring: self._new_game_alert('human') return True def _new_gnuchess_cb(self, button=None): ''' Start a new gnuchess. ''' self._new_game_alert('new') def tag_pairs(self): ''' Tag paris must be ascii ''' if type(self.nick) is str: nick = self.nick.encode('ascii', 'replace') else: nick = self.nick if self.buddy is not None and type(self.buddy) is str: buddy = self.buddy.encode('ascii', 'replace') else: buddy = self.buddy if self.playing_white: white = nick if self.playing_robot: black = 'gnuchess (%s)' % (self.playing_mode) elif self._gnuchess.we_are_sharing and buddy is not None: black = buddy else: black = '?' else: black = nick if self.playing_robot: white = 'gnuchess (%s)' % (self.playing_mode) elif self._gnuchess.we_are_sharing and buddy is not None: white = buddy else: white = '?' return '[White "%s"]\n[Black "%s"]\n\n' % (white, black) def write_file(self, file_path): ''' Write the grid status to the Journal ''' fd = open(file_path, 'w') fd.write(self.tag_pairs()) fd.write(self._gnuchess.copy_game()) fd.close() # self.metadata['saved_game'] = json_dump(self._gnuchess.save_game()) if self.playing_white: self.metadata['playing_white'] = 'True' else: self.metadata['playing_white'] = 'False' self.metadata['playing_mode'] = self.playing_mode if self.playing_robot: self.metadata['playing_robot'] = 'True' else: self.metadata['playing_robot'] = 'False' ''' self.metadata['timer_mode'] = self.timer.get_active_text() ''' def read_file(self, file_path): ''' Read project file on relaunch ''' fd = open(file_path, 'r') self.game_data = fd.read() fd.close() _logger.debug(self.game_data) def _restore(self): ''' Restore the gnuchess state from metadata ''' if 'playing_white' in self.metadata: if self.metadata['playing_white'] == 'False': self.playing_white = False self.play_black_button.set_active(True) if 'playing_mode' in self.metadata: self.playing_mode = self.metadata['playing_mode'] if self.playing_mode == 'hard': self.hard_button.set_active(True) if 'playing_robot' in self.metadata: if self.metadata['playing_robot'] == 'False': self.playing_robot = False self.human_button.set_active(True) ''' if 'timer_mode' in self.metadata: self.timer_intervale.set_active(self.timer_list.index( self.metadata['timer_mode'])) ''' self._gnuchess.restore_game(self._parse_move_list(self.game_data)) self.do_custom_skin_cb() def _choose_skin(self): ''' Select a skin from the Journal ''' chooser = None name = None if hasattr(mime, 'GENERIC_TYPE_IMAGE'): if 'image/svg+xml' not in \ mime.get_generic_type(mime.GENERIC_TYPE_IMAGE).mime_types: mime.get_generic_type( mime.GENERIC_TYPE_IMAGE).mime_types.append('image/svg+xml') chooser = ObjectChooser(parent=self, what_filter=mime.GENERIC_TYPE_IMAGE) else: try: chooser = ObjectChooser(parent=self, what_filter=None) except TypeError: chooser = ObjectChooser( None, activity, Gtk.DialogType.MODAL | Gtk.DialogType.DESTROY_WITH_PARENT) if chooser is not None: try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() if jobject and jobject.file_path: name = jobject.metadata['title'] finally: jobject.destroy() chooser.destroy() del chooser if name is not None: return jobject.object_id, jobject.file_path else: return None, None def _take_button_action(self, button): if button == 'black': self.playing_white = False elif button == 'white': self.playing_white = True elif button == 'easy': self.playing_mode = 'easy' elif button == 'hard': self.playing_mode = 'hard' elif button == 'robot': self.playing_robot = True elif button == 'human': self.playing_robot = False self._gnuchess.new_game() def _no_action(self, button): if button == 'black': self.play_white_button.set_active(True) self.playing_white = True elif button == 'white': self.play_black_button.set_active(True) self.playing_white = False elif button == 'easy': self.hard_button.set_active(True) self.playing_mode = 'hard' elif button == 'hard': self.easy_button.set_active(True) self.playing_mode = 'easy' elif button == 'robot': self.human_button.set_active(True) self.playing_robot = False elif button == 'human': self.robot_button.set_active(True) self.playing_robot = True def _new_game_alert(self, button): ''' We warn the user if the game is in progress before loading a new game. ''' if self.collab.props.leader is not None and not self.collab.props.leader: # joiner cannot push buttons self._restoring = True self._no_action(button) self._restoring = False return if len(self._gnuchess.move_list) == 0: self._take_button_action(button) return self._restoring = True alert = ConfirmationAlert() alert.props.title = _('Game in progress.') alert.props.msg = _('Do you want to start a new game?') def _new_game_alert_response_cb(alert, response_id, self, button): if response_id is Gtk.ResponseType.OK: self._take_button_action(button) elif response_id is Gtk.ResponseType.CANCEL: self._no_action(button) self._restoring = False self.remove_alert(alert) alert.connect('response', _new_game_alert_response_cb, self, button) self.add_alert(alert) alert.show() # Collaboration-related methods def _shared_cb(self, activity): ''' Either set up initial share...''' _logger.debug('shared') self.after_share_join(True) def _joined_cb(self, activity): ''' ...or join an exisiting share. ''' _logger.debug('joined') self.after_share_join(False) self.send_nick() # And let the sharer know we've joined self.send_join() def after_share_join(self, sharer): self._gnuchess.set_sharing(True) self.restoring = True self.playing_robot = False self.human_button.set_active(True) self.robot_button.set_active(False) self.restoring = False self.easy_button.set_sensitive(False) self.hard_button.set_sensitive(False) self.robot_button.set_sensitive(False) def _setup_dispatch_table(self): ''' Associate tokens with commands. ''' self._processing_methods = { 'n': [self._receive_new_game, 'start a new game'], 'm': [self._receive_move, 'make a move'], 'r': [self._receive_restore, 'restore game state'], 'N': [self._receive_nick, 'receive nick from opponent'], 'C': [self._receive_colors, 'receive colors from opponent'], 'j': [self._receive_join, 'receive new joiner'], 'p': [self._receive_piece, 'receive new piece'], } def _message_cb(self, collab, buddy, msg): ''' Data from a tube has arrived. ''' command = msg.get("command") payload = msg.get("payload") self._processing_methods[command][0](payload) def send_new_game(self): ''' Send a new game to joiner. ''' if not self.collab.props.leader: return self.send_nick() if self.playing_white: _logger.debug('send_new_game: B') self.send_event("n", "B") else: _logger.debug('send_new_game: W') self.send_event("n", "W") def send_restore(self): ''' Send a new game to joiner. ''' if not self.collab.props.leader: return _logger.debug('send_restore') self.send_event("r", self._gnuchess.copy_game()) def send_join(self): _logger.debug('send_join') self.send_event("j", self.nick) def send_nick(self): _logger.debug('send_nick') self.send_event("N", self.nick) self.send_event("C", "%s,%s" % (self.colors[0], self.colors[1])) def alert_time(self): def _alert_response_cb(alert, response_id): self.remove_alert(alert) alert = NotifyAlert() alert.props.title = _('Time Up!') alert.props.msg = _('Your time is up.') alert.connect('response', _alert_response_cb) alert.show() self.add_alert(alert) def alert_reset(self, mode): def _alert_response_cb(alert, response_id): self.remove_alert(alert) alert = NotifyAlert() alert.props.title = _('Time Reset') alert.props.msg = _('The timer mode was reset to %s' % mode) alert.connect('response', _alert_response_cb) alert.show() self.add_alert(alert) def stopwatch(self, time, alert_callback): if self.stopwatch_running: GLib.source_remove(self.stopwatch_timer) time = self.time_interval self.stopwatch_timer = GLib.timeout_add(time * 1000, alert_callback) self.stopwatch_running = True def _receive_join(self, payload): _logger.debug('received_join %s' % (payload)) if self.collab.props.leader: self.send_new_game() _logger.debug(self.game_data) if self.game_data is not None: self.send_restore() def _receive_nick(self, payload): _logger.debug('received_nick %s' % (payload)) self.buddy = payload self.opponent.set_label(self.buddy) if self.collab.props.leader: self.send_nick() def _receive_colors(self, payload): _logger.debug('received_colors %s' % (payload)) self.opponent_colors = payload.split(',') xocolors = XoColor(payload) icon = Icon(icon_name='human', xo_color=xocolors) icon.show() self.human_button.set_icon_widget(icon) self.human_button.show() def _receive_restore(self, payload): ''' Get game state from sharer. ''' if self.collab.props.leader: return _logger.debug('received_restore %s' % (payload)) self._gnuchess.restore_game(self._parse_move_list(payload)) def _receive_move(self, payload): ''' Get a move from opponent. ''' _logger.debug('received_move %s' % (payload)) self._gnuchess.remote_move(payload) def _receive_new_game(self, payload): ''' Sharer can start a new gnuchess. ''' _logger.debug('receive_new_game %s' % (payload)) # The leader cannot receive new game if self.collab.props.leader: return self.send_nick() if payload == 'W': if not self.playing_white: self.restoring = True self.play_black_button.set_active(False) self.play_white_button.set_active(True) self.playing_white = True else: if self.playing_white: self.restoring = True self.play_white_button.set_active(False) self.play_black_button.set_active(True) self.playing_white = False self.robot_button.set_active(False) self.human_button.set_active(True) self.playing_robot = False self.restoring = False self._gnuchess.set_sharing(True) self._gnuchess.new_game() def send_event(self, command, payload): ''' Send event through the tube. ''' if hasattr(self, 'collab') and self.collab is not None: self.collab.post(dict(command=command, payload=payload)) # sharing pieces def send_piece(self, piece, pixbuf): _logger.debug('send_piece %s' % (piece)) GLib.idle_add(self.send_event, ("p", self._dump(piece, pixbuf))) def _receive_piece(self, payload): piece, pixbuf = self._load(payload) _logger.debug('received_piece %s' % (piece)) self._gnuchess.reskin(piece, pixbuf) def _dump(self, piece, pixbuf): ''' Dump data for sharing.''' _logger.debug('dumping %s' % (piece)) data = [piece, pixbuf_to_base64(activity, pixbuf)] return json_dump(data) def _load(self, data): ''' Load game data from the journal. ''' piece, pixbuf_data = json_load(data) pixbuf = base64_to_pixbuf(activity, pixbuf_data, width=self._gnuchess.scale, height=self._gnuchess.scale) return piece, pixbuf
class ViewToolbar(Gtk.Toolbar): __gtype_name__ = 'ViewToolbar' __gsignals__ = { 'go-fullscreen': (GObject.SignalFlags.RUN_FIRST, None, ([])), } def __init__(self): Gtk.Toolbar.__init__(self) self._view = None self._bookmarkmanager = None self._update_offset = True self._zoom_out = ToolButton('zoom-out') self._zoom_out.set_tooltip(_('Zoom out')) self._zoom_out.connect('clicked', self._zoom_out_cb) self.insert(self._zoom_out, -1) self._zoom_out.show() self._zoom_in = ToolButton('zoom-in') self._zoom_in.set_tooltip(_('Zoom in')) self._zoom_in.connect('clicked', self._zoom_in_cb) self.insert(self._zoom_in, -1) self._zoom_in.show() self._zoom_to_width = ToolButton('zoom-best-fit') self._zoom_to_width.set_tooltip(_('Zoom to width')) self._zoom_to_width.connect('clicked', self._zoom_to_width_cb) self.insert(self._zoom_to_width, -1) self._zoom_to_width.show() palette = self._zoom_to_width.get_palette() menu_item = MenuItem(_('Zoom to fit')) menu_item.connect('activate', self._zoom_to_fit_menu_item_activate_cb) palette.menu.append(menu_item) menu_item.show() menu_item = MenuItem(_('Actual size')) menu_item.connect('activate', self._actual_size_menu_item_activate_cb) palette.menu.append(menu_item) menu_item.show() tool_item = Gtk.ToolItem() self.insert(tool_item, -1) tool_item.show() self._zoom_spin = Gtk.SpinButton() self._zoom_spin.set_range(5.409, 400) self._zoom_spin.set_increments(1, 10) self._zoom_spin_notify_value_handler = self._zoom_spin.connect( 'notify::value', self._zoom_spin_notify_value_cb) tool_item.add(self._zoom_spin) self._zoom_spin.show() zoom_perc_label = Gtk.Label(_("%")) zoom_perc_label.show() tool_item_zoom_perc_label = Gtk.ToolItem() tool_item_zoom_perc_label.add(zoom_perc_label) self.insert(tool_item_zoom_perc_label, -1) tool_item_zoom_perc_label.show() spacer = Gtk.SeparatorToolItem() spacer.props.draw = False self.insert(spacer, -1) spacer.show() self._fullscreen = ToolButton('view-fullscreen') self._fullscreen.set_tooltip(_('Fullscreen')) self._fullscreen.connect('clicked', self._fullscreen_cb) self.insert(self._fullscreen, -1) self._fullscreen.show() self._view_notify_zoom_handler = None def set_view(self, view): self._view = view def set_bookmarkmanager(self, bookmarkmanager): self._bookmarkmanager = bookmarkmanager def _zoom_spin_notify_value_cb(self, zoom_spin, pspec): self._view.set_zoom(zoom_spin.props.value) def _view_notify_zoom_cb(self, model, pspec): self._zoom_spin.disconnect(self._zoom_spin_notify_value_handler) try: self._zoom_spin.props.value = round(self._view.get_zoom()) finally: self._zoom_spin_notify_value_handler = self._zoom_spin.connect( 'notify::value', self._zoom_spin_notify_value_cb) def __set_progress_if_applicable(self): if (self._view.show_progress_bar() is True) and \ (self._update_offset is True): self._view.get_maximum_offset_possible() def zoom_in(self, zoom_amount): self._view.zoom_in(zoom_amount) self._view._main_instance.window.force_ui_updates() self.__set_progress_if_applicable() def _zoom_in_cb(self, button, zoom_amount=1): if self._view.can_zoom_in(): self.zoom_in(zoom_amount) self._view._number_of_times_zoomed = \ self._view._number_of_times_zoomed + zoom_amount def zoom_out(self, zoom_amount): self._view.zoom_out(zoom_amount) self._view._main_instance.window.force_ui_updates() self.__set_progress_if_applicable() def _zoom_out_cb(self, button, zoom_amount=1): if self._view.can_zoom_out(): self.zoom_out(zoom_amount) self._view._number_of_times_zoomed = \ self._view._number_of_times_zoomed - zoom_amount def update_offset(self, update): self._update_offset = update def zoom_to_width(self): self._view.zoom_to_width() def _zoom_to_width_cb(self, button): self.zoom_to_width() def _zoom_to_fit_menu_item_activate_cb(self, menu_item): self._view.zoom_to_best_fit() def _actual_size_menu_item_activate_cb(self, menu_item): self._view.zoom_to_actual_size() def _fullscreen_cb(self, button): self.emit('go-fullscreen')
class ReadToolbar(Gtk.Toolbar): __gtype_name__ = 'ReadToolbar' def __init__(self): Gtk.Toolbar.__init__(self) self.back = ToolButton('go-previous') self.back.set_tooltip(_('Back')) self.back.props.sensitive = False palette = self.back.get_palette() self.prev_page = MenuItem(text_label= _("Previous page")) palette.menu.append(self.prev_page) self.prev_page.show_all() self.prev_bookmark = MenuItem(text_label= _("Previous bookmark")) palette.menu.append(self.prev_bookmark) self.prev_bookmark.show_all() self.back.connect('clicked', self.go_back_cb) self.prev_page.connect('activate', self.go_back_cb) self.prev_bookmark.connect('activate', self.prev_bookmark_activate_cb) self.insert(self.back, -1) self.back.show() self.forward = ToolButton('go-next') self.forward.set_tooltip(_('Forward')) self.forward.props.sensitive = False palette = self.forward.get_palette() self.next_page = MenuItem(text_label= _("Next page")) palette.menu.append(self.next_page) self.next_page.show_all() self.next_bookmark = MenuItem(text_label= _("Next bookmark")) palette.menu.append(self.next_bookmark) self.next_bookmark.show_all() self.forward.connect('clicked', self.go_forward_cb) self.next_page.connect('activate', self.go_forward_cb) self.next_bookmark.connect('activate', self.next_bookmark_activate_cb) self.insert(self.forward, -1) self.forward.show() num_page_item = Gtk.ToolItem() self.num_page_entry = Gtk.Entry() self.num_page_entry.set_text('0') self.num_page_entry.set_alignment(1) self.num_page_entry.connect('insert-text', self.num_page_entry_insert_text_cb) self.num_page_entry.connect('activate', self.num_page_entry_activate_cb) self.num_page_entry.set_width_chars(4) num_page_item.add(self.num_page_entry) self.num_page_entry.show() self.insert(num_page_item, -1) num_page_item.show() total_page_item = Gtk.ToolItem() self.total_page_label = Gtk.Label() self.total_page_label.set_markup("<span size='14000' foreground='black'>") self.total_page_label.set_text(' / 0') total_page_item.add(self.total_page_label) self.total_page_label.show() self.insert(total_page_item, -1) total_page_item.show() spacer = Gtk.SeparatorToolItem() self.insert(spacer, -1) spacer.show() bookmarkitem = Gtk.ToolItem() self.bookmarker = ToggleToolButton('emblem-favorite') self.bookmarker.set_tooltip(_('Toggle Bookmark')) self.bookmarker_handler_id = self.bookmarker.connect('clicked', self.bookmarker_clicked_cb) bookmarkitem.add(self.bookmarker) self.insert(bookmarkitem, -1) bookmarkitem.show_all() underline_item = Gtk.ToolItem() self.underline = ToggleToolButton('format-text-underline') self.underline.set_tooltip(_('Underline')) self.underline.props.sensitive = False self.underline_id = self.underline.connect('clicked', self.underline_cb) underline_item.add(self.underline) self.insert(underline_item, -1) underline_item.show_all() def num_page_entry_insert_text_cb(self, entry, text, length, position): if not re.match('[0-9]', text): entry.emit_stop_by_name('insert-text') return True return False def num_page_entry_activate_cb(self, entry): if entry.props.text: page = int(entry.props.text) - 1 else: page = 0 if page >= self.total_pages: page = self.total_pages - 1 elif page < 0: page = 0 self.current_page = page self.activity.set_current_page(page) self.activity.show_page(page) entry.props.text = str(page + 1) self.update_nav_buttons() def go_back_cb(self, button): self.activity.page_previous() def go_forward_cb(self, button): self.activity.page_next() def update_nav_buttons(self): current_page = self.current_page self.back.props.sensitive = current_page > 0 self.forward.props.sensitive = \ current_page < self.total_pages - 1 self.num_page_entry.props.text = str(current_page + 1) self.total_page_label.props.label = \ ' / ' + str(self.total_pages) def set_total_pages(self, pages): self.total_pages = pages def set_current_page(self, page): self.current_page = page self.update_nav_buttons() def set_activity(self, activity): self.activity = activity def prev_bookmark_activate_cb(self, menuitem): self.activity.prev_bookmark() def next_bookmark_activate_cb(self, menuitem): self.activity.next_bookmark() def bookmarker_clicked_cb(self, button): self.activity.bookmarker_clicked(button) def underline_cb(self, button): self.activity.underline_clicked(button) def setToggleButtonState(self,button,b,id): button.handler_block(id) button.set_active(b) button.handler_unblock(id) def update_underline_button(self, state): self.setToggleButtonState(self.underline, state, self.underline_id) def update_bookmark_button(self, state): self.setToggleButtonState(self.bookmarker, state, self.bookmarker_handler_id)
class RecordControl(): def __init__(self, toolbar): self._timer_value = TIMER_VALUES[0] self._timer_button = ToolButton('timer-0') self._timer_button.set_tooltip(_('Select timer')) self._timer_button.connect('clicked', self._timer_selection_cb) toolbar.insert(self._timer_button, -1) self._setup_timer_palette() self._duration_value = DURATION_VALUES[0] self._duration_button = ToolButton('duration-2') self._duration_button.set_tooltip(_('Select duration')) self._duration_button.connect('clicked', self._duration_selection_cb) toolbar.insert(self._duration_button, -1) self._setup_duration_palette() self._quality_value = 0 self._quality_button = ToolButton('low-quality') self._quality_button.set_tooltip(_('Select quality')) self._quality_button.connect('clicked', self._quality_selection_cb) toolbar.insert(self._quality_button, -1) self._setup_quality_palette() def _timer_selection_cb(self, widget): if self._timer_palette: if not self._timer_palette.is_up(): self._timer_palette.popup(immediate=True) else: self._timer_palette.popdown(immediate=True) return def _setup_timer_palette(self): self._timer_palette = self._timer_button.get_palette() box = PaletteMenuBox() self._timer_palette.set_content(box) box.show() for seconds in TIMER_VALUES: if seconds == 0: text = _('Immediate') else: text = ngettext('%s second', '%s seconds', seconds) % seconds menu_item = PaletteMenuItem(text, icon_name='timer-%d' % (seconds)) menu_item.connect('activate', self._timer_selected_cb, seconds) box.append_item(menu_item) menu_item.show() def _timer_selected_cb(self, button, seconds): self.set_timer_idx(TIMER_VALUES.index(seconds)) def _duration_selection_cb(self, widget): if self._duration_palette: if not self._duration_palette.is_up(): self._duration_palette.popup(immediate=True) else: self._duration_palette.popdown(immediate=True) return def _setup_duration_palette(self): self._duration_palette = self._duration_button.get_palette() box = PaletteMenuBox() self._duration_palette.set_content(box) box.show() for minutes in DURATION_VALUES: if minutes == 0: text = Gtk.Label(_('Immediate')) else: text = ngettext('%s minute', '%s minutes', minutes) % minutes menu_item = PaletteMenuItem(text, icon_name='duration-%d' % (minutes)) menu_item.connect('activate', self._duration_selected_cb, minutes) box.append_item(menu_item) menu_item.show() def _duration_selected_cb(self, button, minutes): self.set_duration_idx(DURATION_VALUES.index(minutes)) def _quality_selection_cb(self, widget): if self._quality_palette: if not self._quality_palette.is_up(): self._quality_palette.popup(immediate=True) else: self._quality_palette.popdown(immediate=True) return def _setup_quality_palette(self): self._quality_palette = self._quality_button.get_palette() box = PaletteMenuBox() self._quality_palette.set_content(box) box.show() for quality in QUALITY_VALUES: text = _('%s quality') % (quality) menu_item = PaletteMenuItem(text, icon_name=quality + '-quality') menu_item.connect('activate', self._quality_selected_cb, quality) box.append_item(menu_item) menu_item.show() def _quality_selected_cb(self, button, quality): self.set_quality(QUALITY_VALUES.index(quality)) def set_mode(self, mode): if mode == constants.MODE_PHOTO: self._quality_button.set_sensitive(False) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(False) if mode == constants.MODE_VIDEO: self._quality_button.set_sensitive(True) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(True) if mode == constants.MODE_AUDIO: self._quality_button.set_sensitive(False) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(True) def get_timer(self): return self._timer_value def get_timer_idx(self): if self._timer_value in TIMER_VALUES: return TIMER_VALUES.index(self._timer_value) else: return TIMER_VALUES[0] def set_timer_idx(self, idx): self._timer_value = TIMER_VALUES[idx] if hasattr(self, '_timer_button'): self._timer_button.set_icon_name('timer-%d' % (self._timer_value)) def get_duration(self): return self._duration_value def get_duration_idx(self): if self._duration_value in DURATION_VALUES: return DURATION_VALUES.index(self._duration_value) else: return DURATION_VALUES[0] def set_duration_idx(self, idx): self._duration_value = DURATION_VALUES[idx] if hasattr(self, '_duration_button'): self._duration_button.set_icon_name( 'duration-%d' % (self._duration_value)) def get_quality(self): return self._quality_value def set_quality(self, idx): self._quality_value = idx if hasattr(self, '_quality_button'): name = '%s-quality' % (QUALITY_VALUES[idx]) self._quality_button.set_icon_name(name)
def __init__(self, handle): activity.Activity.__init__(self, handle) # abiword uses the current directory for all its file dialogs os.chdir(os.path.expanduser('~')) # create our main abiword canvas self.abiword_canvas = DocumentView() self._new_instance = True toolbar_box = ToolbarBox() self.activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(self.activity_button, -1) separator = Gtk.SeparatorToolItem() separator.show() self.activity_button.props.page.insert(separator, 2) ExportButtonFactory(self, self.abiword_canvas) self.activity_button.show() edit_toolbar = ToolbarButton() edit_toolbar.props.page = EditToolbar(self, toolbar_box) edit_toolbar.props.icon_name = 'toolbar-edit' edit_toolbar.props.label = _('Edit') toolbar_box.toolbar.insert(edit_toolbar, -1) view_toolbar = ToolbarButton() view_toolbar.props.page = ViewToolbar(self.abiword_canvas) view_toolbar.props.icon_name = 'toolbar-view' view_toolbar.props.label = _('View') toolbar_box.toolbar.insert(view_toolbar, -1) # due to http://bugzilla.abisource.com/show_bug.cgi?id=13585 if self.abiword_canvas.get_version() != '3.0': self.speech_toolbar_button = ToolbarButton(icon_name='speak') toolbar_box.toolbar.insert(self.speech_toolbar_button, -1) self._init_speech() separator = Gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) text_toolbar = ToolbarButton() text_toolbar.props.page = TextToolbar(self.abiword_canvas) text_toolbar.props.icon_name = 'format-text' text_toolbar.props.label = _('Text') toolbar_box.toolbar.insert(text_toolbar, -1) para_toolbar = ToolbarButton() para_toolbar.props.page = ParagraphToolbar(self.abiword_canvas) para_toolbar.props.icon_name = 'paragraph-bar' para_toolbar.props.label = _('Paragraph') toolbar_box.toolbar.insert(para_toolbar, -1) insert_toolbar = ToolbarButton() insert_toolbar.props.page = InsertToolbar(self.abiword_canvas) insert_toolbar.props.icon_name = 'insert-table' insert_toolbar.props.label = _('Table') toolbar_box.toolbar.insert(insert_toolbar, -1) image = ToolButton('insert-picture') image.set_tooltip(_('Insert Image')) self._image_id = image.connect('clicked', self._image_cb) toolbar_box.toolbar.insert(image, -1) palette = image.get_palette() content_box = Gtk.VBox() palette.set_content(content_box) image_floating_checkbutton = Gtk.CheckButton(_('Floating')) image_floating_checkbutton.connect( 'toggled', self._image_floating_checkbutton_toggled_cb) content_box.pack_start(image_floating_checkbutton, True, True, 0) content_box.show_all() self.floating_image = False separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_size_request(0, -1) separator.set_expand(True) separator.show() toolbar_box.toolbar.insert(separator, -1) stop = StopButton(self) toolbar_box.toolbar.insert(stop, -1) toolbar_box.show_all() self.set_toolbar_box(toolbar_box) # add a overlay to be able to show a icon while joining a shared doc overlay = Gtk.Overlay() overlay.add(self.abiword_canvas) overlay.show() self._connecting_box = ConnectingBox() overlay.add_overlay(self._connecting_box) self.set_canvas(overlay) # we want a nice border so we can select paragraphs easily self.abiword_canvas.set_show_margin(True) # Read default font face and size client = GConf.Client.get_default() self._default_font_face = client.get_string( '/desktop/sugar/activities/write/font_face') if not self._default_font_face: self._default_font_face = 'Sans' self._default_font_size = client.get_int( '/desktop/sugar/activities/write/font_size') if self._default_font_size == 0: self._default_font_size = 12 # activity sharing self.participants = {} self.joined = False self.connect('shared', self._shared_cb) if self.shared_activity: # we are joining the activity logger.error('We are joining an activity') # display a icon while joining self._connecting_box.show() # disable the abi widget self.abiword_canvas.set_sensitive(False) self._new_instance = False self.connect('joined', self._joined_cb) self.shared_activity.connect('buddy-joined', self._buddy_joined_cb) self.shared_activity.connect('buddy-left', self._buddy_left_cb) if self.get_shared(): self._joined_cb(self) else: # we are creating the activity logger.error("We are creating an activity") self.abiword_canvas.zoom_width() self.abiword_canvas.show() self.connect_after('map-event', self.__map_activity_event_cb) self.abiword_canvas.connect('size-allocate', self.size_allocate_cb)
class PrimaryToolbar(ToolbarBase): __gtype_name__ = 'PrimaryToolbar' __gsignals__ = { 'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'set-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'reset-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'go-library': (GObject.SignalFlags.RUN_FIRST, None, ([])), } def __init__(self, tabbed_view, act): ToolbarBase.__init__(self) self._url_toolbar = UrlToolbar() self._activity = act self._tabbed_view = tabbed_view self._loading = False toolbar = self.toolbar activity_button = ActivityToolbarButton(self._activity) toolbar.insert(activity_button, 0) self._go_home = ToolButton('go-home') self._go_home.set_tooltip(_('Home page')) self._go_home.connect('clicked', self._go_home_cb) # add a menu to save the home page menu_box = PaletteMenuBox() self._go_home.props.palette.set_content(menu_box) menu_item = PaletteMenuItem() menu_item.set_label(_('Select as initial page')) menu_item.connect('activate', self._set_home_cb) menu_box.append_item(menu_item) self._reset_home_menu = PaletteMenuItem() self._reset_home_menu.set_label(_('Reset initial page')) self._reset_home_menu.connect('activate', self._reset_home_cb) menu_box.append_item(self._reset_home_menu) if os.path.isfile(LIBRARY_PATH): library_menu = PaletteMenuItem() library_menu.set_label(_('Library')) library_menu.connect('activate', self._go_library_cb) menu_box.append_item(library_menu) menu_box.show_all() # verify if the home page is configured client = GConf.Client.get_default() self._reset_home_menu.set_visible( client.get_string(HOME_PAGE_GCONF_KEY) is not None) toolbar.insert(self._go_home, -1) self._go_home.show() self.entry = WebEntry() self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-stop') self.entry.connect('icon-press', self._stop_and_reload_cb) self.entry.connect('activate', self._entry_activate_cb) self.entry.connect('focus-in-event', self.__focus_in_event_cb) self.entry.connect('focus-out-event', self.__focus_out_event_cb) self.entry.connect('key-press-event', self.__key_press_event_cb) self.entry.connect('changed', self.__changed_cb) self._entry_item = Gtk.ToolItem() self._entry_item.set_expand(True) self._entry_item.add(self.entry) self.entry.show() toolbar.insert(self._entry_item, -1) self._entry_item.show() self._back = ToolButton('go-previous-paired') self._back.set_tooltip(_('Back')) self._back.props.sensitive = False self._back.connect('clicked', self._go_back_cb) toolbar.insert(self._back, -1) self._back.show() palette = self._back.get_palette() self._back_box_menu = Gtk.VBox() self._back_box_menu.show() palette.set_content(self._back_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._forward = ToolButton('go-next-paired') self._forward.set_tooltip(_('Forward')) self._forward.props.sensitive = False self._forward.connect('clicked', self._go_forward_cb) toolbar.insert(self._forward, -1) self._forward.show() palette = self._forward.get_palette() self._forward_box_menu = Gtk.VBox() self._forward_box_menu.show() palette.set_content(self._forward_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._toolbar_separator = Gtk.SeparatorToolItem() self._toolbar_separator.props.draw = False self._toolbar_separator.set_expand(True) stop_button = StopButton(self._activity) toolbar.insert(stop_button, -1) self._progress_listener = None self._browser = None self._loading_changed_hid = None self._progress_changed_hid = None self._session_history_changed_hid = None self._uri_changed_hid = None self._security_status_changed_hid = None if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) tabbed_view.connect_after('switch-page', self.__switch_page_cb) tabbed_view.connect_after('page-added', self.__page_added_cb) Gdk.Screen.get_default().connect('size-changed', self.__screen_size_changed_cb) self._configure_toolbar() def __key_press_event_cb(self, entry, event): self._tabbed_view.current_browser.loading_uri = entry.props.text def __switch_page_cb(self, tabbed_view, page, page_num): if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) def __page_added_cb(self, notebook, child, pagenum): self.entry._search_popdown() def _configure_toolbar(self, screen=None): # Adapt the toolbars for portrait or landscape mode. if screen is None: screen = Gdk.Screen.get_default() if screen.get_width() < screen.get_height(): if self._entry_item in self._url_toolbar.toolbar.get_children(): return self.toolbar.remove(self._entry_item) self._url_toolbar.toolbar.insert(self._entry_item, -1) separator_pos = len(self.toolbar.get_children()) - 1 self.toolbar.insert(self._toolbar_separator, separator_pos) self._toolbar_separator.show() self.pack_end(self._url_toolbar, True, True, 0) self._url_toolbar.show() else: if self._entry_item in self.toolbar.get_children(): return self.toolbar.remove(self._toolbar_separator) position = len(self.toolbar.get_children()) - 4 self._url_toolbar.toolbar.remove(self._entry_item) self.toolbar.insert(self._entry_item, position) self._toolbar_separator.hide() self.remove(self._url_toolbar) def __screen_size_changed_cb(self, screen): self._configure_toolbar(screen) def _connect_to_browser(self, browser): if self._browser is not None: self._browser.disconnect(self._uri_changed_hid) self._browser.disconnect(self._progress_changed_hid) self._browser.disconnect(self._loading_changed_hid) self._browser.disconnect(self._security_status_changed_hid) self._browser = browser if not isinstance(self._browser, DummyBrowser): address = self._browser.props.uri or self._browser.loading_uri else: address = self._browser.props.uri self._set_address(address) self._set_progress(self._browser.props.progress) self._set_status(self._browser.props.load_status) self._set_security_status(self._browser.security_status) is_webkit_browser = isinstance(self._browser, Browser) self.entry.props.editable = is_webkit_browser self._uri_changed_hid = self._browser.connect( 'notify::uri', self.__uri_changed_cb) self._progress_changed_hid = self._browser.connect( 'notify::progress', self.__progress_changed_cb) self._loading_changed_hid = self._browser.connect( 'notify::load-status', self.__loading_changed_cb) self._security_status_changed_hid = self._browser.connect( 'security-status-changed', self.__security_status_changed_cb) self._update_navigation_buttons() def __loading_changed_cb(self, widget, param): self._set_status(widget.get_load_status()) def __security_status_changed_cb(self, widget): self._set_security_status(widget.security_status) def __progress_changed_cb(self, widget, param): self._set_progress(widget.get_progress()) def _set_status(self, status): self._set_loading(status < WebKit.LoadStatus.FINISHED) def _set_security_status(self, security_status): # Display security status as a lock icon in the left side of # the URL entry. if security_status is None: self.entry.set_icon_from_pixbuf( iconentry.ICON_ENTRY_PRIMARY, None) elif security_status == Browser.SECURITY_STATUS_SECURE: self.entry.set_icon_from_name( iconentry.ICON_ENTRY_PRIMARY, 'channel-secure-symbolic') elif security_status == Browser.SECURITY_STATUS_INSECURE: self.entry.set_icon_from_name( iconentry.ICON_ENTRY_PRIMARY, 'channel-insecure-symbolic') def _set_progress(self, progress): if progress == 1.0: self.entry.set_progress_fraction(0.0) else: self.entry.set_progress_fraction(progress) def _set_address(self, uri): if uri is None: self.entry.props.address = '' else: self.entry.props.address = uri def __changed_cb(self, iconentry): # The WebEntry can be changed when we click on a link, then we # have to show the clear icon only if is the user who has # changed the entry if self.entry.has_focus(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_in_event_cb(self, entry, event): if not self._tabbed_view.is_current_page_pdf(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_out_event_cb(self, entry, event): if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self._show_reload_icon() def _show_no_icon(self): self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY) def _show_stop_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-stop') def _show_reload_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-refresh') def _show_clear_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-cancel') def _update_navigation_buttons(self): can_go_back = self._browser.can_go_back() self._back.props.sensitive = can_go_back can_go_forward = self._browser.can_go_forward() self._forward.props.sensitive = can_go_forward is_webkit_browser = isinstance(self._browser, Browser) self._go_home.props.sensitive = is_webkit_browser if is_webkit_browser: self._reload_session_history() def _entry_activate_cb(self, entry): url = entry.props.text effective_url = self._tabbed_view.normalize_or_autosearch_url(url) self._browser.load_uri(effective_url) self._browser.loading_uri = effective_url self.entry.props.address = effective_url self._browser.grab_focus() def _go_home_cb(self, button): self.emit('go-home') def _go_library_cb(self, button): self.emit('go-library') def _set_home_cb(self, button): self._reset_home_menu.set_visible(True) self.emit('set-home') def _reset_home_cb(self, button): self._reset_home_menu.set_visible(False) self.emit('reset-home') def _go_back_cb(self, button): self._browser.go_back() def _go_forward_cb(self, button): self._browser.go_forward() def __uri_changed_cb(self, widget, param): self._set_address(widget.get_uri()) self._update_navigation_buttons() filepicker.cleanup_temp_files() def _stop_and_reload_cb(self, entry, icon_pos, button): if entry.has_focus() and \ not self._tabbed_view.is_current_page_pdf(): entry.set_text('') else: if self._loading: self._browser.stop_loading() else: self._browser.reload() def _set_loading(self, loading): self._loading = loading if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self.set_sensitive(True) self._show_reload_icon() else: self.set_sensitive(False) self._show_no_icon() def _reload_session_history(self): back_forward_list = self._browser.get_back_forward_list() item_index = 0 # The index of the history item # Clear menus in palettes: for box_menu in (self._back_box_menu, self._forward_box_menu): for menu_item in box_menu.get_children(): box_menu.remove(menu_item) def create_menu_item(history_item, item_index): """Create a MenuItem for the back or forward palettes.""" title = history_item.get_title() if not isinstance(title, unicode): title = unicode(title, 'utf-8') # This is a fix until the Sugar MenuItem is fixed: menu_item = PaletteMenuItem(text_label=title) menu_item.connect('activate', self._history_item_activated_cb, item_index) return menu_item back_list = back_forward_list.get_back_list_with_limit( _MAX_HISTORY_ENTRIES) back_list.reverse() for item in back_list: menu_item = create_menu_item(item, item_index) self._back_box_menu.pack_end(menu_item, False, False, 0) menu_item.show() item_index += 1 # Increment the item index to count the current page: item_index += 1 forward_list = back_forward_list.get_forward_list_with_limit( _MAX_HISTORY_ENTRIES) forward_list.reverse() for item in forward_list: menu_item = create_menu_item(item, item_index) self._forward_box_menu.pack_start(menu_item, False, False, 0) menu_item.show() item_index += 1 def _history_item_activated_cb(self, menu_item, index): self._back.get_palette().popdown(immediate=True) self._forward.get_palette().popdown(immediate=True) self._browser.set_history_index(index)
class InstrumentToolbar(Gtk.Toolbar): ''' The toolbar for adding new instruments ''' def __init__(self, activity): super(type(self), self).__init__() self.activity = activity self.new_instruments = [] self._name_entry = Gtk.Entry() self._name_entry.set_text(_('my instrument')) self._name_entry_changed_id = self._name_entry.connect( 'changed', self.update_name_entry) if hasattr(self._name_entry, 'set_tooltip_text'): self._name_entry.set_tooltip_text(_('Enter instrument name.')) self._name_entry.set_width_chars(24) self._name_entry.show() toolitem = Gtk.ToolItem() toolitem.add(self._name_entry) self.insert(toolitem, -1) toolitem.show() self._note = 'A' self._notes_button = ToolButton('notes') self._notes_button.set_tooltip(_('Notes')) self._notes_button.connect('clicked', self._button_selection_cb) self.insert(self._notes_button, -1) self._setup_notes_palette() self._notes_button.show() self._octave = 4 self._octaves_button = ToolButton('octaves') self._octaves_button.set_tooltip(_('Octaves')) self._octaves_button.connect('clicked', self._button_selection_cb) self.insert(self._octaves_button, -1) self._setup_octaves_palette() self._octaves_button.show() self._new_note = ToolButton('list-add') self._new_note.show() self.insert(self._new_note, -1) self._new_note.set_tooltip(_('Add a new note.')) self._new_note.connect('clicked', self.new_note_cb) self._new_note.show() def _button_selection_cb(self, widget): palette = widget.get_palette() if palette: if not palette.is_up(): palette.popup(immediate=True) else: palette.popdown(immediate=True) return def _setup_notes_palette(self): self._notes_palette = self._notes_button.get_palette() for note in NOTES: menu_item = MenuItem(icon_name='', text_label=note) menu_item.connect('activate', self._note_selected_cb, note) self._notes_palette.menu.append(menu_item) menu_item.show() def _note_selected_cb(self, widget, note): self._note = note def _setup_octaves_palette(self): self._octaves_palette = self._octaves_button.get_palette() for octave in range(9): menu_item = MenuItem(icon_name='', text_label=str(octave)) menu_item.connect('activate', self._octave_selected_cb, octave) self._octaves_palette.menu.append(menu_item) menu_item.show() def _octave_selected_cb(self, widget, octave): self._octave = octave def update_name_entry(self, *args): ''' Add name to INSTRUMENT_DICT and combo box ''' # Wait until a note has been added... return def new_note_cb(self, *args): ''' Add a new note to instrument tuning list ''' name = self._name_entry.get_text() if name not in INSTRUMENT_DICT: INSTRUMENT_DICT[name] = [] self.activity.tuning_toolbar.instrument.append(name) menu_item = MenuItem(icon_name='', text_label=name) menu_item.connect( 'activate', self.activity.tuning_toolbar.instrument_selected_cb, name) self.activity.tuning_toolbar.instrument_palette.menu.append( menu_item) menu_item.show() self.new_instruments.append(name) freq = A0 * pow(TWELTHROOT2, self._octave * 12 + NOTES.index(self._note)) if freq not in INSTRUMENT_DICT[name]: INSTRUMENT_DICT[name].append(freq)
def _load_custom_buttons(self, toolbar): self.numerator = Gtk.Entry() self.numerator.set_text('') self.numerator.set_tooltip_text(_('numerator')) self.numerator.set_width_chars(3) toolitem = Gtk.ToolItem() toolitem.add(self.numerator) self.numerator.show() toolbar.insert(toolitem, -1) toolitem.show() label = Gtk.Label(' / ') toolitem = Gtk.ToolItem() toolitem.add(label) label.show() toolbar.insert(toolitem, -1) toolitem.show() self.denominator = Gtk.Entry() self.denominator.set_text('') self.denominator.set_tooltip_text(_('denominator')) self.denominator.set_width_chars(3) toolitem = Gtk.ToolItem() toolitem.add(self.denominator) self.denominator.show() toolbar.insert(toolitem, -1) toolitem.show() button = ToolButton('list-add') button.set_tooltip(_('add new fraction')) button.props.sensitive = True button.props.accelerator = 'Return' button.connect('clicked', self._add_fraction_cb) toolbar.insert(button, -1) button.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(False) toolbar.insert(separator, -1) separator.show() button = ToolButton('soccerball') button.set_tooltip(_('choose a ball')) button.props.sensitive = True button.connect('clicked', self._button_palette_cb) toolbar.insert(button, -1) button.show() self._ball_palette = button.get_palette() button_grid = Gtk.Grid() row = 0 for ball in BALLDICT.keys(): if ball == 'custom': button = ToolButton('view-source') else: button = ToolButton(ball) button.connect('clicked', self._load_ball_cb, None, ball) eventbox = Gtk.EventBox() eventbox.connect('button_press_event', self._load_ball_cb, ball) label = Gtk.Label(BALLDICT[ball][0]) eventbox.add(label) label.show() button_grid.attach(button, 0, row, 1, 1) button.show() button_grid.attach(eventbox, 1, row, 1, 1) eventbox.show() row += 1 self._ball_palette.set_content(button_grid) button_grid.show() button = ToolButton('insert-picture') button.set_tooltip(_('choose a background')) button.props.sensitive = True button.connect('clicked', self._button_palette_cb) toolbar.insert(button, -1) button.show() self._bg_palette = button.get_palette() button_grid = Gtk.Grid() row = 0 for bg in BGDICT.keys(): if bg == 'custom': button = ToolButton('view-source') else: button = ToolButton(bg) button.connect('clicked', self._load_bg_cb, None, bg) eventbox = Gtk.EventBox() eventbox.connect('button_press_event', self._load_bg_cb, bg) label = Gtk.Label(BGDICT[bg][0]) eventbox.add(label) label.show() button_grid.attach(button, 0, row, 1, 1) button.show() button_grid.attach(eventbox, 1, row, 1, 1) eventbox.show() row += 1 self._bg_palette.set_content(button_grid) button_grid.show()
class ViewToolbar(Gtk.Toolbar): __gtype_name__ = 'ViewToolbar' __gsignals__ = { 'go-fullscreen': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([])), } def __init__(self): Gtk.Toolbar.__init__(self) self._view = None self._zoom_out = ToolButton('zoom-out') self._zoom_out.set_tooltip(_('Zoom out')) self._zoom_out.connect('clicked', self._zoom_out_cb) self.insert(self._zoom_out, -1) self._zoom_out.show() self._zoom_in = ToolButton('zoom-in') self._zoom_in.set_tooltip(_('Zoom in')) self._zoom_in.connect('clicked', self._zoom_in_cb) self.insert(self._zoom_in, -1) self._zoom_in.show() self._zoom_to_width = ToolButton('zoom-best-fit') self._zoom_to_width.set_tooltip(_('Zoom to width')) self._zoom_to_width.connect('clicked', self._zoom_to_width_cb) self.insert(self._zoom_to_width, -1) self._zoom_to_width.show() vbox_menu = Gtk.VBox() fit_menu = SugarMenuItem(text_label=_('Zoom to fit')) fit_menu.connect('clicked', self._zoom_to_fit_menu_item_activate_cb) vbox_menu.add(fit_menu) actual_size_menu = SugarMenuItem(text_label=_('Actual size')) actual_size_menu.connect('clicked', self._actual_size_menu_item_activate_cb) vbox_menu.add(actual_size_menu) vbox_menu.show_all() palette = self._zoom_to_width.get_palette() palette.set_content(vbox_menu) # HACK palette._content.set_border_width(1) tool_item = Gtk.ToolItem() self.insert(tool_item, -1) tool_item.show() self._zoom_spin = Gtk.SpinButton() self._zoom_spin.set_range(5.409, 400) self._zoom_spin.set_increments(1, 10) self._zoom_spin_notify_value_handler = self._zoom_spin.connect( 'notify::value', self._zoom_spin_notify_value_cb) tool_item.add(self._zoom_spin) self._zoom_spin.show() zoom_perc_label = Gtk.Label(_("%")) zoom_perc_label.show() tool_item_zoom_perc_label = Gtk.ToolItem() tool_item_zoom_perc_label.add(zoom_perc_label) self.insert(tool_item_zoom_perc_label, -1) tool_item_zoom_perc_label.show() spacer = Gtk.SeparatorToolItem() spacer.props.draw = False self.insert(spacer, -1) spacer.show() self._fullscreen = ToolButton('view-fullscreen') self._fullscreen.set_tooltip(_('Fullscreen')) self._fullscreen.connect('clicked', self._fullscreen_cb) self.insert(self._fullscreen, -1) self._fullscreen.show() self._view_notify_zoom_handler = None def set_view(self, view): self._view = view self._zoom_spin.props.value = self._view.get_zoom() self._view_notify_zoom_handler = \ self._view.connect_zoom_handler(self._view_notify_zoom_cb) self._update_zoom_buttons() def _zoom_spin_notify_value_cb(self, zoom_spin, pspec): self._view.set_zoom(zoom_spin.props.value) def _view_notify_zoom_cb(self, model, pspec): self._zoom_spin.disconnect(self._zoom_spin_notify_value_handler) try: self._zoom_spin.props.value = round(self._view.get_zoom()) finally: self._zoom_spin_notify_value_handler = self._zoom_spin.connect( 'notify::value', self._zoom_spin_notify_value_cb) def zoom_in(self): self._view.zoom_in() self._update_zoom_buttons() def _zoom_in_cb(self, button): self.zoom_in() def zoom_out(self): self._view.zoom_out() self._update_zoom_buttons() def _zoom_out_cb(self, button): self.zoom_out() def zoom_to_width(self): self._view.zoom_to_width() self._update_zoom_buttons() def _zoom_to_width_cb(self, button): self.zoom_to_width() def _update_zoom_buttons(self): self._zoom_in.props.sensitive = self._view.can_zoom_in() self._zoom_out.props.sensitive = self._view.can_zoom_out() self._zoom_to_width.props.sensitive = self._view.can_zoom_to_width() def _zoom_to_fit_menu_item_activate_cb(self, menu_item): self._view.zoom_to_best_fit() self._update_zoom_buttons() def _actual_size_menu_item_activate_cb(self, menu_item): self._view.zoom_to_actual_size() self._update_zoom_buttons() def _fullscreen_cb(self, button): self.emit('go-fullscreen')
class PrimaryToolbar(ToolbarBase): __gtype_name__ = 'PrimaryToolbar' __gsignals__ = { 'add-link': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), } def __init__(self, tabbed_view, act): ToolbarBase.__init__(self) self._activity = act self._tabbed_view = tabbed_view self._loading = False self._title = _('Untitled') toolbar = self.toolbar activity_button = ActivityToolbarButton(self._activity) toolbar.insert(activity_button, 0) self._go_home = ToolButton('go-home') self._go_home.set_tooltip(_('Home page')) self._go_home.connect('clicked', self._go_home_cb) toolbar.insert(self._go_home, -1) self._go_home.show() self.entry = WebEntry() self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'browse-dialog-cancel') self.entry.connect('icon-press', self._stop_and_reload_cb) self.entry.connect('activate', self._entry_activate_cb) entry_item = Gtk.ToolItem() entry_item.set_expand(True) entry_item.add(self.entry) self.entry.show() toolbar.insert(entry_item, -1) entry_item.show() self._back = ToolButton('go-previous-paired') self._back.set_tooltip(_('Back')) self._back.props.sensitive = False self._back.connect('clicked', self._go_back_cb) toolbar.insert(self._back, -1) self._back.show() palette = self._back.get_palette() self._back_box_menu = Gtk.VBox() self._back_box_menu.show() palette.set_content(self._back_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._forward = ToolButton('go-next-paired') self._forward.set_tooltip(_('Forward')) self._forward.props.sensitive = False self._forward.connect('clicked', self._go_forward_cb) toolbar.insert(self._forward, -1) self._forward.show() palette = self._forward.get_palette() self._forward_box_menu = Gtk.VBox() self._forward_box_menu.show() palette.set_content(self._forward_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._link_add = ToolButton('emblem-favorite') self._link_add.set_tooltip(_('Bookmark')) self._link_add.connect('clicked', self._link_add_clicked_cb) toolbar.insert(self._link_add, -1) self._link_add.show() stop_button = StopButton(self._activity) toolbar.insert(stop_button, -1) self._progress_listener = None self._browser = None self._loading_changed_hid = None self._progress_changed_hid = None self._session_history_changed_hid = None self._title_changed_hid = None self._uri_changed_hid = None if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) tabbed_view.connect_after('switch-page', self.__switch_page_cb) def __switch_page_cb(self, tabbed_view, page, page_num): if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) def _connect_to_browser(self, browser): if self._browser is not None: self._browser.disconnect(self._title_changed_hid) self._browser.disconnect(self._uri_changed_hid) self._browser.disconnect(self._progress_changed_hid) self._browser.disconnect(self._loading_changed_hid) self._browser = browser if self._browser.props.title: self._set_title(self._browser.props.title) else: self._set_title(_('Untitled')) self._set_address(self._browser.props.uri) self._set_progress(self._browser.props.progress) self._set_status(self._browser.props.load_status) is_webkit_browser = isinstance(self._browser, Browser) self.entry.props.editable = is_webkit_browser self._title_changed_hid = self._browser.connect( 'notify::title', self._title_changed_cb) self._uri_changed_hid = self._browser.connect('notify::uri', self.__uri_changed_cb) self._progress_changed_hid = self._browser.connect( 'notify::progress', self.__progress_changed_cb) self._loading_changed_hid = self._browser.connect( 'notify::load-status', self.__loading_changed_cb) self._update_navigation_buttons() def __loading_changed_cb(self, widget, param): status = widget.get_load_status() if status == WebKit.LoadStatus.FAILED: self.entry._set_title(self._title) elif WebKit.LoadStatus.PROVISIONAL <= status \ < WebKit.LoadStatus.FINISHED: self.entry._set_title(_('Loading...')) elif status == WebKit.LoadStatus.FINISHED: if widget.props.title == None: self.entry._set_title(_('Untitled')) self._title = _('Untitled') self._set_status(widget.get_load_status()) def __progress_changed_cb(self, widget, param): self._set_progress(widget.get_progress()) def _set_status(self, status): self._set_loading(status < WebKit.LoadStatus.FINISHED) def _set_progress(self, progress): if progress == 1.0: self.entry.set_progress_fraction(0.0) else: self.entry.set_progress_fraction(progress) def _set_address(self, uri): if uri is None: self.entry.props.address = '' else: self.entry.props.address = uri def _set_title(self, title): self.entry.props.title = title self._title = title def _show_stop_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'browse-dialog-cancel') def _show_reload_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'browse-view-refresh') def _update_navigation_buttons(self): can_go_back = self._browser.can_go_back() self._back.props.sensitive = can_go_back can_go_forward = self._browser.can_go_forward() self._forward.props.sensitive = can_go_forward is_webkit_browser = isinstance(self._browser, Browser) self._link_add.props.sensitive = is_webkit_browser self._go_home.props.sensitive = is_webkit_browser if is_webkit_browser: self._reload_session_history() def _entry_activate_cb(self, entry): url = entry.props.text effective_url = self._tabbed_view.normalize_or_autosearch_url(url) self._browser.load_uri(effective_url) self._browser.grab_focus() def _go_home_cb(self, button): self.emit('go-home') def _go_back_cb(self, button): self._browser.go_back() def _go_forward_cb(self, button): self._browser.go_forward() def _title_changed_cb(self, widget, param): self._set_title(widget.get_title()) def __uri_changed_cb(self, widget, param): self._set_address(widget.get_uri()) self._update_navigation_buttons() filepicker.cleanup_temp_files() def _stop_and_reload_cb(self, entry, icon_pos, button): if self._loading: self._browser.stop_loading() else: self._browser.reload() def _set_loading(self, loading): self._loading = loading if self._loading: self._show_stop_icon() else: self._show_reload_icon() def _reload_session_history(self): back_forward_list = self._browser.get_back_forward_list() item_index = 0 # The index of the history item # Clear menus in palettes: for box_menu in (self._back_box_menu, self._forward_box_menu): for menu_item in box_menu.get_children(): box_menu.remove(menu_item) def create_menu_item(history_item, item_index): """Create a MenuItem for the back or forward palettes.""" title = history_item.get_title() if not isinstance(title, unicode): title = unicode(title, 'utf-8') # This is a fix until the Sugar MenuItem is fixed: menu_item = SugarMenuItem(text_label=title) menu_item.connect('clicked', self._history_item_activated_cb, item_index) return menu_item back_list = back_forward_list.get_back_list_with_limit( _MAX_HISTORY_ENTRIES) back_list.reverse() for item in back_list: menu_item = create_menu_item(item, item_index) self._back_box_menu.pack_end(menu_item, False, False, 0) menu_item.show() item_index += 1 # Increment the item index to count the current page: item_index += 1 forward_list = back_forward_list.get_forward_list_with_limit( _MAX_HISTORY_ENTRIES) forward_list.reverse() for item in forward_list: menu_item = create_menu_item(item, item_index) self._forward_box_menu.pack_start(menu_item, False, False, 0) menu_item.show() item_index += 1 def _history_item_activated_cb(self, menu_item, index): self._browser.set_history_index(index) def _link_add_clicked_cb(self, button): self.emit('add-link')
def __init__(self, handle): activity.Activity.__init__(self, handle) self.set_title('FotoToon') self._max_participants = 1 self.page = None toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) activity_toolbar = activity_button.page toolbar_box.toolbar.insert(activity_button, 0) edit_toolbar_btn = ToolbarButton() edit_toolbar = Gtk.Toolbar() edit_toolbar_btn.props.page = edit_toolbar edit_toolbar_btn.props.icon_name = 'toolbar-edit' edit_toolbar_btn.label = _('Edit') toolbar_box.toolbar.insert(edit_toolbar_btn, -1) view_toolbar_btn = ToolbarButton() view_toolbar = Gtk.Toolbar() view_toolbar_btn.props.page = view_toolbar view_toolbar_btn.props.icon_name = 'toolbar-view' view_toolbar_btn.label = _('View') toolbar_box.toolbar.insert(view_toolbar_btn, -1) slideview_btn = ToggleToolButton('slideshow') slideview_btn.set_tooltip(_('Slideshow')) slideview_btn.set_active(False) slideview_btn.connect('clicked', self._switch_view_mode, False) view_toolbar.insert(slideview_btn, -1) slideview_btn.show() slideview_timings_btn = ToggleToolButton('slideshow-stopwatch') slideview_timings_btn.set_tooltip(_('Slideshow with Timings')) slideview_timings_btn.set_active(False) slideview_timings_btn.connect('clicked', self._switch_view_mode, True) view_toolbar.insert(slideview_timings_btn, -1) slideview_timings_btn.show() time_button = ToolButton('stopwatch') time_button.set_tooltip(_('Set Image Duration in Slideshow (Seconds)')) view_toolbar.insert(time_button, -1) time_button.show() self._time_spin = Gtk.SpinButton.new_with_range(MIN_TIME, MAX_TIME, 1) self._time_spin.connect('value-changed', self.__time_spin_changed_cb) self._time_spin.props.value = DEFAULT_TIME self._time_spin.props.update_policy = \ Gtk.SpinButtonUpdatePolicy.IF_VALID palette = time_button.get_palette() palette.connect('popup', self.__time_button_popup_cb) time_button.connect( 'clicked', lambda *args: palette.popup(immediate=True, state=Palette.SECONDARY)) alignment = Gtk.Alignment() alignment.set_padding(style.DEFAULT_PADDING, style.DEFAULT_PADDING, style.DEFAULT_PADDING, style.DEFAULT_PADDING) alignment.add(self._time_spin) self._time_spin.show() palette.set_content(alignment) alignment.show() fullscreen_btn = ToolButton('view-fullscreen') fullscreen_btn.set_tooltip(_('Fullscreen')) fullscreen_btn.props.accelerator = '<Alt>Return' fullscreen_btn.connect('clicked', lambda w: self.fullscreen()) view_toolbar.insert(fullscreen_btn, -1) fullscreen_btn.show() self.set_toolbar_box(toolbar_box) toolbar = toolbar_box.toolbar self.page = Page() self.globes_manager = GlobesManager(toolbar, edit_toolbar, self) # fonts self._text_button = ToolbarButton() self._text_button.props.page = TextToolbar(self.page) self._text_button.props.icon_name = 'format-text-size' self._text_button.props.label = _('Text') self._toolbar_box.toolbar.insert(self._text_button, -1) reorder_img_btn = ToolButton('thumbs-view') reorder_img_btn.set_icon_name('thumbs-view') reorder_img_btn.set_tooltip(_('Change image order')) reorder_img_btn.connect('clicked', self.__image_order_cb) edit_toolbar.insert(reorder_img_btn, -1) reorder_img_btn.show() bgchange = ToolButton(icon_name='contract-coordinates') bgchange.set_tooltip(_('Edit background image')) bgchange.connect('clicked', self.__bgchange_clicked_cb) edit_toolbar.insert(bgchange, -1) bgchange.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) stop = StopButton(self) toolbar_box.toolbar.insert(stop, -1) toolbar_box.show_all() # add export button separator_2 = Gtk.SeparatorToolItem() separator_2.show() activity_toolbar.insert(separator_2, -1) self.bt_save_as_image = ToolButton() self.bt_save_as_image.props.icon_name = 'save-as-image' self.bt_save_as_image.connect('clicked', self.write_image) self.bt_save_as_image.set_tooltip(_('Save as Image')) activity_toolbar.insert(self.bt_save_as_image, -1) self.bt_save_as_image.show() save_as_pdf = ToolButton() save_as_pdf.props.icon_name = 'save-as-pdf' save_as_pdf.connect('clicked', self._save_as_pdf) save_as_pdf.set_tooltip(_('Save as a Book (PDF)')) activity_toolbar.insert(save_as_pdf, -1) save_as_pdf.show() save_as_ogg = ToolButton() save_as_ogg.props.icon_name = 'save-as-ogg' save_as_ogg.connect('clicked', self.__save_as_ogg_cb) save_as_ogg.set_tooltip(_('Save as a Movie (OGG)')) activity_toolbar.insert(save_as_ogg, -1) Gst.init(None) if Gst.version_string() != 'GStreamer 1.0.10': save_as_ogg.show() activity_button.page.title.connect("focus-in-event", self.on_title) scrolled = Gtk.ScrolledWindow() # scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS) scrolled.add_with_viewport(self.page) scrolled.set_kinetic_scrolling(False) scrolled.show_all() self._slideview = SlideView(self) self._slideview.show_all() self._notebook = Gtk.Notebook() self._notebook.set_show_tabs(False) self._notebook.append_page(scrolled, None) self._notebook.append_page(self._slideview, None) self._notebook.show_all() if self._jobject.file_path is None or self._jobject.file_path == '': empty_widget = EmptyWidget() empty_widget.connect('choose-image', self.__add_image) self.set_canvas(empty_widget) else: self.set_canvas(self._notebook) self.show() self.metadata['mime_type'] = 'application/x-fototoon-activity' self.page.empty_page = handle.object_id is None self._key_press_signal_id = None
def make_toolbar(self): def make_separator(expand=True): separator = Gtk.SeparatorToolItem() separator.props.draw = not expand separator.set_expand(expand) return separator toolbarbox = ToolbarBox() self.set_toolbar_box(toolbarbox) toolbar = toolbarbox.toolbar toolbar.insert(ActivityToolbarButton(self), -1) toolbar.insert(make_separator(False), -1) self.restart_button = ToolButton(icon_name="system-restart") self.restart_button.set_tooltip(_("Restart")) self.restart_button.props.accelerator = '<Ctrl>N' self.restart_button.connect("clicked", self._restart_cb) toolbar.insert(self.restart_button, -1) self.ok_button = ToolButton(icon_name="dialog-ok") self.ok_button.set_tooltip(_("Ok")) self.ok_button.set_sensitive(False) self.ok_button.props.accelerator = "Return" self.ok_button.connect("clicked", self._ok_cb) toolbar.insert(self.ok_button, -1) toolbar.insert(make_separator(False), -1) button = ToolButton(icon_name="emblem-favorite") button.set_tooltip(_("Difficulty")) toolbar.insert(button, -1) palette = button.get_palette() palette_box = Gtk.VBox() palette.set_content(palette_box) self.easy_button = Gtk.RadioButton(_("Easy")) palette_box.pack_start(self.easy_button, False, False, 0) self.medium_button = Gtk.RadioButton(_("Medium"), group=self.easy_button) palette_box.pack_start(self.medium_button, False, False, 0) self.advanced_button = Gtk.RadioButton(_("Advanced"), group=self.easy_button) palette_box.pack_start(self.advanced_button, False, False, 0) self.expert_button = Gtk.RadioButton(_("Expert"), group=self.easy_button) palette_box.pack_start(self.expert_button, False, False, 0) palette_box.show_all() item = Gtk.ToolItem() toolbar.insert(item, -1) self.label = Gtk.Label() self.label.modify_font(Pango.FontDescription("Bold")) item.add(self.label) toolbar.insert(make_separator(True), -1) helpbutton = HelpButton() helpbutton.add_section(_("Instructions:")) helpbutton.add_paragraph(_("Place colors to the last played row."), image="instructions1.png") helpbutton.add_paragraph( _("When you complete a row, click on 'Ok button'."), image="instructions2.png") helpbutton.add_paragraph( _("Next to the row will appear black and white circles."), image="instructions3.png") helpbutton.add_paragraph( _("A black circle means you matched a peg and you placed it correctly." )) helpbutton.add_paragraph( _("A white circle means you matched a peg and you wrong placed it." )) helpbutton.add_paragraph( _("The goal is match all pegs in the correct place.")) toolbar.insert(helpbutton, -1) stop_button = StopButton(self) toolbar.insert(stop_button, -1) toolbar.show_all()
class PrimaryToolbar(ToolbarBase): __gtype_name__ = 'PrimaryToolbar' __gsignals__ = { 'add-link': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'set-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'reset-home': (GObject.SignalFlags.RUN_FIRST, None, ([])), 'go-library': (GObject.SignalFlags.RUN_FIRST, None, ([])), } def __init__(self, tabbed_view, act): ToolbarBase.__init__(self) self._url_toolbar = UrlToolbar() self._activity = act self._tabbed_view = self._canvas = tabbed_view self._loading = False toolbar = self.toolbar activity_button = ActivityToolbarButton(self._activity) toolbar.insert(activity_button, 0) separator = Gtk.SeparatorToolItem() save_as_pdf = ToolButton('save-as-pdf') save_as_pdf.set_tooltip(_('Save page as pdf')) save_as_pdf.connect('clicked', self.save_as_pdf) activity_button.props.page.insert(separator, -1) activity_button.props.page.insert(save_as_pdf, -1) separator.show() save_as_pdf.show() self._go_home = ToolButton('go-home') self._go_home.set_tooltip(_('Home page')) self._go_home.connect('clicked', self._go_home_cb) # add a menu to save the home page menu_box = PaletteMenuBox() self._go_home.props.palette.set_content(menu_box) menu_item = PaletteMenuItem() menu_item.set_label(_('Select as initial page')) menu_item.connect('activate', self._set_home_cb) menu_box.append_item(menu_item) self._reset_home_menu = PaletteMenuItem() self._reset_home_menu.set_label(_('Reset initial page')) self._reset_home_menu.connect('activate', self._reset_home_cb) menu_box.append_item(self._reset_home_menu) if os.path.isfile(LIBRARY_PATH): library_menu = PaletteMenuItem() library_menu.set_label(_('Library')) library_menu.connect('activate', self._go_library_cb) menu_box.append_item(library_menu) menu_box.show_all() # verify if the home page is configured client = GConf.Client.get_default() self._reset_home_menu.set_visible( client.get_string(HOME_PAGE_GCONF_KEY) is not None) toolbar.insert(self._go_home, -1) self._go_home.show() self.entry = WebEntry() self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-stop') self.entry.connect('icon-press', self._stop_and_reload_cb) self.entry.connect('activate', self._entry_activate_cb) self.entry.connect('focus-in-event', self.__focus_in_event_cb) self.entry.connect('focus-out-event', self.__focus_out_event_cb) self.entry.connect('key-press-event', self.__key_press_event_cb) self.entry.connect('changed', self.__changed_cb) self._entry_item = Gtk.ToolItem() self._entry_item.set_expand(True) self._entry_item.add(self.entry) self.entry.show() toolbar.insert(self._entry_item, -1) self._entry_item.show() self._back = ToolButton('go-previous-paired') self._back.set_tooltip(_('Back')) self._back.props.sensitive = False self._back.connect('clicked', self._go_back_cb) toolbar.insert(self._back, -1) self._back.show() palette = self._back.get_palette() self._back_box_menu = Gtk.VBox() self._back_box_menu.show() palette.set_content(self._back_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) self._forward = ToolButton('go-next-paired') self._forward.set_tooltip(_('Forward')) self._forward.props.sensitive = False self._forward.connect('clicked', self._go_forward_cb) toolbar.insert(self._forward, -1) self._forward.show() palette = self._forward.get_palette() self._forward_box_menu = Gtk.VBox() self._forward_box_menu.show() palette.set_content(self._forward_box_menu) # FIXME, this is a hack, should be done in the theme: palette._content.set_border_width(1) # Downloads ProgressIcon self._download_icon = ProgressToolButton('emblem-downloads', style.STANDARD_ICON_SIZE, 'vertical') self._download_icon.set_tooltip(_('Downloads')) self._download_icon.props.sensitive = False down_id = GObject.timeout_add(500, self.__download_running_cb) toolbar.insert(self._download_icon, -1) self._download_icon.show() self._link_add = ToolButton('emblem-favorite') self._link_add.set_tooltip(_('Bookmark')) self._link_add.connect('clicked', self._link_add_clicked_cb) toolbar.insert(self._link_add, -1) self._link_add.show() self._toolbar_separator = Gtk.SeparatorToolItem() self._toolbar_separator.props.draw = False self._toolbar_separator.set_expand(True) # Adds an options-toolbar button to the main-toolbar self._options_toolbar = OptionsToolbar(self._activity) self._options_toolbar_button = ToolbarButton( page=self._options_toolbar, icon_name='options') toolbar.insert(self._options_toolbar_button, -1) stop_button = StopButton(self._activity) toolbar.insert(stop_button, -1) self._progress_listener = None self._browser = None self._loading_changed_hid = None self._progress_changed_hid = None self._session_history_changed_hid = None self._uri_changed_hid = None self._security_status_changed_hid = None if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) tabbed_view.connect_after('switch-page', self.__switch_page_cb) tabbed_view.connect_after('page-added', self.__page_added_cb) Gdk.Screen.get_default().connect('size-changed', self.__screen_size_changed_cb) self._configure_toolbar() def __download_running_cb(self): ''' Updates the downloadIcon tooltip message and progress value. ''' progress = downloadmanager.overall_downloads_progress() self._download_icon.update(progress) if progress > 0.0: self._download_icon.set_tooltip( _("Downloading.. {}%".format(int(progress * 100)))) else: self._download_icon.set_tooltip(_("No active downloads")) return True def __key_press_event_cb(self, entry, event): self._tabbed_view.current_browser.loading_uri = entry.props.text def __switch_page_cb(self, tabbed_view, page, page_num): if tabbed_view.get_n_pages(): self._connect_to_browser(tabbed_view.props.current_browser) def __page_added_cb(self, notebook, child, pagenum): self.entry._search_popdown() def _configure_toolbar(self, screen=None): # Adapt the toolbars for portrait or landscape mode. if screen is None: screen = Gdk.Screen.get_default() if screen.get_width() < screen.get_height(): if self._entry_item in self._url_toolbar.toolbar.get_children(): return self.toolbar.remove(self._entry_item) self._url_toolbar.toolbar.insert(self._entry_item, -1) separator_pos = len(self.toolbar.get_children()) - 1 self.toolbar.insert(self._toolbar_separator, separator_pos) self._toolbar_separator.show() self.pack_end(self._url_toolbar, True, True, 0) self._url_toolbar.show() else: if self._entry_item in self.toolbar.get_children(): return self.toolbar.remove(self._toolbar_separator) position = len(self.toolbar.get_children()) - 4 self._url_toolbar.toolbar.remove(self._entry_item) self.toolbar.insert(self._entry_item, position) self._toolbar_separator.hide() self.remove(self._url_toolbar) def __screen_size_changed_cb(self, screen): self._configure_toolbar(screen) def _connect_to_browser(self, browser): if self._browser is not None: self._browser.disconnect(self._uri_changed_hid) self._browser.disconnect(self._progress_changed_hid) self._browser.disconnect(self._loading_changed_hid) self._browser.disconnect(self._security_status_changed_hid) self._browser = browser if not isinstance(self._browser, DummyBrowser): address = self._browser.props.uri or self._browser.loading_uri else: address = self._browser.props.uri self._set_address(address) self._set_progress(self._browser.props.progress) self._set_status(self._browser.props.load_status) self._set_security_status(self._browser.security_status) is_webkit_browser = isinstance(self._browser, Browser) self.entry.props.editable = is_webkit_browser self._uri_changed_hid = self._browser.connect('notify::uri', self.__uri_changed_cb) self._progress_changed_hid = self._browser.connect( 'notify::progress', self.__progress_changed_cb) self._loading_changed_hid = self._browser.connect( 'notify::load-status', self.__loading_changed_cb) self._security_status_changed_hid = self._browser.connect( 'security-status-changed', self.__security_status_changed_cb) self._update_navigation_buttons() def __loading_changed_cb(self, widget, param): self._set_status(widget.get_load_status()) def __security_status_changed_cb(self, widget): self._set_security_status(widget.security_status) def __progress_changed_cb(self, widget, param): self._set_progress(widget.get_progress()) def _set_status(self, status): self._set_loading(status < WebKit.LoadStatus.FINISHED) def _set_security_status(self, security_status): # Display security status as a lock icon in the left side of # the URL entry. if security_status is None: self.entry.set_icon_from_pixbuf(iconentry.ICON_ENTRY_PRIMARY, None) elif security_status == Browser.SECURITY_STATUS_SECURE: self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, 'channel-secure-symbolic') elif security_status == Browser.SECURITY_STATUS_INSECURE: self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, 'channel-insecure-symbolic') def _set_progress(self, progress): if progress == 1.0: self.entry.set_progress_fraction(0.0) else: self.entry.set_progress_fraction(progress) def _set_address(self, uri): if uri is None: self.entry.props.address = '' else: self.entry.props.address = uri def __changed_cb(self, iconentry): # The WebEntry can be changed when we click on a link, then we # have to show the clear icon only if is the user who has # changed the entry if self.entry.has_focus(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_in_event_cb(self, entry, event): if not self._tabbed_view.is_current_page_pdf(): if not self.entry.props.text: self._show_no_icon() else: self._show_clear_icon() def __focus_out_event_cb(self, entry, event): if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self._show_reload_icon() def _show_no_icon(self): self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY) def _show_stop_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-stop') def _show_reload_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-refresh') def _show_clear_icon(self): self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, 'entry-cancel') def _update_navigation_buttons(self): can_go_back = self._browser.can_go_back() self._back.props.sensitive = can_go_back can_go_forward = self._browser.can_go_forward() self._forward.props.sensitive = can_go_forward is_webkit_browser = isinstance(self._browser, Browser) self._link_add.props.sensitive = is_webkit_browser self._go_home.props.sensitive = is_webkit_browser if is_webkit_browser: self._reload_session_history() def _entry_activate_cb(self, entry): url = entry.props.text effective_url = self._tabbed_view.normalize_or_autosearch_url(url) self._browser.load_uri(effective_url) self._browser.loading_uri = effective_url self.entry.props.address = effective_url self._browser.grab_focus() def _go_home_cb(self, button): self.emit('go-home') def _go_library_cb(self, button): self.emit('go-library') def _set_home_cb(self, button): self._reset_home_menu.set_visible(True) self.emit('set-home') def _reset_home_cb(self, button): self._reset_home_menu.set_visible(False) self.emit('reset-home') def _go_back_cb(self, button): self._browser.go_back() def _go_forward_cb(self, button): self._browser.go_forward() def __uri_changed_cb(self, widget, param): self._set_address(widget.get_uri()) self._update_navigation_buttons() filepicker.cleanup_temp_files() def _stop_and_reload_cb(self, entry, icon_pos, button): if entry.has_focus() and \ not self._tabbed_view.is_current_page_pdf(): entry.set_text('') else: if self._loading: self._browser.stop_loading() else: self._browser.reload() def _set_loading(self, loading): self._loading = loading if self._loading: self._show_stop_icon() else: if not self._tabbed_view.is_current_page_pdf(): self.set_sensitive(True) self._show_reload_icon() else: self.set_sensitive(False) self._show_no_icon() def _reload_session_history(self): back_forward_list = self._browser.get_back_forward_list() item_index = 0 # The index of the history item # Clear menus in palettes: for box_menu in (self._back_box_menu, self._forward_box_menu): for menu_item in box_menu.get_children(): box_menu.remove(menu_item) def create_menu_item(history_item, item_index): """Create a MenuItem for the back or forward palettes.""" title = history_item.get_title() if not isinstance(title, unicode): title = unicode(title, 'utf-8') # This is a fix until the Sugar MenuItem is fixed: menu_item = PaletteMenuItem(text_label=title) menu_item.connect('activate', self._history_item_activated_cb, item_index) return menu_item back_list = back_forward_list.get_back_list_with_limit( _MAX_HISTORY_ENTRIES) back_list.reverse() for item in back_list: menu_item = create_menu_item(item, item_index) self._back_box_menu.pack_end(menu_item, False, False, 0) menu_item.show() item_index += 1 # Increment the item index to count the current page: item_index += 1 forward_list = back_forward_list.get_forward_list_with_limit( _MAX_HISTORY_ENTRIES) forward_list.reverse() for item in forward_list: menu_item = create_menu_item(item, item_index) self._forward_box_menu.pack_start(menu_item, False, False, 0) menu_item.show() item_index += 1 def _history_item_activated_cb(self, menu_item, index): self._back.get_palette().popdown(immediate=True) self._forward.get_palette().popdown(immediate=True) self._browser.set_history_index(index) def _link_add_clicked_cb(self, button): self.emit('add-link') def save_as_pdf(self, widget): tmp_dir = os.path.join(self._activity.get_activity_root(), 'tmp') fd, file_path = tempfile.mkstemp(dir=tmp_dir) os.close(fd) page = self._canvas.get_current_page() webview = self._canvas.get_children()[page].get_children()[0] operation = Gtk.PrintOperation.new() operation.set_export_filename(file_path) webview.get_main_frame().print_full(operation, Gtk.PrintOperationAction.EXPORT) client = GConf.Client.get_default() jobject = datastore.create() color = client.get_string('/desktop/sugar/user/color') try: jobject.metadata['title'] = _('Browse activity as PDF') jobject.metadata['icon-color'] = color jobject.metadata['mime_type'] = 'application/pdf' jobject.file_path = file_path datastore.write(jobject) finally: self.__pdf_alert(jobject.object_id) jobject.destroy() del jobject def __pdf_alert(self, object_id): alert = Alert() alert.props.title = _('Page saved') alert.props.msg = _('The page has been saved as PDF to journal') alert.add_button(Gtk.ResponseType.APPLY, _('Show in Journal'), Icon(icon_name='zoom-activity')) alert.add_button(Gtk.ResponseType.OK, _('Ok'), Icon(icon_name='dialog-ok')) # Remove other alerts for alert in self._activity._alerts: self._activity.remove_alert(alert) self._activity.add_alert(alert) alert.connect('response', self.__pdf_response_alert, object_id) alert.show_all() def __pdf_response_alert(self, alert, response_id, object_id): if response_id is Gtk.ResponseType.APPLY: activity.show_object_in_journal(object_id) self._activity.remove_alert(alert)
class ReadToolbar(Gtk.Toolbar): __gtype_name__ = 'ReadToolbar' def __init__(self): GObject.GObject.__init__(self) self.back = ToolButton('go-previous') self.back.set_tooltip(_('Back')) self.back.props.sensitive = False palette = self.back.get_palette() self.prev_page = MenuItem(text_label=_("Previous page")) palette.menu.append(self.prev_page) self.prev_page.show_all() self.back.connect('clicked', self.go_back_cb) self.prev_page.connect('activate', self.go_back_cb) self.insert(self.back, -1) self.back.show() self.forward = ToolButton('go-next') self.forward.set_tooltip(_('Forward')) self.forward.props.sensitive = False palette = self.forward.get_palette() self.next_page = MenuItem(text_label=_("Next page")) palette.menu.append(self.next_page) self.next_page.show_all() self.forward.connect('clicked', self.go_forward_cb) self.next_page.connect('activate', self.go_forward_cb) self.insert(self.forward, -1) self.forward.show() num_page_item = Gtk.ToolItem() self._num_page_entry = Gtk.Entry() self._num_page_entry.set_text('0') self._num_page_entry.set_alignment(1) self._num_page_entry.connect('insert-text', self._num_page_entry_insert_text_cb) self._num_page_entry.connect('activate', self._num_page_entry_activate_cb) self._num_page_entry.set_width_chars(4) num_page_item.add(self._num_page_entry) self._num_page_entry.show() self.insert(num_page_item, -1) num_page_item.show() total_page_item = Gtk.ToolItem() self._total_page_label = Gtk.Label() self._total_page_label.set_text(' / 0') total_page_item.add(self._total_page_label) self._total_page_label.show() self.insert(total_page_item, -1) total_page_item.show() def _num_page_entry_insert_text_cb(self, entry, text, length, position): if not re.match('[0-9]', text): entry.emit_stop_by_name('insert-text') return True return False def _num_page_entry_activate_cb(self, entry): if entry.props.text: page = int(entry.props.text) - 1 else: page = 0 if page >= self.total_pages: page = self.total_pages - 1 elif page < 0: page = 0 self.current_page = page self.activity.set_current_page(page) self.activity.show_page(page) entry.props.text = str(page + 1) self._update_nav_buttons() def go_back_cb(self, button): self.activity.previous_page() def go_forward_cb(self, button): self.activity.next_page() def _update_nav_buttons(self): current_page = self.current_page self.back.props.sensitive = current_page > 0 self.forward.props.sensitive = \ current_page < self.total_pages - 1 self._num_page_entry.props.text = str(current_page + 1) self._total_page_label.props.label = \ ' / ' + str(self.total_pages) def set_total_pages(self, pages): self.total_pages = pages def set_current_page(self, page): self.current_page = page self._update_nav_buttons() def set_activity(self, activity): self.activity = activity def setToggleButtonState(self, button, b, id): button.handler_block(id) button.set_active(b) button.handler_unblock(id)