class TitleBox(Gtk.Toolbar): def __init__(self, title=None): Gtk.Toolbar.__init__(self) self.journal_button = ToolButton() icon = Icon(icon_name='activity-journal', xo_color=profile.get_color()) self.journal_button.set_icon_widget(icon) self.journal_button.set_tooltip(_('Select from the Journal')) self.insert(self.journal_button, -1) self.journal_button.show_all() label = Gtk.Label() if title is None: title = _('Choose an image') label.set_markup('<b>%s</b>' % title) label.set_alignment(0, 0.5) label.set_margin_left(10) self._add_widget(label, expand=True) self.close_button = ToolButton(icon_name='dialog-cancel') self.close_button.set_tooltip(_('Close')) self.insert(self.close_button, -1) self.close_button.show() def _add_widget(self, widget, expand=False): tool_item = Gtk.ToolItem() tool_item.set_expand(expand) tool_item.add(widget) widget.show() self.insert(tool_item, -1) tool_item.show()
def __init__(self, handle): "The entry point to the Activity" activity.Activity.__init__(self, handle, False) self.max_participants = 1 self._sequence = 0 self.selected_book = None self.queryresults = None self._getter = None self.show_images = True self.languages = {} self._lang_code_handler = languagenames.LanguageNames() self.catalogs_configuration = {} self.catalog_history = [] if os.path.exists('/etc/get-books.cfg'): self._read_configuration('/etc/get-books.cfg') else: self._read_configuration() toolbar_box = ToolbarBox() activity_button = ToolButton() color = profile.get_color() bundle = ActivityBundle(activity.get_bundle_path()) icon = Icon(file=bundle.get_icon(), xo_color=color) activity_button.set_icon_widget(icon) activity_button.show() toolbar_box.toolbar.insert(activity_button, 0) self._add_search_controls(toolbar_box.toolbar) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) toolbar_box.toolbar.insert(StopButton(self), -1) self.set_toolbar_box(toolbar_box) toolbar_box.show_all() self._books_toolbar = toolbar_box.toolbar self._create_controls() self.using_powerd = os.access(POWERD_INHIBIT_DIR, os.W_OK) self.__book_downloader = self.__image_downloader = None
def __init__(self, handle): "The entry point to the Activity" activity.Activity.__init__(self, handle, False) self.max_participants = 1 self._sequence = 0 self.selected_book = None self.queryresults = None self._getter = None self.show_images = True self.languages = {} self._lang_code_handler = languagenames.LanguageNames() self.catalogs_configuration = {} self.catalog_history = [] if os.path.exists('/etc/get-books.cfg'): self._read_configuration('/etc/get-books.cfg') else: self._read_configuration() toolbar_box = ToolbarBox() activity_button = ToolButton() color = profile.get_color() bundle = ActivityBundle(activity.get_bundle_path()) icon = Icon(file=bundle.get_icon(), xo_color=color) activity_button.set_icon_widget(icon) activity_button.show() toolbar_box.toolbar.insert(activity_button, 0) self._add_search_controls(toolbar_box.toolbar) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) toolbar_box.toolbar.insert(StopButton(self), -1) self.set_toolbar_box(toolbar_box) toolbar_box.show_all() self._books_toolbar = toolbar_box.toolbar self._create_controls() self.using_powerd = os.access(POWERD_INHIBIT_DIR, os.W_OK) self.__book_downloader = self.__image_downloader = None
def make_toolbarbox(self): def make_separator(expand=False): separator = Gtk.SeparatorToolItem() if expand: separator.props.draw = False separator.set_expand(True) return separator toolbar_box = ToolbarBox() activity_button = ToolButton() self.button_new = ToolButton('new-game') self.button_save = ToolButton(Gtk.STOCK_SAVE) self.button_open = ToolButton(Gtk.STOCK_OPEN) self.button_advice = ToolButton(Gtk.STOCK_ADD) stop_button = ToolButton('activity-stop') self.button_new.connect('clicked', self.new_game) self.button_save.connect('clicked', self.save_game) self.button_open.connect('clicked', self.open_game) self.button_advice.connect('clicked', self.new_advice) stop_button.connect('clicked', self._exit) activity_button.set_icon_widget(ActivityIcon(None)) activity_button.set_tooltip(self.get_title()) self.button_new.set_tooltip(_('New game')) self.button_new.props.accelerator = '<Ctrl>N' self.button_save.set_tooltip(_('Save game')) self.button_save.props.accelerator = '<Ctrl>S' self.button_open.set_tooltip(_('Open game')) self.button_open.props.accelerator = '<Ctrl>O' self.button_advice.set_tooltip(_('New hint\nYou have %d hints.' % (5))) self.button_advice.props.accelerator = '<Ctrl>A' self.button_advice.set_sensitive(False) stop_button.props.accelerator = '<Ctrl>Q' toolbar_box.toolbar.insert(activity_button, -1) toolbar_box.toolbar.insert(make_separator(), -1) toolbar_box.toolbar.insert(self.button_new, -1) toolbar_box.toolbar.insert(self.button_save, -1) toolbar_box.toolbar.insert(self.button_open, -1) toolbar_box.toolbar.insert(make_separator(), -1) toolbar_box.toolbar.insert(self.button_advice, -1) toolbar_box.toolbar.insert(make_separator(True), -1) toolbar_box.toolbar.insert(stop_button, -1) return toolbar_box
def make_toolbar(self): def make_separator(expand=False, size=0): separator = Gtk.SeparatorToolItem() separator.set_size_request(size, -1) if expand: separator.set_expand(True) if expand or size: separator.props.draw = False return separator toolbar_box = ToolbarBox() toolbar = toolbar_box.toolbar activity_button = ToolButton() button_copy = ToolButton(Gtk.STOCK_COPY) button_cut = ToolButton('cut') button_remove = ToolButton(Gtk.STOCK_REMOVE) stop_button = ToolButton('activity-stop') activity_button.set_icon_widget(ActivityIcon(None)) button_copy.set_tooltip('Copy the text.') button_cut.set_tooltip('Cut the text.') button_remove.set_tooltip('Remove all the text.') stop_button.connect('clicked', lambda w: self.close()) stop_button.props.accelerator = '<Ctrl>Q' button_copy.connect('clicked', self.copy_text) button_cut.connect('clicked', self.cut_text) button_remove.connect('clicked', self.remove_text) toolbar.insert(activity_button, -1) toolbar.insert(make_separator(size=30), -1) toolbar.insert(button_copy, -1) toolbar.insert(button_cut, -1) toolbar.insert(button_remove, -1) toolbar.insert(make_separator(expand=True), -1) toolbar.insert(stop_button, -1) self.set_toolbar_box(toolbar_box)
class GameToolbar(Gtk.Toolbar): __gtype_name__ = 'GameToolbar' __gsignals__ = { 'game-restart': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, []), 'ai-activated': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, []), 'ai-deactivated': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, []), 'game-board-size': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, [GObject.TYPE_INT]), } def __init__(self, activity): Gtk.Toolbar.__init__(self) self.activity = activity # Reset Button restart_icon = join(dirname(__file__), 'images', 'gtk-refresh.svg') restart_image = Gtk.Image() restart_image.set_from_file(restart_icon) self._restart_button = ToolButton() self._restart_button.set_icon_widget(restart_image) self._restart_button.connect('clicked', self._game_restart_cb) self._restart_button.set_tooltip(_('Restart Game')) self.insert(self._restart_button, -1) self._restart_button.show() # Separator separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.insert(separator, -1) self._add_widget(Gtk.Label(_('Board size') + ': ')) # Change size combobox self._size_combo = ToolComboBox() self._sizes = ['19 X 19', '13 X 13', '9 X 9'] for i, f in enumerate(self._sizes): self._size_combo.combo.append_item(i, f) self._size_combo.combo.connect('changed', self._game_size_cb) self._add_widget(self._size_combo) self._size_combo.combo.set_active(0) # Separator separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.insert(separator, -1) # Artificial Intelligence Button self._ai_button = Gtk.ToggleToolButton() if search_for_gnugo(): self._ai_button.connect('toggled', self._ai_toggled_cb) self._ai_button.set_label(_('Play against PlayGo!')) else: self._ai_button.set_label(_('You need to install gnugo to play against PlayGo')) self._ai_button.set_sensitive(False) self.insert(self._ai_button, -1) self._ai_button.show() def _add_widget(self, widget, expand=False): tool_item = Gtk.ToolItem() tool_item.set_expand(expand) tool_item.add(widget) widget.show() self.insert(tool_item, -1) tool_item.show() def _game_restart_cb(self, widget): self._size_combo.set_sensitive(True) self.emit('game-restart') def grey_out_restart(self): self._restart_button.set_sensitive(False) def _game_size_cb(self, widget): game_size = int(self._sizes[self._size_combo.combo.get_active()][:2]) self.emit('game-board-size', game_size) def grey_out_size_change(self): self._size_combo.set_sensitive(False) def update_toolbar(self, widget, data, grid): size = data.get('size') self._size_combo.combo.handler_block(self.size_handle_id) size_index = self._sizes.index(size+' X '+size) self._size_combo.combo.set_active(int(size_index)) self._size_combo.combo.handler_unblock(self.size_handle_id) def _ai_toggled_cb(self, widget): if widget.get_active(): self.emit('ai-activated') else: self.emit('ai-deactivated') def grey_out_ai(self): self._ai_button.set_sensitive(False) def set_ai_button_state(self, value): self._ai_button.set_active(value)
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 make_toolbar(self): toolbar_box = ToolbarBox() toolbar = toolbar_box.toolbar activity_button = ToolButton() activity_button.set_icon_widget(ActivityIcon(None)) toolbar.insert(activity_button, -1) utils.make_separator(toolbar, False) edit_toolbar = EditToolbar() edit_toolbar.undo.props.visible = False edit_toolbar.redo.props.visible = False edit_toolbar.separator.props.visible = False edit_toolbar.copy.connect("clicked", self.copy_cb) edit_toolbar.copy.props.accelerator = "<Ctrl><Shift>C" edit_toolbar.paste.connect("clicked", self.paste_cb) edit_toolbar.paste.props.accelerator = "<Ctrl><Shift>V" self.copy_button = edit_toolbar.copy self.copy_button.set_sensitive(False) edit_toolbar_button = ToolbarButton(page=edit_toolbar, icon_name="toolbar-edit") toolbar_box.toolbar.insert(edit_toolbar_button, -1) view_toolbar = Gtk.Toolbar() boton_toolbar_view = ToolbarButton(page=view_toolbar, icon_name="toolbar-view") toolbar.insert(boton_toolbar_view, -1) background_color_button = ColorToolButton() background_color_button.set_color(self.background_color) background_color_button.set_title("Background color") background_color_button.connect("color-set", self.background_color_changed) view_toolbar.insert(background_color_button, -1) text_color_button = ColorToolButton() text_color_button.set_color(self.text_color) text_color_button.set_title("Text color") text_color_button.connect("color-set", self.text_color_changed) view_toolbar.insert(text_color_button, -1) item_font_size = FontSize() item_font_size.set_font_size(self.font_size, False) item_font_size.connect("changed", self.font_size_changed) view_toolbar.insert(item_font_size, -1) utils.make_separator(view_toolbar, False) button_left = Gtk.RadioToolButton() button_left.set_icon_name('go-left') button_left.set_tooltip_text("Move 'add' button to the left") view_toolbar.insert(button_left, -1) button_right = Gtk.RadioToolButton.new_from_widget(button_left) button_right.set_icon_name('go-right') button_right.set_tooltip_text("Move 'add' button to the right") view_toolbar.insert(button_right, -1) if self.button_position == Gtk.PackType.START: button_left.set_active(True) elif self.button_position == Gtk.PackType.END: button_right.set_active(True) button_left.connect("toggled", self.move_button, Gtk.PackType.START) button_right.connect("toggled", self.move_button, Gtk.PackType.END) view_toolbar.show_all() self.button_new = ToolButton("add") self.button_new.props.accelerator = "<Ctrl><Shift>T" self.button_new.connect("clicked", lambda button: self.notebook.new_terminal()) toolbar.insert(self.button_new, -1) utils.make_separator(toolbar, True) button_stop = ToolButton("activity-stop") button_stop.props.accelerator = "<Ctrl><Shift>C" button_stop.connect("clicked", self._close) toolbar.insert(button_stop, -1) toolbar.show_all() self.set_toolbar_box(toolbar_box)
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() client = GConf.Client.get_default() color = XoColor(client.get_string('/desktop/sugar/user/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): misc.resume(self._metadata, alert_window=journalwindow.get_journal_window()) def _copy_clicked_cb(self, button): button.palette.popup(immediate=True, state=Palette.SECONDARY) def _refresh_clicked_cb(self, button): button.palette.popup(immediate=True, state=Palette.SECONDARY) def _duplicate_clicked_cb(self, button): try: model.copy(self._metadata, '/') except IOError, e: logging.exception('Error while copying the entry.') self.emit('volume-error', _('Error while copying the entry. %s') % (e.strerror, ), _('Error'))
class WriteBooksActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) self._book_model = BookModel() self._actual_page = 1 # we do not have collaboration features # make the share option insensitive self.max_participants = 1 # get the language configured by the user # will be used to translate the names of the media files locale = os.environ.get('LANG', '') language_location = locale.split('.', 1)[0].lower() self._language = language_location.split('_')[0] if self._language == 'en': # we don't need translate the file names if langauage is 'en' self._language = None self._translations = None if self._language is not None: # read the translations file if available dict_path = os.path.join(activity.get_bundle_path(), 'data', "%s_dict.csv" % self._language) logging.debug('Looking for media translation dictionary %s', dict_path) if os.path.exists(dict_path): logging.debug('Loading translations') self._translations = {} with open(dict_path) as dict_file: for line in dict_file: words = line.split(',') self._translations[words[0]] = words[1].strip() toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) self._edit_toolbar = EditToolbar() edit_toolbar_button = ToolbarButton( page=self._edit_toolbar, icon_name='toolbar-edit') toolbar_box.toolbar.insert(edit_toolbar_button, 1) set_background_button = ToolButton('set-background') set_background_button.set_tooltip(_('Set the background')) set_background_button.connect('clicked', self.__set_background_clicked_cb) toolbar_box.toolbar.insert(set_background_button, -1) insert_picture_button = ToolButton('insert-picture') insert_picture_button.set_tooltip(_('Add a picture')) insert_picture_button.connect('clicked', self.__add_image_clicked_cb) toolbar_box.toolbar.insert(insert_picture_button, -1) toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1) self._duplicate_page_button = ToolButton() icon = Icon(icon_name='edit-duplicate', xo_color=profile.get_color()) self._duplicate_page_button.set_icon_widget(icon) self._duplicate_page_button.set_tooltip(_('Duplicate page')) self._duplicate_page_button.connect( 'clicked', self.__duplicate_page_clicked_cb) toolbar_box.toolbar.insert(self._duplicate_page_button, -1) self._add_page_button = ToolButton('list-add') self._add_page_button.set_tooltip(_('Add a page')) self._add_page_button.connect('clicked', self.__add_page_clicked_cb) toolbar_box.toolbar.insert(self._add_page_button, -1) self._remove_button = ToolButton('edit-delete') self._remove_button.set_tooltip(_('Remove an image or page')) self._remove_button.connect('clicked', self.__remove_clicked_cb) toolbar_box.toolbar.insert(self._remove_button, -1) self._prev_page_button = ToolButton('go-previous-paired') self._prev_page_button.set_tooltip(_('Previous page')) self._prev_page_button.connect('clicked', self.__prev_page_clicked_cb) toolbar_box.toolbar.insert(self._prev_page_button, -1) self._next_page_button = ToolButton('go-next-paired') self._next_page_button.set_tooltip(_('Next page')) self._next_page_button.connect('clicked', self.__next_page_clicked_cb) toolbar_box.toolbar.insert(self._next_page_button, -1) self._view_list_button = ToggleToolButton('view-list') self._view_list_button.set_tooltip(_('View pages')) self._view_list_button.connect('toggled', self.__view_list_toggled_cb) toolbar_box.toolbar.insert(self._view_list_button, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) stop_button = StopButton(self) toolbar_box.toolbar.insert(stop_button, -1) # add export buttons activity_toolbar = activity_button.props.page epub_button = ToolButton('save-as-epub') epub_button.set_tooltip(_('Save as EPUB book')) epub_button.connect('clicked', self.__save_ebook_clicked_cb) activity_toolbar.insert(epub_button, -1) epub_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show_all() edition_canvas = self.create_edition_canvas() hbox = Gtk.HBox() self._preview_panel = PreviewPanel(self._book_model.get_pages()) self._preview_panel.connect('page-activated', self.__page_activated_cb) self._preview_panel.connect('page-moved', self.__page_moved_cb) hbox.pack_start(self._preview_panel, False, False, 0) hbox.pack_start(edition_canvas, True, True, 0) self.set_canvas(hbox) self.prepare_edit_toolbar() self._update_page_buttons() self.show_all() self._preview_panel.hide() def create_edition_canvas(self): self._image_canvas = ImageCanvas() self._image_canvas.connect('images-modified', self.__images_modified_cb) self._image_canvas.set_halign(Gtk.Align.CENTER) self._image_canvas.set_valign(Gtk.Align.CENTER) self._image_canvas.set_vexpand(True) self._text_editor = TextEditor() self._text_changed_signal_id = self._text_editor.connect( 'changed', self.__text_changed_cb) self._page_counter_label = Gtk.Label('1 / 1') font_desc = Pango.font_description_from_string('12') self._page_counter_label.modify_font(font_desc) self._page_counter_label.set_halign(Gtk.Align.END) self._page_counter_label.set_valign(Gtk.Align.END) self._page_counter_label.set_margin_right(style.DEFAULT_PADDING) self._page_counter_label.set_margin_top(style.DEFAULT_PADDING) background = Gtk.EventBox() rgba = Gdk.RGBA() rgba.red, rgba.green, rgba.blue, rgba.alpha = 1., 1., 1., 1. background.override_background_color(Gtk.StateFlags.NORMAL, rgba) self._scrolled_window = Gtk.ScrolledWindow() self._scrolled_window.set_shadow_type(Gtk.ShadowType.ETCHED_IN) self._scrolled_window.set_size_request( Gdk.Screen.width() - style.GRID_CELL_SIZE * 2, style.GRID_CELL_SIZE * 2) self._scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self._scrolled_window.add(self._text_editor) self._scrolled_window.set_margin_left(style.GRID_CELL_SIZE) self._scrolled_window.set_margin_right(style.GRID_CELL_SIZE) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) box.pack_start(self._page_counter_label, False, False, 0) box.pack_start(self._image_canvas, True, True, 0) box.pack_start(self._scrolled_window, False, False, style.DEFAULT_PADDING) background.add(box) background.show_all() background.connect('size_allocate', self.__background_size_allocate_cb) return background def __background_size_allocate_cb(self, widget, allocation): height = allocation.height / 4 * 3 width = height / 3 * 4 logging.debug('size allocate %s x %s', width, height) self._image_canvas.set_size_request(width, height) widget.check_resize() def __view_list_toggled_cb(self, button): if button.get_active(): self._preview_panel.update_model(self._book_model.get_pages()) self._preview_panel.show() self._image_canvas.set_editable(False) self._text_editor.set_editable(False) self._scrolled_window.set_size_request( (Gdk.Screen.width() * 3 / 4) - style.GRID_CELL_SIZE * 2, style.GRID_CELL_SIZE * 2) else: self._preview_panel.hide() self._image_canvas.set_editable(True) self._text_editor.set_editable(True) self._scrolled_window.set_size_request( Gdk.Screen.width() - style.GRID_CELL_SIZE * 2, style.GRID_CELL_SIZE * 2) def write_file(self, file_path): self._book_model.write(file_path) self.metadata['mime_type'] = 'application/x-writebooks-activity' def read_file(self, file_path): self._book_model.read(file_path) self._update_page_buttons() def prepare_edit_toolbar(self): self._edit_toolbar.copy.connect('clicked', self.__copy_clicked_cb) self._edit_toolbar.paste.connect('clicked', self.__paste_clicked_cb) self._edit_toolbar.undo.connect('clicked', self.__undo_clicked_cb) self._edit_toolbar.redo.connect('clicked', self.__redo_clicked_cb) def __copy_clicked_cb(self, button): if self._text_editor.get_buffer().get_has_selection(): self._text_editor.get_buffer().copy_clipboard( Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)) elif self._image_canvas.is_image_active(): # if not text is selected # and a image is selected, copy as pixbuf clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) pxb = self._image_canvas.create_pixbuf_with_active_image() clipboard.set_image(pxb) def __paste_clicked_cb(self, button): self._text_editor.get_buffer().paste_clipboard( Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD), None, True) def __undo_clicked_cb(self, button): self._text_editor.get_buffer().undo() def __redo_clicked_cb(self, button): self._text_editor.get_buffer().redo() def __set_background_clicked_cb(self, button): categories = { _('Indoors'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Indoors')], _('Nature'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Nature')], _('Outdoors'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Outdoors')], _('Sports'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Sports')]} chooser = ImageFileChooser(image_type='backgrounds', title=_('Select a background'), categories=categories, language=self._language, translations=self._translations, parent=self.get_window()) chooser.connect('response', self.__chooser_response_cb, self._change_background) self.set_sensitive(False) chooser.show() def __chooser_response_cb(self, chooser, response_id, operation_function): self.set_sensitive(True) if response_id == Gtk.ResponseType.ACCEPT: logging.error('selected %s', chooser.get_selected_object_id()) file_path = chooser.get_selected_object_id() tempfile_name = \ os.path.join(self.get_activity_root(), 'instance', 'tmp%i' % time.time()) os.link(file_path, tempfile_name) operation_function(tempfile_name) chooser.destroy() del chooser if response_id == Gtk.ResponseType.REJECT: try: chooser = ObjectChooser(self, what_filter='Image', filter_type=FILTER_TYPE_GENERIC_MIME, show_preview=True) except: # for compatibility with older versions chooser = ObjectChooser(self, what_filter='Image') try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: logging.error('ObjectChooser: %r' % chooser.get_selected_object()) jobject = chooser.get_selected_object() if jobject and jobject.file_path: logging.error("imagen seleccionada: %s", jobject.file_path) tempfile_name = \ os.path.join(self.get_activity_root(), 'instance', 'tmp%i' % time.time()) os.link(jobject.file_path, tempfile_name) operation_function(tempfile_name) finally: chooser.destroy() del chooser def _change_background(self, file_name): self._book_model.set_page_background(self._actual_page, file_name) self._update_page_view() def __add_image_clicked_cb(self, button): categories = { _('Animals'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Animals'), os.path.join(TUXPAINT_STAMPS_PATH, 'animals')], _('Fantasy'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Fantasy'), os.path.join(TUXPAINT_STAMPS_PATH, 'cartoon')], _('Letters'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Letters')], _('People'): [os.path.join(SCRATCH_COSTUMES_PATH, 'People'), os.path.join(TUXPAINT_STAMPS_PATH, 'people')], _('Things'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Things'), os.path.join(TUXPAINT_STAMPS_PATH, 'clothes'), os.path.join(TUXPAINT_STAMPS_PATH, 'hobbies'), os.path.join(TUXPAINT_STAMPS_PATH, 'medical'), os.path.join(TUXPAINT_STAMPS_PATH, 'household'), os.path.join(TUXPAINT_STAMPS_PATH, 'food')], _('Transportation'): [ os.path.join(SCRATCH_COSTUMES_PATH, 'Transportation'), os.path.join(TUXPAINT_STAMPS_PATH, 'vehicles')]} chooser = ImageFileChooser(image_type='actors', title=_('Select an image to add'), categories=categories, language=self._language, translations=self._translations, parent=self.get_window()) chooser.connect('response', self.__chooser_response_cb, self._add_image) self.set_sensitive(False) chooser.show() def _add_image(self, file_name): logging.error('Add image %s', file_name) self._book_model.add_image(self._actual_page, file_name) self._update_page_view() def __remove_clicked_cb(self, file_name): if self._image_canvas.is_image_active(): alert = ConfirmationAlert() alert.props.title = _('Do you want remove the selected image?') # alert.props.msg = _('') alert.connect('response', self.__confirm_remove_image_cb) self.add_alert(alert) else: if len(self._book_model.get_pages()) > 1: alert = ConfirmationAlert() alert.props.title = _('Do you want remove the page?') # alert.props.msg = _('') alert.connect('response', self.__confirm_remove_page_cb) self.add_alert(alert) def __confirm_remove_image_cb(self, alert, response_id): # Callback for conf alert self.remove_alert(alert) if response_id is Gtk.ResponseType.OK: self._image_canvas.remove_active_image() def __confirm_remove_page_cb(self, alert, response_id): # Callback for conf alert self.remove_alert(alert) if response_id is Gtk.ResponseType.OK: if self._book_model.remove_page(self._actual_page): if self._actual_page > len(self._book_model.get_pages()): self._actual_page -= 1 self._update_page_buttons() self._preview_panel.update_model(self._book_model.get_pages()) def __images_modified_cb(self, canvas, images_views): self._book_model.update_images(self._actual_page, images_views) def _update_page_buttons(self): cant_pages = len(self._book_model.get_pages()) self._page_counter_label.set_text('%d / %d' % (self._actual_page, cant_pages)) self._prev_page_button.set_sensitive(self._actual_page > 1) self._next_page_button.set_sensitive(self._actual_page < cant_pages) self._update_page_view() def _update_page_view(self): page_model = self._book_model.get_page_model(self._actual_page) self._image_canvas.set_background(page_model.background_path) self._image_canvas.set_images(page_model.images) self._text_editor.disconnect(self._text_changed_signal_id) self._text_editor.set_text(page_model.text) self._text_changed_signal_id = self._text_editor.connect( 'changed', self.__text_changed_cb) def __add_page_clicked_cb(self, button): self._book_model.add_page() self._actual_page = len(self._book_model.get_pages()) self._update_page_buttons() self._preview_panel.update_model(self._book_model.get_pages()) def __duplicate_page_clicked_cb(self, button): actual_page_model = self._book_model.get_page_model(self._actual_page) self._book_model.add_page(actual_page_model) self._actual_page = len(self._book_model.get_pages()) self._update_page_buttons() self._preview_panel.update_model(self._book_model.get_pages()) def __next_page_clicked_cb(self, button): self._actual_page += 1 self._update_page_buttons() self._preview_panel.update_position(1) def __prev_page_clicked_cb(self, button): self._actual_page -= 1 self._update_page_buttons() self._preview_panel.update_position(-1) def __page_activated_cb(self, preview_panel, order): self._actual_page = order self._update_page_buttons() def __page_moved_cb(self, preview_panel, pages_order_array): new_pages = [] for n in pages_order_array: new_pages.append(self._book_model.get_pages()[n]) # actual_page is 1 based and order is 0 based actual_page_order = self._actual_page - 1 new_order_actual_page = pages_order_array.index(actual_page_order) self._actual_page = new_order_actual_page + 1 self._book_model.set_pages(new_pages) self._update_page_buttons() preview_panel.update_model(self._book_model.get_pages()) def __text_changed_cb(self, texteditor): self._book_model.set_page_text(self._actual_page, texteditor.get_text()) def __save_ebook_clicked_cb(self, button): alert = Alert() alert.props.title = _('Book creation') alert.props.msg = _('Do you want to add an image for the cover?') icon = Icon(icon_name='dialog-ok') alert.add_button(Gtk.ResponseType.YES, _('Yes'), icon) icon.show() icon = Icon(icon_name='dialog-cancel') alert.add_button(Gtk.ResponseType.NO, _('No'), icon) icon.show() alert.connect('response', self.__add_cover_response_cb, self._set_cover_and_create_book) self.add_alert(alert) def __add_cover_response_cb(self, alert, response_id, operation_function): if response_id == Gtk.ResponseType.YES: try: chooser = ObjectChooser(self, what_filter='Image', filter_type=FILTER_TYPE_GENERIC_MIME, show_preview=True) except: # for compatibility with older versions chooser = ObjectChooser(self, what_filter='Image') try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: logging.error('ObjectChooser: %r' % chooser.get_selected_object()) jobject = chooser.get_selected_object() if jobject and jobject.file_path: logging.error("imagen seleccionada: %s", jobject.file_path) mime_type = mime.get_for_file(jobject.file_path) extension = mime.get_primary_extension(mime_type) tempfile_name = \ os.path.join( self.get_activity_root(), 'instance', 'tmp%i.%s' % (time.time(), extension)) os.link(jobject.file_path, tempfile_name) operation_function(tempfile_name) finally: chooser.destroy() del chooser elif response_id == Gtk.ResponseType.NO: self._save_epub() self.remove_alert(alert) def _set_cover_and_create_book(self, cover_file_name): self._book_model.cover_path = cover_file_name self._save_epub() def _save_epub(self): epub_file_name = create_ebub_from_book_model( self.metadata['title'], self._book_model) # create a new journal item fileObject = datastore.create() fileObject.metadata['title'] = \ _('"%s" as book') % self.metadata['title'] fileObject.metadata['mime_type'] = 'application/epub+zip' full_text = '' for page in self._book_model.get_pages(): full_text += page.text + '\n' fileObject.metadata['fulltext'] = full_text fileObject.metadata['icon-color'] = self.metadata['icon-color'] fileObject.metadata['keep'] = self.metadata.get('keep', '0') fileObject.metadata['preview'] = self.metadata['preview'] fileObject.file_path = epub_file_name # store the journal item datastore.write(fileObject, transfer_ownership=True) book_object_id = fileObject.object_id fileObject.destroy() del fileObject shutil.rmtree(os.path.dirname(epub_file_name)) finish_alert = Alert() finish_alert.props.title = _('Book created') finish_alert.props.msg = _('You can read the book in your Journal') open_icon = Icon(icon_name='zoom-activity') finish_alert.add_button(Gtk.ResponseType.APPLY, _('Show in Journal'), open_icon) open_icon.show() ok_icon = Icon(icon_name='dialog-ok') finish_alert.add_button(Gtk.ResponseType.OK, _('Ok'), ok_icon) ok_icon.show() # Remove other alerts for alert in self._alerts: self.remove_alert(alert) self.add_alert(finish_alert) finish_alert.connect('response', self.__book_saved_alert_response_cb, book_object_id) finish_alert.show() def __book_saved_alert_response_cb(self, alert, response_id, book_object_id): if response_id is Gtk.ResponseType.APPLY: activity.show_object_in_journal(book_object_id) self.remove_alert(alert)
class DetailToolbox(ToolbarBox): __gsignals__ = { 'volume-error': (GObject.SignalFlags.RUN_FIRST, None, ([str, str])), } def __init__(self): ToolbarBox.__init__(self) self._metadata = None self._temp_file_path = None self._resume = ToolButton('activity-start') self._resume.connect('clicked', self._resume_clicked_cb) self.toolbar.insert(self._resume, -1) self._resume.show() client = GConf.Client.get_default() color = XoColor(client.get_string('/desktop/sugar/user/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) 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_resume_palette() def _resume_clicked_cb(self, button): misc.resume(self._metadata) def _copy_clicked_cb(self, button): button.palette.popup(immediate=True, state=Palette.SECONDARY) def _duplicate_clicked_cb(self, button): file_path = model.get_file(self._metadata['uid']) try: model.copy(self._metadata, '/') except IOError, e: logging.exception('Error while copying the entry.') self.emit('volume-error', _('Error while copying the entry. %s') % (e.strerror, ), _('Error'))
class CreateCardPanel(Gtk.EventBox): __gsignals__ = { 'add-pair': (GObject.SignalFlags.RUN_FIRST, None, 10 * [GObject.TYPE_PYOBJECT]), 'update-pair': (GObject.SignalFlags.RUN_FIRST, None, 8 * [GObject.TYPE_PYOBJECT]), 'change-font': (GObject.SignalFlags.RUN_FIRST, None, 2 * [GObject.TYPE_PYOBJECT]), 'pair-closed': (GObject.SignalFlags.RUN_FIRST, None, []), } def __init__(self, game): def make_label(icon_name, label): label_box = Gtk.VBox() icon = Icon(icon_name=icon_name, pixel_size=style.LARGE_ICON_SIZE) label_box.pack_start(icon, False, False, 0) label = Gtk.Label(label=label) label.modify_fg(Gtk.StateType.NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) label_box.pack_start(label, True, True, 0) label_box.show_all() return label_box Gtk.EventBox.__init__(self) self._game = game self.equal_pairs = False self._updatebutton_sensitive = False self._card1_has_sound = False self._card2_has_sound = False # save buttons self._portrait = Gdk.Screen.width() < Gdk.Screen.height() if self._portrait: buttons_bar_orientation = Gtk.Orientation.HORIZONTAL else: buttons_bar_orientation = Gtk.Orientation.VERTICAL self._buttons_bar = Gtk.Box(orientation=buttons_bar_orientation) self._buttons_bar.props.border_width = 10 self._buttons_bar.set_valign(Gtk.Align.CENTER) self._buttons_bar.set_halign(Gtk.Align.CENTER) self._addbutton = ToolButton(tooltip=_('Add as new pair'), sensitive=False) self._addbutton.set_icon_widget( make_label('pair-add', ' ' + _('Add'))) self._addbutton.connect('clicked', self.emit_add_pair) self._buttons_bar.pack_start(self._addbutton, False, False, 0) self._updatebutton = ToolButton(tooltip=_('Update selected pair'), sensitive=False) self._updatebutton.set_icon_widget( make_label('pair-update', ' ' + _('Update'))) self._updatebutton.connect('clicked', self.emit_update_pair) self._buttons_bar.pack_start(self._updatebutton, False, False, 0) self._removebutton = ToolButton(tooltip=_('Remove selected pair'), sensitive=False) self._removebutton.set_icon_widget( make_label('remove', ' ' + _('Remove'))) self._removebutton.connect('clicked', self.emit_close) self._buttons_bar.pack_start(self._removebutton, False, False, 0) # Set card editors self.cardeditor1 = CardEditor(self._game, 1) self.cardeditor2 = CardEditor(self._game, 2) self.clean(None) self.cardeditor1.connect('has-text', self.receive_text_signals) self.cardeditor2.connect('has-text', self.receive_text_signals) self.cardeditor1.connect('has-picture', self.receive_picture_signals) self.cardeditor2.connect('has-picture', self.receive_picture_signals) self.cardeditor1.connect('has-sound', self.receive_sound_signals) self.cardeditor2.connect('has-sound', self.receive_sound_signals) self.cardeditor1.connect('change-font', self.receive_font_signals) self.cardeditor2.connect('change-font', self.receive_font_signals) # edit panel self.card_box = Gtk.HBox() self.card_box.set_homogeneous(True) self.cardeditor1.set_halign(Gtk.Align.CENTER) self.cardeditor1.set_valign(Gtk.Align.CENTER) self.cardeditor2.set_halign(Gtk.Align.CENTER) self.cardeditor2.set_valign(Gtk.Align.CENTER) self.card_box.pack_start(self.cardeditor1, True, True, 0) self.card_box.pack_start(self.cardeditor2, True, True, 0) if self._portrait: main_box_orientation = Gtk.Orientation.VERTICAL else: main_box_orientation = Gtk.Orientation.HORIZONTAL self._main_box = Gtk.Box(orientation=main_box_orientation) self._main_box.pack_start(self.card_box, True, True, 0) self._main_box.pack_start(self._buttons_bar, True, True, 0) self.add(self._main_box) self.connect('size-allocate', self._allocate_cb) self.show_all() def _allocate_cb(self, widget, allocation): GLib.idle_add(self.update_orientation) def update_orientation(self): self._portrait = Gdk.Screen.width() < Gdk.Screen.height() if self._portrait: self._buttons_bar.props.orientation = Gtk.Orientation.HORIZONTAL self._main_box.props.orientation = Gtk.Orientation.VERTICAL else: self._buttons_bar.props.orientation = Gtk.Orientation.VERTICAL self._main_box.props.orientation = Gtk.Orientation.HORIZONTAL def update_font_combos(self, widget, data, grid): if 'font_name1' in data: self.cardeditor1.set_font_name(data['font_name1']) self.cardeditor1.card.change_font(data['font_name1']) if 'font_name2' in data: self.cardeditor2.set_font_name(data['font_name2']) self.cardeditor2.card.change_font(data['font_name2']) def emit_close(self, widget): self.emit('pair-closed') def emit_add_pair(self, widget): self._addbutton.set_sensitive(False) if self.equal_pairs: self.emit('add-pair', self.cardeditor1.get_text(), self.cardeditor1.get_text(), self.cardeditor1.get_image_path(), self.cardeditor1.get_image_path(), self.cardeditor1.get_snd(), self.cardeditor1.get_snd(), self.cardeditor1.get_speak(), self.cardeditor1.get_speak(), self.cardeditor1.get_font_name(), self.cardeditor1.get_font_name()) else: self.emit('add-pair', self.cardeditor1.get_text(), self.cardeditor2.get_text(), self.cardeditor1.get_image_path(), self.cardeditor2.get_image_path(), self.cardeditor1.get_snd(), self.cardeditor2.get_snd(), self.cardeditor1.get_speak(), self.cardeditor2.get_speak(), self.cardeditor1.get_font_name(), self.cardeditor2.get_font_name()) self.clean(None) def emit_update_pair(self, widget): self._addbutton.set_sensitive(False) if self.equal_pairs: self.emit('update-pair', self.cardeditor1.get_text(), self.cardeditor1.get_text(), self.cardeditor1.get_image_path(), self.cardeditor1.get_image_path(), self.cardeditor1.get_snd(), self.cardeditor1.get_snd(), self.cardeditor1.get_speak(), self.cardeditor1.get_speak()) else: self.emit('update-pair', self.cardeditor1.get_text(), self.cardeditor2.get_text(), self.cardeditor1.get_image_path(), self.cardeditor2.get_image_path(), self.cardeditor1.get_snd(), self.cardeditor2.get_snd(), self.cardeditor1.get_speak(), self.cardeditor2.get_speak()) self.clean(None) def pair_selected(self, widget, selected, newtext1, newtext2, aimage_path, bimage_path, asnd, bsnd, aspeak, bspeak): if selected: self.cardeditor1.set_text(newtext1) self.cardeditor2.set_text(newtext2) self.cardeditor1.set_image_path(aimage_path) self.cardeditor2.set_image_path(bimage_path) self.cardeditor1.set_snd(asnd) self.cardeditor2.set_snd(bsnd) self.cardeditor1.set_speak(aspeak) self.cardeditor2.set_speak(bspeak) self._addbutton.set_sensitive(True) self._updatebutton.set_sensitive(selected) self._updatebutton_sensitive = selected self._removebutton.set_sensitive(selected) def change_equal_pairs(self, widget, state): self.equal_pairs = state self.clean(None) if self.equal_pairs: if self.cardeditor2.get_parent(): self.card_box.remove(self.cardeditor2) else: if not self.cardeditor2.get_parent(): self.card_box.pack_start(self.cardeditor2, True, True, 0) def clean(self, widget): self.cardeditor1.clean() self.cardeditor2.clean() self._addbutton.set_sensitive(False) self._card1_has_text = False self._card2_has_text = False self._card1_has_picture = False self._card2_has_picture = False def receive_text_signals(self, widget, has_text): if widget == self.cardeditor1: self._card1_has_text = has_text if widget == self.cardeditor2: self._card2_has_text = has_text self._update_buttom_status() def receive_picture_signals(self, widget, has_picture): if widget == self.cardeditor1: self._card1_has_picture = has_picture if widget == self.cardeditor2: self._card2_has_picture = has_picture self._update_buttom_status() def receive_sound_signals(self, widget, has_sound): if widget == self.cardeditor1: self._card1_has_sound = has_sound if widget == self.cardeditor2: self._card2_has_sound = has_sound self._update_buttom_status() def receive_font_signals(self, widget, font_name): if self.equal_pairs: self.emit('change-font', 1, font_name) self.emit('change-font', 2, font_name) else: if widget == self.cardeditor1: self.emit('change-font', 1, font_name) if widget == self.cardeditor2: self.emit('change-font', 2, font_name) def _update_buttom_status(self): if not self.equal_pairs: if (self._card1_has_text or self._card1_has_picture or self._card1_has_sound) and (self._card2_has_text or self._card2_has_picture or self._card2_has_sound): self._addbutton.set_sensitive(True) self._updatebutton.set_sensitive(self._updatebutton_sensitive) else: self._addbutton.set_sensitive(False) self._updatebutton.set_sensitive(False) else: if (self._card1_has_text or self._card1_has_picture or self._card1_has_sound): self._addbutton.set_sensitive(True) self._updatebutton.set_sensitive(self._updatebutton_sensitive) else: self._addbutton.set_sensitive(False) self._updatebutton.set_sensitive(False) def set_temp_folder(self, temp_folder): self.cardeditor1.temp_folder = temp_folder self.cardeditor2.temp_folder = temp_folder
class WriteBooksActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) self._book_model = BookModel() self._actual_page = 1 # we do not have collaboration features # make the share option insensitive self.max_participants = 1 # get the language configured by the user # will be used to translate the names of the media files locale = os.environ.get('LANG', '') language_location = locale.split('.', 1)[0].lower() self._language = language_location.split('_')[0] if self._language == 'en': # we don't need translate the file names if langauage is 'en' self._language = None self._translations = None if self._language is not None: # read the translations file if available dict_path = os.path.join(activity.get_bundle_path(), 'data', "%s_dict.csv" % self._language) logging.debug('Looking for media translation dictionary %s', dict_path) if os.path.exists(dict_path): logging.debug('Loading translations') self._translations = {} with open(dict_path) as dict_file: for line in dict_file: words = line.split(',') self._translations[words[0]] = words[1].strip() toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) self._edit_toolbar = EditToolbar() edit_toolbar_button = ToolbarButton(page=self._edit_toolbar, icon_name='toolbar-edit') toolbar_box.toolbar.insert(edit_toolbar_button, 1) set_background_button = ToolButton('set-background') set_background_button.set_tooltip(_('Set the background')) set_background_button.connect('clicked', self.__set_background_clicked_cb) toolbar_box.toolbar.insert(set_background_button, -1) insert_picture_button = ToolButton('insert-picture') insert_picture_button.set_tooltip(_('Add a picture')) insert_picture_button.connect('clicked', self.__add_image_clicked_cb) toolbar_box.toolbar.insert(insert_picture_button, -1) toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1) self._duplicate_page_button = ToolButton() icon = Icon(icon_name='edit-duplicate', xo_color=profile.get_color()) self._duplicate_page_button.set_icon_widget(icon) self._duplicate_page_button.set_tooltip(_('Duplicate page')) self._duplicate_page_button.connect('clicked', self.__duplicate_page_clicked_cb) toolbar_box.toolbar.insert(self._duplicate_page_button, -1) self._add_page_button = ToolButton('list-add') self._add_page_button.set_tooltip(_('Add a page')) self._add_page_button.connect('clicked', self.__add_page_clicked_cb) toolbar_box.toolbar.insert(self._add_page_button, -1) self._remove_button = ToolButton('edit-delete') self._remove_button.set_tooltip(_('Remove a image or page')) self._remove_button.connect('clicked', self.__remove_clicked_cb) toolbar_box.toolbar.insert(self._remove_button, -1) self._prev_page_button = ToolButton('go-previous-paired') self._prev_page_button.set_tooltip(_('Previous page')) self._prev_page_button.connect('clicked', self.__prev_page_clicked_cb) toolbar_box.toolbar.insert(self._prev_page_button, -1) self._next_page_button = ToolButton('go-next-paired') self._next_page_button.set_tooltip(_('Next page')) self._next_page_button.connect('clicked', self.__next_page_clicked_cb) toolbar_box.toolbar.insert(self._next_page_button, -1) self._view_list_button = ToggleToolButton('view-list') self._view_list_button.set_tooltip(_('View pages')) self._view_list_button.connect('toggled', self.__view_list_toggled_cb) toolbar_box.toolbar.insert(self._view_list_button, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) stop_button = StopButton(self) toolbar_box.toolbar.insert(stop_button, -1) # add export buttons activity_toolbar = activity_button.props.page epub_button = ToolButton('save-as-epub') epub_button.set_tooltip(_('Save as EPUB book')) epub_button.connect('clicked', self.__save_ebook_clicked_cb) activity_toolbar.insert(epub_button, -1) epub_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show_all() edition_canvas = self.create_edition_canvas() hbox = Gtk.HBox() self._preview_panel = PreviewPanel(self._book_model.get_pages()) self._preview_panel.connect('page-activated', self.__page_activated_cb) self._preview_panel.connect('page-moved', self.__page_moved_cb) hbox.pack_start(self._preview_panel, False, False, 0) hbox.pack_start(edition_canvas, True, True, 0) self.set_canvas(hbox) self.prepare_edit_toolbar() self._update_page_buttons() self.show_all() self._preview_panel.hide() def create_edition_canvas(self): self._image_canvas = ImageCanvas() self._image_canvas.connect('images-modified', self.__images_modified_cb) self._image_canvas.set_halign(Gtk.Align.CENTER) self._image_canvas.set_valign(Gtk.Align.CENTER) self._image_canvas.set_vexpand(True) self._text_editor = TextEditor() self._text_changed_signal_id = self._text_editor.connect( 'changed', self.__text_changed_cb) self._page_counter_label = Gtk.Label('1 / 1') font_desc = Pango.font_description_from_string('12') self._page_counter_label.modify_font(font_desc) self._page_counter_label.set_halign(Gtk.Align.END) self._page_counter_label.set_valign(Gtk.Align.END) self._page_counter_label.set_margin_right(style.DEFAULT_PADDING) self._page_counter_label.set_margin_top(style.DEFAULT_PADDING) background = Gtk.EventBox() rgba = Gdk.RGBA() rgba.red, rgba.green, rgba.blue, rgba.alpha = 1., 1., 1., 1. background.override_background_color(Gtk.StateFlags.NORMAL, rgba) self._scrolled_window = Gtk.ScrolledWindow() self._scrolled_window.set_shadow_type(Gtk.ShadowType.ETCHED_IN) self._scrolled_window.set_size_request( Gdk.Screen.width() - style.GRID_CELL_SIZE * 2, style.GRID_CELL_SIZE * 2) self._scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self._scrolled_window.add(self._text_editor) self._scrolled_window.set_margin_left(style.GRID_CELL_SIZE) self._scrolled_window.set_margin_right(style.GRID_CELL_SIZE) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) box.pack_start(self._page_counter_label, False, False, 0) box.pack_start(self._image_canvas, True, True, 0) box.pack_start(self._scrolled_window, False, False, style.DEFAULT_PADDING) background.add(box) background.show_all() background.connect('size_allocate', self.__background_size_allocate_cb) return background def __background_size_allocate_cb(self, widget, allocation): height = allocation.height / 4 * 3 width = height / 3 * 4 logging.debug('size allocate %s x %s', width, height) self._image_canvas.set_size_request(width, height) widget.check_resize() def __view_list_toggled_cb(self, button): if button.get_active(): self._preview_panel.update_model(self._book_model.get_pages()) self._preview_panel.show() self._image_canvas.set_editable(False) self._text_editor.set_editable(False) self._scrolled_window.set_size_request( (Gdk.Screen.width() * 3 / 4) - style.GRID_CELL_SIZE * 2, style.GRID_CELL_SIZE * 2) else: self._preview_panel.hide() self._image_canvas.set_editable(True) self._text_editor.set_editable(True) self._scrolled_window.set_size_request( Gdk.Screen.width() - style.GRID_CELL_SIZE * 2, style.GRID_CELL_SIZE * 2) def write_file(self, file_path): self._book_model.write(file_path) self.metadata['mime_type'] = 'application/x-writebooks-activity' def read_file(self, file_path): self._book_model.read(file_path) self._update_page_buttons() def prepare_edit_toolbar(self): self._edit_toolbar.copy.connect('clicked', self.__copy_clicked_cb) self._edit_toolbar.paste.connect('clicked', self.__paste_clicked_cb) self._edit_toolbar.undo.connect('clicked', self.__undo_clicked_cb) self._edit_toolbar.redo.connect('clicked', self.__redo_clicked_cb) def __copy_clicked_cb(self, button): if self._text_editor.get_buffer().get_has_selection(): self._text_editor.get_buffer().copy_clipboard( Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)) elif self._image_canvas.is_image_active(): # if not text is selected # and a image is selected, copy as pixbuf clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) pxb = self._image_canvas.create_pixbuf_with_active_image() clipboard.set_image(pxb) def __paste_clicked_cb(self, button): self._text_editor.get_buffer().paste_clipboard( Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD), None, True) def __undo_clicked_cb(self, button): self._text_editor.get_buffer().undo() def __redo_clicked_cb(self, button): self._text_editor.get_buffer().redo() def __set_background_clicked_cb(self, button): categories = { _('Indoors'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Indoors')], _('Nature'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Nature')], _('Outdoors'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Outdoors')], _('Sports'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Sports')] } chooser = ImageFileChooser(image_type='backgrounds', title=_('Select a background'), categories=categories, language=self._language, translations=self._translations, parent=self.get_window()) chooser.connect('response', self.__chooser_response_cb, self._change_background) self.set_sensitive(False) chooser.show() def __chooser_response_cb(self, chooser, response_id, operation_function): self.set_sensitive(True) if response_id == Gtk.ResponseType.ACCEPT: logging.error('selected %s', chooser.get_selected_object_id()) file_path = chooser.get_selected_object_id() tempfile_name = \ os.path.join(self.get_activity_root(), 'instance', 'tmp%i' % time.time()) os.link(file_path, tempfile_name) operation_function(tempfile_name) chooser.destroy() del chooser if response_id == Gtk.ResponseType.REJECT: try: chooser = ObjectChooser(self, what_filter='Image', filter_type=FILTER_TYPE_GENERIC_MIME, show_preview=True) except: # for compatibility with older versions chooser = ObjectChooser(self, what_filter='Image') try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: logging.error('ObjectChooser: %r' % chooser.get_selected_object()) jobject = chooser.get_selected_object() if jobject and jobject.file_path: logging.error("imagen seleccionada: %s", jobject.file_path) tempfile_name = \ os.path.join(self.get_activity_root(), 'instance', 'tmp%i' % time.time()) os.link(jobject.file_path, tempfile_name) operation_function(tempfile_name) finally: chooser.destroy() del chooser def _change_background(self, file_name): self._book_model.set_page_background(self._actual_page, file_name) self._update_page_view() def __add_image_clicked_cb(self, button): categories = { _('Animals'): [ os.path.join(SCRATCH_COSTUMES_PATH, 'Animals'), os.path.join(TUXPAINT_STAMPS_PATH, 'animals') ], _('Fantasy'): [ os.path.join(SCRATCH_COSTUMES_PATH, 'Fantasy'), os.path.join(TUXPAINT_STAMPS_PATH, 'cartoon') ], _('Letters'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Letters')], _('People'): [ os.path.join(SCRATCH_COSTUMES_PATH, 'People'), os.path.join(TUXPAINT_STAMPS_PATH, 'people') ], _('Things'): [ os.path.join(SCRATCH_COSTUMES_PATH, 'Things'), os.path.join(TUXPAINT_STAMPS_PATH, 'clothes'), os.path.join(TUXPAINT_STAMPS_PATH, 'hobbies'), os.path.join(TUXPAINT_STAMPS_PATH, 'medical'), os.path.join(TUXPAINT_STAMPS_PATH, 'household'), os.path.join(TUXPAINT_STAMPS_PATH, 'food') ], _('Transportation'): [ os.path.join(SCRATCH_COSTUMES_PATH, 'Transportation'), os.path.join(TUXPAINT_STAMPS_PATH, 'vehicles') ] } chooser = ImageFileChooser(image_type='actors', title=_('Select a image to add'), categories=categories, language=self._language, translations=self._translations, parent=self.get_window()) chooser.connect('response', self.__chooser_response_cb, self._add_image) self.set_sensitive(False) chooser.show() def _add_image(self, file_name): logging.error('Add image %s', file_name) self._book_model.add_image(self._actual_page, file_name) self._update_page_view() def __remove_clicked_cb(self, file_name): if self._image_canvas.is_image_active(): alert = ConfirmationAlert() alert.props.title = _('Do you want remove the selected image?') # alert.props.msg = _('') alert.connect('response', self.__confirm_remove_image_cb) self.add_alert(alert) else: if len(self._book_model.get_pages()) > 1: alert = ConfirmationAlert() alert.props.title = _('Do you want remove the page?') # alert.props.msg = _('') alert.connect('response', self.__confirm_remove_page_cb) self.add_alert(alert) def __confirm_remove_image_cb(self, alert, response_id): # Callback for conf alert self.remove_alert(alert) if response_id is Gtk.ResponseType.OK: self._image_canvas.remove_active_image() def __confirm_remove_page_cb(self, alert, response_id): # Callback for conf alert self.remove_alert(alert) if response_id is Gtk.ResponseType.OK: if self._book_model.remove_page(self._actual_page): if self._actual_page > len(self._book_model.get_pages()): self._actual_page -= 1 self._update_page_buttons() self._preview_panel.update_model(self._book_model.get_pages()) def __images_modified_cb(self, canvas, images_views): self._book_model.update_images(self._actual_page, images_views) def _update_page_buttons(self): cant_pages = len(self._book_model.get_pages()) self._page_counter_label.set_text('%d / %d' % (self._actual_page, cant_pages)) self._prev_page_button.set_sensitive(self._actual_page > 1) self._next_page_button.set_sensitive(self._actual_page < cant_pages) self._update_page_view() def _update_page_view(self): page_model = self._book_model.get_page_model(self._actual_page) self._image_canvas.set_background(page_model.background_path) self._image_canvas.set_images(page_model.images) self._text_editor.disconnect(self._text_changed_signal_id) self._text_editor.set_text(page_model.text) self._text_changed_signal_id = self._text_editor.connect( 'changed', self.__text_changed_cb) def __add_page_clicked_cb(self, button): self._book_model.add_page() self._actual_page = len(self._book_model.get_pages()) self._update_page_buttons() self._preview_panel.update_model(self._book_model.get_pages()) def __duplicate_page_clicked_cb(self, button): actual_page_model = self._book_model.get_page_model(self._actual_page) self._book_model.add_page(actual_page_model) self._actual_page = len(self._book_model.get_pages()) self._update_page_buttons() self._preview_panel.update_model(self._book_model.get_pages()) def __next_page_clicked_cb(self, button): self._actual_page += 1 self._update_page_buttons() self._preview_panel.update_position(1) def __prev_page_clicked_cb(self, button): self._actual_page -= 1 self._update_page_buttons() self._preview_panel.update_position(-1) def __page_activated_cb(self, preview_panel, order): self._actual_page = order self._update_page_buttons() def __page_moved_cb(self, preview_panel, pages_order_array): new_pages = [] for n in pages_order_array: new_pages.append(self._book_model.get_pages()[n]) # actual_page is 1 based and order is 0 based actual_page_order = self._actual_page - 1 new_order_actual_page = pages_order_array.index(actual_page_order) self._actual_page = new_order_actual_page + 1 self._book_model.set_pages(new_pages) self._update_page_buttons() preview_panel.update_model(self._book_model.get_pages()) def __text_changed_cb(self, texteditor): self._book_model.set_page_text(self._actual_page, texteditor.get_text()) def __save_ebook_clicked_cb(self, button): alert = Alert() alert.props.title = _('Book creation') alert.props.msg = _('Do you want to add an image for the cover?') icon = Icon(icon_name='dialog-ok') alert.add_button(Gtk.ResponseType.YES, _('Yes'), icon) icon.show() icon = Icon(icon_name='dialog-cancel') alert.add_button(Gtk.ResponseType.NO, _('No'), icon) icon.show() alert.connect('response', self.__add_cover_response_cb, self._set_cover_and_create_book) self.add_alert(alert) def __add_cover_response_cb(self, alert, response_id, operation_function): if response_id == Gtk.ResponseType.YES: try: chooser = ObjectChooser(self, what_filter='Image', filter_type=FILTER_TYPE_GENERIC_MIME, show_preview=True) except: # for compatibility with older versions chooser = ObjectChooser(self, what_filter='Image') try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: logging.error('ObjectChooser: %r' % chooser.get_selected_object()) jobject = chooser.get_selected_object() if jobject and jobject.file_path: logging.error("imagen seleccionada: %s", jobject.file_path) mime_type = mime.get_for_file(jobject.file_path) extension = mime.get_primary_extension(mime_type) tempfile_name = \ os.path.join( self.get_activity_root(), 'instance', 'tmp%i.%s' % (time.time(), extension)) os.link(jobject.file_path, tempfile_name) operation_function(tempfile_name) finally: chooser.destroy() del chooser elif response_id == Gtk.ResponseType.NO: self._save_epub() self.remove_alert(alert) def _set_cover_and_create_book(self, cover_file_name): self._book_model.cover_path = cover_file_name self._save_epub() def _save_epub(self): epub_file_name = create_ebub_from_book_model(self.metadata['title'], self._book_model) # create a new journal item fileObject = datastore.create() fileObject.metadata['title'] = \ _('"%s" as book') % self.metadata['title'] fileObject.metadata['mime_type'] = 'application/epub+zip' full_text = '' for page in self._book_model.get_pages(): full_text += page.text + '\n' fileObject.metadata['fulltext'] = full_text fileObject.metadata['icon-color'] = self.metadata['icon-color'] fileObject.metadata['keep'] = self.metadata.get('keep', '0') fileObject.metadata['preview'] = self.metadata['preview'] fileObject.file_path = epub_file_name # store the journal item datastore.write(fileObject, transfer_ownership=True) book_object_id = fileObject.object_id fileObject.destroy() del fileObject shutil.rmtree(os.path.dirname(epub_file_name)) finish_alert = Alert() finish_alert.props.title = _('Book created') finish_alert.props.msg = _('You can read the book in your Journal') open_icon = Icon(icon_name='zoom-activity') finish_alert.add_button(Gtk.ResponseType.APPLY, _('Show in Journal'), open_icon) open_icon.show() ok_icon = Icon(icon_name='dialog-ok') finish_alert.add_button(Gtk.ResponseType.OK, _('Ok'), ok_icon) ok_icon.show() # Remove other alerts for alert in self._alerts: self.remove_alert(alert) self.add_alert(finish_alert) finish_alert.connect('response', self.__book_saved_alert_response_cb, book_object_id) finish_alert.show() def __book_saved_alert_response_cb(self, alert, response_id, book_object_id): if response_id is Gtk.ResponseType.APPLY: activity.show_object_in_journal(book_object_id) self.remove_alert(alert)
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 make_toolbar(self): def make_separator(toolbar, expand=True): separator = Gtk.SeparatorToolItem() separator.props.draw = not expand separator.set_expand(expand) toolbar.insert(separator, -1) toolbar_box = ToolbarBox() toolbar = toolbar_box.toolbar activity_button = ToolButton() activity_button.set_icon_widget(ActivityIcon(None)) toolbar.insert(activity_button, -1) toolbar.insert(Gtk.SeparatorToolItem(), -1) toolbar_file = Gtk.Toolbar() boton_toolbar_file = ToolbarButton(page=toolbar_file, icon_name='txt') toolbar.add(boton_toolbar_file) toolbar_edit = EditToolbar() button_toolbar_edit = ToolbarButton(page=toolbar_edit, icon_name='toolbar-edit') toolbar.insert(button_toolbar_edit, -1) toolbar_view = Gtk.Toolbar() boton_toolbar_view = ToolbarButton(page=toolbar_view, icon_name='toolbar-view') toolbar.insert(boton_toolbar_view, -1) self.button_undo = toolbar_edit.undo self.button_undo.props.accelerator = '<Ctrl>Z' self.button_undo.set_sensitive(False) toolbar_edit.undo.connect('clicked', self.undo) self.button_redo = toolbar_edit.redo self.button_redo.props.accelerator = '<Ctrl><Mayus>Z' self.button_redo.set_sensitive(False) self.button_redo.connect('clicked', self.redo) self.entry_search = IconEntry() item_entry = Gtk.ToolItem() self.entry_search.set_size_request(250, -1) self.entry_search.set_placeholder_text('Search...') self.entry_search.set_icon_from_name(Gtk.EntryIconPosition.SECONDARY, 'search') self.entry_search.connect('changed', self.search_text) self.entry_search.connect('activate', self.search_text, True) item_entry.add(self.entry_search) toolbar_edit.insert(item_entry, -1) self.entry_replace = IconEntry() item_entry = Gtk.ToolItem() self.entry_replace.set_size_request(250, -1) self.entry_replace.set_placeholder_text('Replace...') self.entry_replace.connect('activate', self.replace_text) item_entry.add(self.entry_replace) toolbar_edit.insert(item_entry, -1) button_new = ToolButton('new-file') button_new.props.accelerator = '<Ctrl>N' button_new.connect('clicked', lambda w: self.new_page()) button_new.set_tooltip(_('New file')) toolbar_file.insert(button_new, -1) button_open = ToolButton('fileopen') button_open.props.accelerator = '<Ctrl>O' button_open.set_tooltip(_('Open file from file system')) button_open.connect('clicked', self.file_chooser_open) toolbar_file.insert(button_open, -1) self.button_save = ToolButton('filesave') self.button_save.props.accelerator = '<Ctrl>S' self.button_save.set_tooltip(_('Save file to the file system')) self.button_save.connect('clicked', self.file_chooser_save) toolbar_file.insert(self.button_save, -1) button_save_as = ToolButton('save-as') button_save_as.props.accelerator = '<Ctrl><Mayus>S' button_save_as.set_tooltip(_('Save as file to the file system')) button_save_as.connect('clicked', self.file_chooser_save, True) toolbar_file.insert(button_save_as, -1) make_separator(toolbar_file, False) button_print = ToolButton('printer') button_print.props.accelerator = '<Ctrl>I' button_print.set_tooltip(_('Print file')) button_print.connect('clicked', self.print_file) toolbar_file.insert(button_print, -1) make_separator(toolbar_edit, False) button_clock = ToolButton('clock') button_clock.props.accelerator = '<Ctrl>T' button_clock.set_tooltip(_('Insert date and time')) button_clock.connect('clicked', self.insert_date_and_time) toolbar_edit.insert(button_clock, -1) button_wrap_none = Gtk.RadioToolButton() button_wrap_none.set_icon_name('wrap-none') button_wrap_none.connect("toggled", self.wrap_mode_changed, 'none') toolbar_view.insert(button_wrap_none, -1) button_wrap_char = Gtk.RadioToolButton.new_from_widget( button_wrap_none) button_wrap_char.set_icon_name('format-justify-fill') button_wrap_char.connect("toggled", self.wrap_mode_changed, 'char') toolbar_view.insert(button_wrap_char, -1) button_wrap_word = Gtk.RadioToolButton.new_from_widget( button_wrap_none) button_wrap_word.set_icon_name('format-justify-left') button_wrap_word.connect("toggled", self.wrap_mode_changed, 'word') toolbar_view.insert(button_wrap_word, -1) if self.conf['wrap-mode'] == 'none': button_wrap_none.set_active(True) elif self.conf['wrap-mode'] == 'char': button_wrap_none.set_active(True) elif self.conf['wrap-mode'] == 'word': button_wrap_none.set_active(True) make_separator(toolbar_view, False) item_font_size = FontSize() item_font_size.set_font_size(self.conf['font-size']) item_font_size.connect('changed', self.font_size_changed) toolbar_view.insert(item_font_size, -1) combo_font = FontComboBox(self.conf['font']) combo_font.connect('changed', self.font_changed) toolbar_view.insert(combo_font, -1) make_separator(toolbar_view, False) button_numbers = ToggleToolButton('show-numbers') button_numbers.props.accelerator = '<Ctrl><Mayus>N' button_numbers.set_tooltip(_('Show line numbers')) button_numbers.set_active(self.conf['show-line-numbers']) button_numbers.connect('toggled', self.show_numbers_changed) toolbar_view.insert(button_numbers, -1) button_right_line = ToggleToolButton('show-right-line') button_right_line.props.accelerator = '<Ctrl>L' button_right_line.set_tooltip(_('Show a line in a specific position')) button_right_line.set_active(self.conf['show-right-line']) button_right_line.connect('toggled', self.show_right_line_changed) toolbar_view.insert(button_right_line, -1) self.spinner_right_line = Spinner(self.conf['right-line-pos'], 1, 150) self.spinner_right_line.set_sensitive(self.conf['show-right-line']) self.spinner_right_line.connect('value-changed', self.right_line_pos_changed) toolbar_view.insert(self.spinner_right_line, -1) make_separator(toolbar_view, False) combo_styles = ComboStyles(self.conf['theme']) combo_styles.connect('theme-changed', self.theme_changed) toolbar_view.insert(combo_styles, -1) make_separator(toolbar, True) button_stop = ToolButton('activity-stop') button_stop.props.accelerator = '<Ctrl>Q' button_stop.connect('clicked', self._exit) toolbar.insert(button_stop, -1) toolbar_file.show_all() toolbar_edit.show_all() toolbar_view.show_all() toolbar_edit.copy.hide() toolbar_edit.paste.hide() self.set_toolbar_box(toolbar_box)
def make_toolbar(self): def make_separator(expand=False, size=0): separator = Gtk.SeparatorToolItem() separator.set_size_request(size, -1) if expand: separator.set_expand(True) if expand or size: separator.props.draw = False return separator self.color_palettes = [] toolbar_box = ToolbarBox() toolbar = toolbar_box.toolbar activity_button = ToolButton() activity_button.set_icon_widget(ActivityIcon(None)) toolbar.insert(activity_button, -1) toolbar.insert(make_separator(size=30), -1) button_copy = ToolButton(Gtk.STOCK_COPY) button_copy.set_tooltip('Copy the text.') button_copy.connect('clicked', self.copy_text) toolbar.insert(button_copy, -1) button_cut = ToolButton('cut') button_cut.set_tooltip('Cut the text.') button_cut.connect('clicked', self.cut_text) toolbar.insert(button_cut, -1) button_remove = ToolButton(Gtk.STOCK_REMOVE) button_remove.set_tooltip('Remove all the text.') button_remove.connect('clicked', self.remove_text) toolbar.insert(button_remove, -1) toolbar.insert(make_separator(size=30), -1) button_normal = ColorToolButton() button_normal.set_color(G.cairo_to_gdk(self.area.normal_color)) button_normal.set_title('Choose a color for the buttons.') button_normal.connect('color-set', self._normal_color_changed) toolbar.insert(button_normal, -1) self.color_palettes.append(button_normal) button_selected = ColorToolButton() button = button_selected.get_child() button_selected.set_color(G.cairo_to_gdk(self.area.selected_color)) button_selected.set_title('Choose a color for the selected buttons.') button_selected.connect('color-set', self._selected_color_changed) toolbar.insert(button_selected, -1) self.color_palettes.append(button_selected) button_labels = ColorToolButton() button_labels.set_color(G.cairo_to_gdk(self.area.label_color)) button_labels.set_title('Choose a color for the labels buttons.') button_labels.connect('color-set', self._label_color_changed) toolbar.insert(button_labels, -1) self.color_palettes.append(button_labels) button_background = ColorToolButton() button_background.set_color(G.cairo_to_gdk(self.area.background_color)) button_background.set_title('Choose a color for the background.') button_background.connect('color-set', self._background_color_changed) toolbar.insert(button_background, -1) self.color_palettes.append(button_background) toolbar.insert(make_separator(expand=True), -1) stop_button = ToolButton('activity-stop') stop_button.connect('clicked', lambda w: self.close()) stop_button.props.accelerator = '<Ctrl>Q' toolbar.insert(stop_button, -1) self.set_toolbar_box(toolbar_box)
def __init__(self,handle): activity.Activity.__init__(self,handle,True) self.basePath=activity.get_bundle_path() scroll=Gtk.ScrolledWindow(); scroll.set_policy(Gtk.PolicyType.NEVER,Gtk.PolicyType.NEVER); #get container self.canvasHolder=TabbedCanvas() self.canvasHolder.basePath=self.basePath #add tabControl to scrolled window scroll.add_with_viewport(self.canvasHolder) self.set_canvas(scroll) #add toolbox toolbox= ToolbarBox(self) activity_button=ActivityButton(self); toolbox.toolbar.insert(activity_button,0) activity_button.show() separator = Gtk.SeparatorToolItem() separator.show() toolbox.toolbar.insert(separator, 1) #new file button new_file = ToolButton('list-add') new_file.set_tooltip(_('New File')) new_file.props.accelerator=('<ctrl><shift>n') new_file.connect('clicked', self.newFile) toolbox.toolbar.insert(new_file,2) new_file.show() #close file button close_file=ToolButton('list-remove') close_file.set_tooltip(_('Close File')) close_file.props.accelerator=('<ctrl><shift>x') close_file.connect('clicked',self.closeFile) toolbox.toolbar.insert(close_file,3) #delete button delete_file=ToolButton('dialog-cancel') delete_file.set_tooltip('Delete File') delete_file.props.accelerator=('del') delete_file.connect('clicked',self.deleteFile) toolbox.toolbar.insert(delete_file,4) separator = Gtk.SeparatorToolItem() separator.show() toolbox.toolbar.insert(separator, 5) #save file button saveBtnImage = Gtk.Image() saveBtnImage.set_from_file("%s/icons/oopsy_save_as.svg" % os.getcwd()) save_file=ToolButton('gtk-save') save_file.set_icon_widget(saveBtnImage) save_file.set_tooltip(_('Save File')) save_file.props.accelerator=('<ctrl>s') save_file.connect('clicked',self.saveFile,self.basePath) toolbox.toolbar.insert(save_file,6) #compile button compile_button=ToolButton('view-source') compile_button.set_tooltip(_('Compile')) compile_button.props.accelerator=('<ctrl>F6') compile_button.connect('clicked',self.compileFile,self.basePath) toolbox.toolbar.insert(compile_button,7) #run button gobutton = ToolButton('media-playback-start') gobutton.props.accelerator = ('<ctrl>F5') #gobutton.set_icon_widget(goicon_bw) gobutton.set_tooltip(_("Run!")) gobutton.connect('clicked',self.executeFile,self.basePath) toolbox.toolbar.insert(gobutton,8) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) separator.show() toolbox.toolbar.insert(separator, 9) #stop button stop_button=StopButton(self) toolbox.toolbar.insert(stop_button,10) stop_button.show() self.set_toolbar_box(toolbox) act_path = activity.get_bundle_path() print "BUNDLE_PAth:",act_path self.loadExplorer(self.basePath) self.show_all()
def __init__(self, handle): activity.Activity.__init__(self, handle, True) self.basePath = activity.get_bundle_path() scroll = Gtk.ScrolledWindow() scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER) #get container self.canvasHolder = TabbedCanvas() self.canvasHolder.basePath = self.basePath #add tabControl to scrolled window scroll.add_with_viewport(self.canvasHolder) self.set_canvas(scroll) #add toolbox toolbox = ToolbarBox(self) activity_button = ActivityButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() separator = Gtk.SeparatorToolItem() separator.show() toolbox.toolbar.insert(separator, 1) #new file button new_file = ToolButton('list-add') new_file.set_tooltip(_('New File')) new_file.props.accelerator = ('<ctrl><shift>n') new_file.connect('clicked', self.newFile) toolbox.toolbar.insert(new_file, 2) new_file.show() #close file button close_file = ToolButton('list-remove') close_file.set_tooltip(_('Close File')) close_file.props.accelerator = ('<ctrl><shift>x') close_file.connect('clicked', self.closeFile) toolbox.toolbar.insert(close_file, 3) #delete button delete_file = ToolButton('dialog-cancel') delete_file.set_tooltip('Delete File') delete_file.props.accelerator = ('del') delete_file.connect('clicked', self.deleteFile) toolbox.toolbar.insert(delete_file, 4) separator = Gtk.SeparatorToolItem() separator.show() toolbox.toolbar.insert(separator, 5) #save file button saveBtnImage = Gtk.Image() saveBtnImage.set_from_file("%s/icons/oopsy_save_as.svg" % os.getcwd()) save_file = ToolButton('gtk-save') save_file.set_icon_widget(saveBtnImage) save_file.set_tooltip(_('Save File')) save_file.props.accelerator = ('<ctrl>s') save_file.connect('clicked', self.saveFile, self.basePath) toolbox.toolbar.insert(save_file, 6) #compile button compile_button = ToolButton('view-source') compile_button.set_tooltip(_('Compile')) compile_button.props.accelerator = ('<ctrl>F6') compile_button.connect('clicked', self.compileFile, self.basePath) toolbox.toolbar.insert(compile_button, 7) #run button gobutton = ToolButton('media-playback-start') gobutton.props.accelerator = ('<ctrl>F5') #gobutton.set_icon_widget(goicon_bw) gobutton.set_tooltip(_("Run!")) gobutton.connect('clicked', self.executeFile, self.basePath) toolbox.toolbar.insert(gobutton, 8) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) separator.show() toolbox.toolbar.insert(separator, 9) #stop button stop_button = StopButton(self) toolbox.toolbar.insert(stop_button, 10) stop_button.show() self.set_toolbar_box(toolbox) act_path = activity.get_bundle_path() print "BUNDLE_PAth:", act_path self.loadExplorer(self.basePath) self.show_all()
class MessageBox(Gtk.HBox): def __init__(self, **kwargs): GObject.GObject.__init__(self, **kwargs) self._radius = style.zoom(20) self.border_color = style.Color("#0000FF") self.background_color = style.Color("#FFFF00") self.modify_bg(0, self.background_color.get_gdk_color()) self.set_resize_mode(Gtk.ResizeMode.PARENT) self.connect("draw", self.__draw_cb) self.connect("add", self.__add_cb) close_icon = Icon(icon_name = 'entry-stop') close_icon.props.pixel_size = style.zoom(20) drag_icon = Icon(icon_name = 'hand1') drag_icon.props.pixel_size = style.zoom(20) self.drag_button = Gtk.Button() #self.drag_button.set_icon_widget(drag_icon) self.drag_button.set_image(drag_icon) drag_icon.show() self.drag_button.add_events(Gdk.EventMask.POINTER_MOTION_HINT_MASK | \ Gdk.EventMask.POINTER_MOTION_MASK) self.drag_button.connect("motion_notify_event", self.__motion_notify_cb) self.drag_button.connect("enter_notify_event", self.__enter_notify_cb) self.drag_button.connect("button-press-event", self._button_pressed) self.drag_button.connect("button-release-event", self._button_released) self.close_button = ToolButton(icon_name='entry-stop') self.close_button.set_icon_widget(close_icon) close_icon.show() self.close_button.connect("clicked", self._close_box) self.pack_end(self.close_button, False, False, 0) self.pack_start(self.drag_button, False, False, style.zoom(20)) def __motion_notify_cb(self, widget, event): if event.get_state() & Gdk.ModifierType.BUTTON1_MASK: x, y = event.x, event.y ev = widget.get_parent().get_parent() fixed = ev.get_parent() self.lx = self.x + x - self.sx self.ly = self.y + y - self.sy fixed.move(ev, self.lx, self.ly) self.x, self.y = self.lx, self.ly def __enter_notify_cb(self, widget, event): win = widget.get_window() hand_cursor = Gdk.Cursor.new(Gdk.CursorType.HAND2) win.set_cursor(hand_cursor) def _button_pressed(self, widget, event): self.sx = event.x self.sy = event.y def _button_released(self, widget, event): self.x = self.lx self.y = self.ly def _close_box(self, button): self.get_parent().remove(self) def __add_cb(self, widget, params): child.set_border_width(style.zoom(5)) def __draw_cb(self, widget, cr): rect = self.get_allocation() x = rect.x y = rect.y width = rect.width - BORDER_DEFAULT height = rect.height - BORDER_DEFAULT logging.debug("final x = " + str(self.x + rect.width) + "screen width = " + str(Gdk.Screen.width())) diff1 = self.x + rect.width - int(Gdk.Screen.width()) diff2 = self.y + rect.height - int(Gdk.Screen.height()) if diff1 >= 0 or diff2 >= 0: ev = self.get_parent() fixed = ev.get_parent() self.x = random.randint(self.panel_width, int(Gdk.Screen.width()) - rect.width - self.panel_width) self.y = random.randint(self.panel_width, int(Gdk.Screen.width()) - rect.height - self.panel_width) fixed.move(ev, self.x, self.y) cr.move_to(x, y) cr.arc(x + width - self._radius, y + self._radius, self._radius, math.pi * 1.5, math.pi * 2) cr.arc(x + width - self._radius, y + height - self._radius, self._radius, 0, math.pi * 0.5) cr.arc(x + self._radius, y + height - self._radius, self._radius, math.pi * 0.5, math.pi) cr.arc(x + self._radius, y + self._radius, self._radius, math.pi, math.pi * 1.5) cr.close_path() if self.background_color is not None: r, g, b, __ = self.background_color.get_rgba() cr.set_source_rgb(r, g, b) cr.fill_preserve() if self.border_color is not None: r, g, b, __ = self.border_color.get_rgba() cr.set_source_rgb(r, g, b) cr.set_line_width(BORDER_DEFAULT) cr.stroke() return False
class GameToolbar(Gtk.Toolbar): __gtype_name__ = 'GameToolbar' __gsignals__ = { 'game-restart': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, []), 'ai-activated': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, []), 'ai-deactivated': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, []), 'game-board-size': ( GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, [GObject.TYPE_INT]), } def __init__(self, activity): Gtk.Toolbar.__init__(self) self.activity = activity # Reset Button restart_icon = join(dirname(__file__), 'images', 'gtk-refresh.svg') restart_image = Gtk.Image() restart_image.set_from_file(restart_icon) self._restart_button = ToolButton() self._restart_button.set_icon_widget(restart_image) self._restart_button.connect('clicked', self._game_restart_cb) self._restart_button.set_tooltip(_('Restart Game')) self.insert(self._restart_button, -1) self._restart_button.show() # Separator separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.insert(separator, -1) self._add_widget(Gtk.Label(_('Board size') + ': ')) # Change size combobox self._size_combo = ToolComboBox() self._sizes = ['19 X 19', '13 X 13', '9 X 9'] for i, f in enumerate(self._sizes): self._size_combo.combo.append_item(i, f) self._size_combo.combo.connect('changed', self._game_size_cb) self._add_widget(self._size_combo) self._size_combo.combo.set_active(0) # Separator separator = Gtk.SeparatorToolItem() separator.set_draw(True) self.insert(separator, -1) # Artificial Intelligence Button self._ai_button = Gtk.ToggleToolButton() if search_for_gnugo(): self._ai_button.connect('toggled', self._ai_toggled_cb) self._ai_button.set_label(_('Play against PlayGo!')) else: self._ai_button.set_label( _('You need to install gnugo to play against PlayGo')) self._ai_button.set_sensitive(False) self.insert(self._ai_button, -1) self._ai_button.show() def _add_widget(self, widget, expand=False): tool_item = Gtk.ToolItem() tool_item.set_expand(expand) tool_item.add(widget) widget.show() self.insert(tool_item, -1) tool_item.show() def _game_restart_cb(self, widget): self._size_combo.set_sensitive(True) self.emit('game-restart') def grey_out_restart(self): self._restart_button.set_sensitive(False) def _game_size_cb(self, widget): game_size = int(self._sizes[self._size_combo.combo.get_active()][:2]) self.emit('game-board-size', game_size) def grey_out_size_change(self): self._size_combo.set_sensitive(False) def update_toolbar(self, widget, data, grid): size = data.get('size') self._size_combo.combo.handler_block(self.size_handle_id) size_index = self._sizes.index(size + ' X ' + size) self._size_combo.combo.set_active(int(size_index)) self._size_combo.combo.handler_unblock(self.size_handle_id) def _ai_toggled_cb(self, widget): if widget.get_active(): self.emit('ai-activated') else: self.emit('ai-deactivated') def grey_out_ai(self): self._ai_button.set_sensitive(False) def set_ai_button_state(self, value): self._ai_button.set_active(value)
class Controls(GObject.GObject): """Class to create the Control (play, back, forward, add, remove, etc) toolbar""" SCALE_UPDATE_INTERVAL = 1000 SCALE_DURATION_TEXT = 100 RESEEK_TIMEOUT = 250 # ms def __init__(self, activity, main_toolbar, secondary_toolbar): GObject.GObject.__init__(self) self.activity = activity self.toolbar = main_toolbar self.secondary_toolbar = secondary_toolbar self._scale_update_id = -1 self._scale_value_changed_id = -1 self._scale_reseek_timeout_id = -1 self.open_button = ToolButton('list-add') self.open_button.set_tooltip(_('Add track')) self.open_button.show() self.open_button.connect('clicked', self.__open_button_clicked_cb) self.toolbar.insert(self.open_button, -1) erase_playlist_entry_btn = ToolButton(icon_name='list-remove') erase_playlist_entry_btn.set_tooltip(_('Remove track')) erase_playlist_entry_btn.connect( 'clicked', self.__erase_playlist_entry_clicked_cb) self.toolbar.insert(erase_playlist_entry_btn, -1) self._spacer = Gtk.SeparatorToolItem() self._spacer.props.draw = True self._spacer.set_expand(False) self.toolbar.insert(self._spacer, -1) self._spacer.show() self.prev_button = ToolButton('player_rew') self.prev_button.set_tooltip(_('Previous')) self.prev_button.props.accelerator = 'Up' self.prev_button.show() self.prev_button.connect('clicked', self.__prev_button_clicked_cb) self.toolbar.insert(self.prev_button, -1) self.pause_image = Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PAUSE, Gtk.IconSize.BUTTON) self.pause_image.show() self.play_image = Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PLAY, Gtk.IconSize.BUTTON) self.play_image.show() self.button = ToolButton('media-playback-start') self.button.set_tooltip(_('Play or Pause')) self.button.set_icon_widget(self.play_image) self.button.props.accelerator = 'space' self.button.set_property('can-default', True) self.button.show() self.button.connect('clicked', self._button_clicked_cb) self.toolbar.insert(self.button, -1) self.next_button = ToolButton('player_fwd') self.next_button.set_tooltip(_('Next')) self.next_button.props.accelerator = 'Down' self.next_button.show() self.next_button.connect('clicked', self.__next_button_clicked_cb) self.toolbar.insert(self.next_button, -1) self._current_time = Gtk.ToolItem() self.current_time_label = Gtk.Label(label='') self._current_time.add(self.current_time_label) self._current_time.show() self.toolbar.insert(self._current_time, -1) self.adjustment = Gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0) self.hscale = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL, adjustment=self.adjustment) self.hscale.set_draw_value(False) # FIXME: this seems to be deprecated # self.hscale.set_update_policy(Gtk.UPDATE_CONTINUOUS) logging.debug("FIXME: AttributeError: 'Scale' object has no " "attribute 'set_update_policy'") self.hscale.connect('button-press-event', self.__scale_button_press_cb) self.hscale.connect('button-release-event', self.__scale_button_release_cb) self.scale_item = Gtk.ToolItem() self.scale_item.set_expand(True) self.scale_item.add(self.hscale) self.toolbar.insert(self.scale_item, -1) self._total_time = Gtk.ToolItem() self.total_time_label = Gtk.Label(label='') self._total_time.add(self.total_time_label) self._total_time.show() self.toolbar.insert(self._total_time, -1) self.activity.connect('playlist-finished', self.__playlist_finished_cb) self.activity.player.connect('play', self.__player_play) def update_layout(self, landscape=True): if landscape: self._remove_controls(self.secondary_toolbar) self._add_controls(self.toolbar) else: self._remove_controls(self.toolbar) self._add_controls(self.secondary_toolbar) self._spacer.hide() def _remove_controls(self, toolbar): for control in [ self._spacer, self.prev_button, self.button, self.next_button, self._current_time, self.scale_item, self._total_time ]: if control in toolbar: toolbar.remove(control) def _add_controls(self, toolbar): for control in [ self._spacer, self.prev_button, self.button, self.next_button, self._current_time, self.scale_item, self._total_time ]: if control not in toolbar: toolbar.insert(control, -1) control.show() def __player_play(self, widget): if self._scale_update_id == -1: self._scale_update_id = GObject.timeout_add( self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) # We need to wait for GstPlayer to load the stream's duration GObject.timeout_add(self.SCALE_DURATION_TEXT, self.__set_scale_duration) self.set_enabled() self.set_button_pause() def __set_scale_duration(self): success, self.p_position, self.p_duration = \ self.activity.player.query_position() if success and self.p_duration != Gst.CLOCK_TIME_NONE: seconds = self.p_duration * 10**-9 time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60)) self.total_time_label.set_text(time) # Once we set the total_time we don't need to change it # until a new stream is played return False else: # We don't have the stream's duration yet, we need to call # this method again return True def __open_button_clicked_cb(self, widget): self.show_picker_cb() def __erase_playlist_entry_clicked_cb(self, widget): self.activity.playlist_widget.delete_selected_items() self.check_if_next_prev() def show_picker_cb(self, button=None): # optional parameter button is used when called from activity.py # emptypanel big button jobject = None chooser = ObjectChooser(self.activity, what_filter=mime.GENERIC_TYPE_AUDIO) try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() if jobject and jobject.file_path: logging.info('Adding %s', jobject.file_path) self.activity.playlist_widget.load_file(jobject) self.check_if_next_prev() self.activity._switch_canvas(False) self.activity._view_toolbar._show_playlist.set_active(True) finally: if jobject is not None: jobject.destroy() def __prev_button_clicked_cb(self, widget): self.activity.songchange('prev') def __next_button_clicked_cb(self, widget): self.activity.songchange('next') def check_if_next_prev(self): current_playing = self.activity.playlist_widget.get_current_playing() if len(self.activity.playlist_widget._items) == 0: # There is no media in the playlist self.prev_button.set_sensitive(False) self.button.set_sensitive(False) self.next_button.set_sensitive(False) self.hscale.set_sensitive(False) self.activity._view_toolbar._fullscreen.set_sensitive(False) else: self.button.set_sensitive(True) self.hscale.set_sensitive(True) self.activity._view_toolbar._fullscreen.set_sensitive(True) if current_playing == 0: self.prev_button.set_sensitive(False) else: self.prev_button.set_sensitive(True) items = len(self.activity.playlist_widget._items) if current_playing == items - 1: self.next_button.set_sensitive(False) else: self.next_button.set_sensitive(True) def _button_clicked_cb(self, widget): self.set_enabled() if self.activity.player.is_playing(): self.activity.player.pause() self.set_button_play() GObject.source_remove(self._scale_update_id) self._scale_update_id = -1 else: if self.activity.player.error: self.set_disabled() else: if self.activity.player.player.props.current_uri is None: # There is no stream selected to be played # yet. Select the first one available = self.activity.playlist_widget.\ _items[0]['available'] if available: path = self.activity.playlist_widget._items[0]['path'] self.activity.playlist_widget.emit( 'play-index', 0, path) self.activity.playlist_widget.set_current_playing(0) else: self.activity.player.play() self.activity._switch_canvas(True) self._scale_update_id = GObject.timeout_add( self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) def set_button_play(self): self.button.set_icon_widget(self.play_image) def set_button_pause(self): self.button.set_icon_widget(self.pause_image) def set_disabled(self): self.button.set_sensitive(False) self.scale_item.set_sensitive(False) self.hscale.set_sensitive(False) def set_enabled(self): self.button.set_sensitive(True) self.scale_item.set_sensitive(True) self.hscale.set_sensitive(True) def __scale_button_press_cb(self, widget, event): self.button.set_sensitive(False) self._was_playing = self.activity.player.is_playing() if self._was_playing: self.activity.player.pause() # don't timeout-update position during seek if self._scale_update_id != -1: GObject.source_remove(self._scale_update_id) self._scale_update_id = -1 # make sure we get changed notifies if self._scale_value_changed_id == -1: self._scale_value_changed_id = self.hscale.connect( 'value-changed', self.__scale_value_changed_cb) def __scale_value_changed_cb(self, scale): if self._scale_reseek_timeout_id != -1: GObject.source_remove(self._scale_reseek_timeout_id) self._scale_reseek_timeout_id = GObject.timeout_add( self.RESEEK_TIMEOUT, self._reseek) def _reseek(self): self._scale_reseek_timeout_id = -1 location = long(self.activity.control.hscale.get_value() * self.p_duration / 100) # in ns self.activity.player.seek(location) # Allow for a preroll self.activity.player.get_state(timeout=50 * Gst.MSECOND) # 50 ms return False def __scale_button_release_cb(self, widget, event): if self._scale_reseek_timeout_id != -1: GObject.source_remove(self._scale_reseek_timeout_id) self._scale_reseek_timeout_id = -1 self._reseek() widget.disconnect(self._scale_value_changed_id) self._scale_value_changed_id = -1 self.button.set_sensitive(True) if self._was_playing: self.activity.player.play() if self._scale_update_id == -1: self._scale_update_id = GObject.timeout_add( self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) def __update_scale_cb(self): success, self.p_position, self.p_duration = \ self.activity.player.query_position() if success and self.p_position != Gst.CLOCK_TIME_NONE: value = self.p_position * 100.0 / self.p_duration self.adjustment.set_value(value) # Update the current time seconds = self.p_position * 10**-9 time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60)) self.current_time_label.set_text(time) return True def __playlist_finished_cb(self, widget): self.activity.player.stop() self.set_button_play() self.check_if_next_prev() self.adjustment.set_value(0) self.current_time_label.set_text('') self.total_time_label.set_text('')
class Controls(GObject.GObject): """Class to create the Control (play, back, forward, add, remove, etc) toolbar""" SCALE_UPDATE_INTERVAL = 1000 SCALE_DURATION_TEXT = 100 RESEEK_TIMEOUT = 250 # ms def __init__(self, activity, main_toolbar, secondary_toolbar): GObject.GObject.__init__(self) self.activity = activity self.toolbar = main_toolbar self.secondary_toolbar = secondary_toolbar self._scale_update_id = -1 self._scale_value_changed_id = -1 self._scale_reseek_timeout_id = -1 self.open_button = ToolButton('list-add') self.open_button.set_tooltip(_('Add track')) self.open_button.show() self.open_button.connect('clicked', self.__open_button_clicked_cb) self.toolbar.insert(self.open_button, -1) erase_playlist_entry_btn = ToolButton(icon_name='list-remove') erase_playlist_entry_btn.set_tooltip(_('Remove track')) erase_playlist_entry_btn.connect( 'clicked', self.__erase_playlist_entry_clicked_cb) self.toolbar.insert(erase_playlist_entry_btn, -1) self._spacer = Gtk.SeparatorToolItem() self._spacer.props.draw = True self._spacer.set_expand(False) self.toolbar.insert(self._spacer, -1) self._spacer.show() self.prev_button = ToolButton('player_rew') self.prev_button.set_tooltip(_('Previous')) self.prev_button.props.accelerator = 'Up' self.prev_button.show() self.prev_button.connect('clicked', self.__prev_button_clicked_cb) self.toolbar.insert(self.prev_button, -1) self.pause_image = Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PAUSE, Gtk.IconSize.BUTTON) self.pause_image.show() self.play_image = Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PLAY, Gtk.IconSize.BUTTON) self.play_image.show() self.button = ToolButton('media-playback-start') self.button.set_tooltip(_('Play or Pause')) self.button.set_icon_widget(self.play_image) self.button.props.accelerator = 'space' self.button.set_property('can-default', True) self.button.show() self.button.connect('clicked', self._button_clicked_cb) self.toolbar.insert(self.button, -1) self.next_button = ToolButton('player_fwd') self.next_button.set_tooltip(_('Next')) self.next_button.props.accelerator = 'Down' self.next_button.show() self.next_button.connect('clicked', self.__next_button_clicked_cb) self.toolbar.insert(self.next_button, -1) self._current_time = Gtk.ToolItem() self.current_time_label = Gtk.Label(label='') self._current_time.add(self.current_time_label) self._current_time.show() self.toolbar.insert(self._current_time, -1) self.adjustment = Gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0) self.hscale = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL, adjustment=self.adjustment) self.hscale.set_draw_value(False) # FIXME: this seems to be deprecated # self.hscale.set_update_policy(Gtk.UPDATE_CONTINUOUS) logging.debug("FIXME: AttributeError: 'Scale' object has no " "attribute 'set_update_policy'") self.hscale.connect('button-press-event', self.__scale_button_press_cb) self.hscale.connect('button-release-event', self.__scale_button_release_cb) self.scale_item = Gtk.ToolItem() self.scale_item.set_expand(True) self.scale_item.add(self.hscale) self.toolbar.insert(self.scale_item, -1) self._total_time = Gtk.ToolItem() self.total_time_label = Gtk.Label(label='') self._total_time.add(self.total_time_label) self._total_time.show() self.toolbar.insert(self._total_time, -1) self.activity.connect('playlist-finished', self.__playlist_finished_cb) self.activity.player.connect('play', self.__player_play) def update_layout(self, landscape=True): if landscape: self._remove_controls(self.secondary_toolbar) self._add_controls(self.toolbar) else: self._remove_controls(self.toolbar) self._add_controls(self.secondary_toolbar) self._spacer.hide() def _remove_controls(self, toolbar): for control in [self._spacer, self.prev_button, self.button, self.next_button, self._current_time, self.scale_item, self._total_time]: if control in toolbar: toolbar.remove(control) def _add_controls(self, toolbar): for control in [self._spacer, self.prev_button, self.button, self.next_button, self._current_time, self.scale_item, self._total_time]: if control not in toolbar: toolbar.insert(control, -1) control.show() def __player_play(self, widget): if self._scale_update_id == -1: self._scale_update_id = GObject.timeout_add( self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) # We need to wait for GstPlayer to load the stream's duration GObject.timeout_add(self.SCALE_DURATION_TEXT, self.__set_scale_duration) self.set_enabled() self.set_button_pause() def __set_scale_duration(self): success, self.p_position, self.p_duration = \ self.activity.player.query_position() if success and self.p_duration != Gst.CLOCK_TIME_NONE: seconds = self.p_duration * 10 ** -9 time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60)) self.total_time_label.set_text(time) # Once we set the total_time we don't need to change it # until a new stream is played return False else: # We don't have the stream's duration yet, we need to call # this method again return True def __open_button_clicked_cb(self, widget): self.show_picker_cb() def __erase_playlist_entry_clicked_cb(self, widget): self.activity.playlist_widget.delete_selected_items() self.check_if_next_prev() def show_picker_cb(self, button=None): # optional parameter button is used when called from activity.py # emptypanel big button jobject = None chooser = ObjectChooser(self.activity, what_filter=mime.GENERIC_TYPE_AUDIO) try: result = chooser.run() if result == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() if jobject and jobject.file_path: logging.info('Adding %s', jobject.file_path) self.activity.playlist_widget.load_file(jobject) self.check_if_next_prev() self.activity._switch_canvas(False) self.activity._view_toolbar._show_playlist.set_active( True) finally: if jobject is not None: jobject.destroy() def __prev_button_clicked_cb(self, widget): self.activity.songchange('prev') def __next_button_clicked_cb(self, widget): self.activity.songchange('next') def check_if_next_prev(self): current_playing = self.activity.playlist_widget.get_current_playing() if len(self.activity.playlist_widget._items) == 0: # There is no media in the playlist self.prev_button.set_sensitive(False) self.button.set_sensitive(False) self.next_button.set_sensitive(False) self.hscale.set_sensitive(False) self.activity._view_toolbar._fullscreen.set_sensitive(False) else: self.button.set_sensitive(True) self.hscale.set_sensitive(True) self.activity._view_toolbar._fullscreen.set_sensitive(True) if current_playing == 0: self.prev_button.set_sensitive(False) else: self.prev_button.set_sensitive(True) items = len(self.activity.playlist_widget._items) if current_playing == items - 1: self.next_button.set_sensitive(False) else: self.next_button.set_sensitive(True) def _button_clicked_cb(self, widget): self.set_enabled() if self.activity.player.is_playing(): self.activity.player.pause() self.set_button_play() GObject.source_remove(self._scale_update_id) self._scale_update_id = -1 else: if self.activity.player.error: self.set_disabled() else: if self.activity.player.player.props.current_uri is None: # There is no stream selected to be played # yet. Select the first one available = self.activity.playlist_widget.\ _items[0]['available'] if available: path = self.activity.playlist_widget._items[0]['path'] self.activity.playlist_widget.emit( 'play-index', 0, path) self.activity.playlist_widget.set_current_playing(0) else: self.activity.player.play() self.activity._switch_canvas(True) self._scale_update_id = GObject.timeout_add( self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) def set_button_play(self): self.button.set_icon_widget(self.play_image) def set_button_pause(self): self.button.set_icon_widget(self.pause_image) def set_disabled(self): self.button.set_sensitive(False) self.scale_item.set_sensitive(False) self.hscale.set_sensitive(False) def set_enabled(self): self.button.set_sensitive(True) self.scale_item.set_sensitive(True) self.hscale.set_sensitive(True) def __scale_button_press_cb(self, widget, event): self.button.set_sensitive(False) self._was_playing = self.activity.player.is_playing() if self._was_playing: self.activity.player.pause() # don't timeout-update position during seek if self._scale_update_id != -1: GObject.source_remove(self._scale_update_id) self._scale_update_id = -1 # make sure we get changed notifies if self._scale_value_changed_id == -1: self._scale_value_changed_id = self.hscale.connect( 'value-changed', self.__scale_value_changed_cb) def __scale_value_changed_cb(self, scale): if self._scale_reseek_timeout_id != -1: GObject.source_remove(self._scale_reseek_timeout_id) self._scale_reseek_timeout_id = GObject.timeout_add( self.RESEEK_TIMEOUT, self._reseek) def _reseek(self): self._scale_reseek_timeout_id = -1 location = long(self.activity.control.hscale.get_value() * self.p_duration / 100) # in ns self.activity.player.seek(location) # Allow for a preroll self.activity.player.get_state(timeout=50 * Gst.MSECOND) # 50 ms return False def __scale_button_release_cb(self, widget, event): if self._scale_reseek_timeout_id != -1: GObject.source_remove(self._scale_reseek_timeout_id) self._scale_reseek_timeout_id = -1 self._reseek() widget.disconnect(self._scale_value_changed_id) self._scale_value_changed_id = -1 self.button.set_sensitive(True) if self._was_playing: self.activity.player.play() if self._scale_update_id == -1: self._scale_update_id = GObject.timeout_add( self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) def __update_scale_cb(self): success, self.p_position, self.p_duration = \ self.activity.player.query_position() if success and self.p_position != Gst.CLOCK_TIME_NONE: value = self.p_position * 100.0 / self.p_duration self.adjustment.set_value(value) # Update the current time seconds = self.p_position * 10 ** -9 time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60)) self.current_time_label.set_text(time) return True def __playlist_finished_cb(self, widget): self.activity.player.stop() self.set_button_play() self.check_if_next_prev() self.adjustment.set_value(0) self.current_time_label.set_text('') self.total_time_label.set_text('')
def __init__(self, activity, top_level_toolbox): self._activity = activity self.toolbox = top_level_toolbox Terminal.__init__(self, self) #set up tool box/menu buttons activity_toolbar = self.toolbox.toolbar separator = Gtk.SeparatorToolItem() separator.set_draw(True) separator.show() activity_toolbar.insert(separator, 0) activity_go = ToolButton(stock_id=Gtk.STOCK_MEDIA_FORWARD) activity_go.set_icon_widget(None) activity_go.set_tooltip(_('Start Debugging')) activity_go.connect('clicked', self.project_run_cb) activity_go.add_accelerator('clicked', self.get_accelerator(), ord('O'), Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE) activity_go.show() activity_toolbar.insert(activity_go, 0) activity_copy_tb = ToolButton('edit-copy') activity_copy_tb.set_tooltip(_('Copy')) activity_copy_tb.connect('clicked', self._copy_cb) activity_toolbar.insert(activity_copy_tb, 3) activity_copy_tb.show() activity_paste_tb = ToolButton('edit-paste') activity_paste_tb.set_tooltip(_('Paste')) activity_paste_tb.connect('clicked', self._paste_cb) activity_paste_tb.add_accelerator('clicked', self.get_accelerator(), ord('V'), Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE) activity_toolbar.insert(activity_paste_tb, 4) activity_paste_tb.show() activity_tab_tb = ToolButton('list-add') activity_tab_tb.set_tooltip(_("Open New Tab")) activity_tab_tb.add_accelerator('clicked', self.get_accelerator(), ord('T'), Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE) activity_tab_tb.show() activity_tab_tb.connect('clicked', self._open_tab_cb) activity_toolbar.insert(activity_tab_tb, 5) activity_tab_delete_tv = ToolButton('list-remove') activity_tab_delete_tv.set_tooltip(_("Close Tab")) activity_tab_delete_tv.show() activity_tab_delete_tv.connect('clicked', self._close_tab_cb) activity_toolbar.insert(activity_tab_delete_tv, 6) activity_fullscreen_tb = ToolButton('view-fullscreen') activity_fullscreen_tb.set_tooltip(_("Fullscreen")) activity_fullscreen_tb.connect('clicked', self._activity._fullscreen_cb) activity_toolbar.insert(activity_fullscreen_tb, 7) activity_fullscreen_tb.hide()