Beispiel #1
0
    def __init__(self, calc):
        Gtk.Toolbar.__init__(self)

        copy_tool = ToolButton('edit-copy')
        copy_tool.set_tooltip(_('Copy'))
        copy_tool.set_accelerator(_('<ctrl>c'))
        copy_tool.connect('clicked', lambda x: calc.text_copy())
        self.insert(copy_tool, -1)

        menu_item = MenuItem(_('Cut'))

        try:
            menu_item.set_accelerator(_('<ctrl>x'))
        except AttributeError:
            pass

        menu_item.connect('activate', lambda x: calc.text_cut())
        menu_item.show()
        copy_tool.get_palette().menu.append(menu_item)

        self.insert(IconToolButton('edit-paste', _('Paste'),
                                   lambda x: calc.text_paste(),
                                   alt_html='Paste'), -1)

        self.show_all()
Beispiel #2
0
    def __init__(self, calc):
        Gtk.Toolbar.__init__(self)

        copy_tool = ToolButton('edit-copy')
        copy_tool.set_tooltip(_('Copy'))
        copy_tool.set_accelerator(_('<ctrl>c'))
        copy_tool.connect('clicked', lambda x: calc.text_copy())
        self.insert(copy_tool, -1)

        menu_item = MenuItem(_('Cut'))

        try:
            menu_item.set_accelerator(_('<ctrl>x'))
        except AttributeError:
            pass

        menu_item.connect('activate', lambda x: calc.text_cut())
        menu_item.show()
        copy_tool.get_palette().menu.append(menu_item)

        self.insert(
            IconToolButton('edit-paste',
                           _('Paste'),
                           lambda x: calc.text_paste(),
                           alt_html='Paste'), -1)

        self.show_all()
Beispiel #3
0
    def __init__(self, activity, **kwargs):
        GObject.GObject.__init__(self)

        description_button = ToolButton('edit-description')
        description_button.show()
        description_button.set_tooltip(_('Description'))
        self._palette = description_button.get_palette()

        description_box = Gtk.HBox()
        sw = Gtk.ScrolledWindow()
        sw.set_size_request(int(Gdk.Screen.width() / 2),
                            2 * style.GRID_CELL_SIZE)
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        self._text_view = Gtk.TextView()
        self._text_view.set_left_margin(style.DEFAULT_PADDING)
        self._text_view.set_right_margin(style.DEFAULT_PADDING)
        text_buffer = Gtk.TextBuffer()
        if 'description' in activity.metadata:
            text_buffer.set_text(activity.metadata['description'])
        self._text_view.set_buffer(text_buffer)
        self._text_view.connect('focus-out-event',
                               self.__description_changed_cb, activity)
        sw.add(self._text_view)
        description_box.pack_start(sw, False, True, 0)
        self._palette.set_content(description_box)
        description_box.show_all()

        self.add(description_button)
        description_button.connect('clicked',
                                   self.__description_button_clicked_cb)

        activity.metadata.connect('updated', self.__jobject_updated_cb)
Beispiel #4
0
    def __init__(self, **kwargs):
        Gtk.ToolItem.__init__(self)

        help_button = ToolButton('toolbar-help')
        help_button.set_tooltip(_('Ayuda / ÑepYsyrõ'))
        self.add(help_button)

        self._palette = help_button.get_palette()

        sw = Gtk.ScrolledWindow()
        sw.set_size_request(int(Gdk.Screen.width() / 2.8), 100)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        self._max_text_width = int(Gdk.Screen.width() / 3) - 600
        self._vbox = Gtk.Box()
        self._vbox.set_orientation(Gtk.Orientation.VERTICAL)
        self._vbox.set_homogeneous(False)
        self._vbox.set_border_width(10)

        hbox = Gtk.Box()
        hbox.pack_start(self._vbox, False, True, 0)

        sw.add_with_viewport(hbox)

        self._palette.set_content(sw)
        sw.show_all()

        help_button.connect('clicked', self.__help_button_clicked_cb)
Beispiel #5
0
    def __init__(self, **kwargs):
        GObject.GObject.__init__(self)

        help_button = ToolButton("toolbar-help")
        help_button.set_tooltip(
            _("What should you know before using Solar System?"))
        self.add(help_button)

        self._palette = help_button.get_palette()

        sw = Gtk.ScrolledWindow()
        sw.set_size_request(int(Gdk.Screen.width() / 2.8), 310)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        self._max_text_width = int(Gdk.Screen.width() / 3) - 600
        self._vbox = Gtk.Box()
        self._vbox.set_orientation(Gtk.Orientation.VERTICAL)
        self._vbox.set_homogeneous(False)
        self._vbox.set_border_width(10)

        hbox = Gtk.Box()
        hbox.pack_start(self._vbox, False, True, 0)

        sw.add_with_viewport(hbox)

        self._palette.set_content(sw)
        sw.show_all()

        help_button.connect('clicked', self.__help_button_clicked_cb)
    def __init__(self, **kwargs):
        GObject.GObject.__init__(self)

        help_button = ToolButton('toolbar-help')
        help_button.set_tooltip(_('Help'))
        self.add(help_button)

        self._palette = help_button.get_palette()

        sw = Gtk.ScrolledWindow()
        sw.set_size_request(int(Gdk.Screen.width() / 2.8),
            Gdk.Screen.height() - style.GRID_CELL_SIZE * 3)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        self._max_text_width = int(Gdk.Screen.width() / 3) - 600
        self._vbox = Gtk.Box()
        self._vbox.set_orientation(Gtk.Orientation.VERTICAL)
        self._vbox.set_homogeneous(False)
        self._vbox.set_border_width(10)

        hbox = Gtk.Box()
        hbox.pack_start(self._vbox, False, True, 0)

        sw.add_with_viewport(hbox)

        self._palette.set_content(sw)
        sw.show_all()

        help_button.connect('clicked', self.__help_button_clicked_cb)
    def __init__(self, activity, **kwargs):
        Gtk.ToolItem.__init__(self)

        description_button = ToolButton('edit-description')
        description_button.show()
        description_button.set_tooltip(_('Description'))
        description_button.palette_invoker.props.toggle_palette = True
        description_button.props.hide_tooltip_on_click = False
        self._palette = description_button.get_palette()

        description_box = PaletteMenuBox()
        sw = Gtk.ScrolledWindow()
        sw.set_size_request(int(Gdk.Screen.width() / 2),
                            2 * style.GRID_CELL_SIZE)
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        self._text_view = Gtk.TextView()
        self._text_view.set_left_margin(style.DEFAULT_PADDING)
        self._text_view.set_right_margin(style.DEFAULT_PADDING)
        self._text_view.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
        text_buffer = Gtk.TextBuffer()
        if 'description' in activity.metadata:
            text_buffer.set_text(activity.metadata['description'])
        self._text_view.set_buffer(text_buffer)
        self._text_view.connect('focus-out-event',
                               self.__description_changed_cb, activity)
        sw.add(self._text_view)
        description_box.append_item(sw, vertical_padding=0)
        self._palette.set_content(description_box)
        description_box.show_all()

        self.add(description_button)

        activity.metadata.connect('updated', self.__jobject_updated_cb)
Beispiel #8
0
    def __init__(self, **kwargs):
        GObject.GObject.__init__(self)

        help_button = ToolButton('toolbar-help')
        help_button.set_tooltip(_('Help'))
        self.add(help_button)

        self._palette = help_button.get_palette()

        sw = Gtk.ScrolledWindow()
        sw.set_size_request(int(Gdk.Screen.width() / 2.8),
            Gdk.Screen.height() - style.GRID_CELL_SIZE * 3)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        self._max_text_width = int(Gdk.Screen.width() / 3) - 600
        self._vbox = Gtk.Box()
        self._vbox.set_orientation(Gtk.Orientation.VERTICAL)
        self._vbox.set_homogeneous(False)

        sw.add_with_viewport(self._vbox)

        self._palette.set_content(sw)
        sw.show_all()

        help_button.connect('clicked', self.__help_button_clicked_cb)
    def __init__(self, activity):
        self._activity = activity
        self._current_palette = 'turtle'

        Gtk.ToolItem.__init__(self)

        help_button = ToolButton('help-toolbar')
        help_button.set_tooltip(_('Help'))
        self.add(help_button)
        help_button.show()

        self._palette = help_button.get_palette()

        help_button.connect('clicked', self.__help_button_clicked_cb)
Beispiel #10
0
    def _create_back_button(self):
        back = ToolButton('go-previous-paired')
        back.set_tooltip(_('Back'))
        back.props.sensitive = False
        palette = back.get_palette()

        previous_page = MenuItem(text_label=_("Previous page"))
        previous_page.show()
        previous_bookmark = MenuItem(text_label=_("Previous bookmark"))
        previous_bookmark.show()
        palette.menu.append(previous_page)
        palette.menu.append(previous_bookmark)

        back.connect('clicked', self.__go_back_cb)
        previous_page.connect('activate', self.__go_back_page_cb)
        previous_bookmark.connect('activate', self.__prev_bookmark_activate_cb)
        return back
Beispiel #11
0
    def _create_forward_button(self):
        forward = ToolButton('go-next-paired')
        forward.set_tooltip(_('Forward'))
        forward.props.sensitive = False
        palette = forward.get_palette()

        next_page = MenuItem(text_label=_("Next page"))
        next_page.show()
        next_bookmark = MenuItem(text_label=_("Next bookmark"))
        next_bookmark.show()

        palette.menu.append(next_page)
        palette.menu.append(next_bookmark)

        forward.connect('clicked', self.__go_forward_cb)
        next_page.connect('activate', self.__go_forward_page_cb)
        next_bookmark.connect('activate', self.__next_bookmark_activate_cb)
        return forward
Beispiel #12
0
    def __init__(self, handle):
        ''' Initiate activity. '''
        super(AbacusActivity, self).__init__(handle)

        self._setting_up = True
        self.bead_colors = profile.get_color().to_string().split(',')

        # no sharing
        self.max_participants = 1

        self.sep = []
        self.abacus_toolbar = Gtk.Toolbar()
        custom_toolbar = Gtk.Toolbar()
        edit_toolbar = Gtk.Toolbar()

        toolbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        toolbox.toolbar.insert(activity_button, 0)
        activity_button.show()

        edit_toolbar_button = ToolbarButton(label=_('Edit'),
                                            page=edit_toolbar,
                                            icon_name='toolbar-edit')
        edit_toolbar_button.show()
        toolbox.toolbar.insert(edit_toolbar_button, -1)
        edit_toolbar_button.show()

        self.abacus_toolbar_button = ToolbarButton(
            page=self.abacus_toolbar,
            icon_name='abacus-list')
        self.abacus_toolbar.show()
        toolbox.toolbar.insert(self.abacus_toolbar_button, -1)
        self.abacus_toolbar_button.show()

        self.custom_toolbar_button = ToolbarButton(
            page=custom_toolbar,
            icon_name='view-source')
        custom_toolbar.show()
        toolbox.toolbar.insert(self.custom_toolbar_button, -1)
        self.custom_toolbar_button.show()

        separator_factory(toolbox.toolbar, False, True)

        button_factory('edit-delete', toolbox.toolbar,
                       self._reset_cb, tooltip=_('Reset'))

        separator_factory(toolbox.toolbar, False, True)

        self._label = label_factory(NAMES['suanpan'], toolbox.toolbar)

        separator_factory(toolbox.toolbar, True, False)

        stop_button = StopButton(self)
        stop_button.props.accelerator = _('<Ctrl>Q')
        toolbox.toolbar.insert(stop_button, -1)
        stop_button.show()

        self.set_toolbar_box(toolbox)
        toolbox.show()

        self.abacus_buttons = {}

        # Traditional
        self._add_abacus_button('decimal', None)
        self._add_abacus_button('soroban', self.abacus_buttons['decimal'])
        self._add_abacus_button('suanpan', self.abacus_buttons['decimal'])

        self.sep.append(separator_factory(self.abacus_toolbar))

        # Bases other than 10
        self._add_abacus_button('nepohualtzintzin',
                                self.abacus_buttons['decimal'])
        self._add_abacus_button('hexadecimal', self.abacus_buttons['decimal'])
        self._add_abacus_button('binary', self.abacus_buttons['decimal'])

        self.sep.append(separator_factory(self.abacus_toolbar))

        # Fractions
        self._add_abacus_button('schety', self.abacus_buttons['decimal'])
        # self._add_abacus_button('fraction', self.abacus_buttons['decimal'])
        self._add_abacus_button('caacupe', self.abacus_buttons['decimal'])

        self.sep.append(separator_factory(self.abacus_toolbar))

        # Non-traditional
        self._add_abacus_button('cuisenaire', self.abacus_buttons['decimal'])

        self.sep.append(separator_factory(self.abacus_toolbar))

        # Custom
        self._add_abacus_button('custom', self.abacus_buttons['decimal'])

        preferences_button = ToolButton('preferences-system')
        preferences_button.set_tooltip(_('Custom'))
        custom_toolbar.insert(preferences_button, -1)
        preferences_button.palette_invoker.props.toggle_palette = True
        preferences_button.palette_invoker.props.lock_palette = True
        preferences_button.props.hide_tooltip_on_click = False
        preferences_button.show()

        self._palette = preferences_button.get_palette()
        button_box = Gtk.VBox()
        # TRANS: Number of rods on the abacus
        self._rods_spin = add_spinner_and_label(
            15, 1, MAX_RODS, _('Rods:'), self._rods_spin_cb, button_box)
        # TRANS: Number of beads in the top section of the abacus
        self._top_spin = add_spinner_and_label(
            2, 0, MAX_TOP, _('Top:'), self._top_spin_cb, button_box)
        # TRANS: Number of beads in the bottom section of the abacus
        self._bottom_spin = add_spinner_and_label(
            5, 0, MAX_BOT, _('Bottom:'), self._bottom_spin_cb, button_box)
        # TRANS: Scale factor between bottom and top beads
        self._value_spin = add_spinner_and_label(
            5, 1, MAX_BOT + 1, _('Factor:'), self._value_spin_cb, button_box)
        # TRANS: Scale factor between rods
        self._base_spin = add_spinner_and_label(
            10, 1, (MAX_TOP + 1) * MAX_BOT, _('Base:'), self._base_spin_cb,
            button_box)
        hbox = Gtk.HBox()
        hbox.pack_start(button_box, True, True, style.DEFAULT_SPACING)
        hbox.show_all()
        self._palette.set_content(hbox)

        separator_factory(custom_toolbar, False, False)

        self.custom_maker = button_factory('new-abacus', custom_toolbar,
                                           self._custom_cb,
                                           tooltip=_('Custom'))

        button_factory('edit-copy', edit_toolbar, self._copy_cb,
                       tooltip=_('Copy'), accelerator='<Ctrl>c')
        button_factory('edit-paste', edit_toolbar, self._paste_cb,
                       tooltip=_('Paste'), accelerator='<Ctrl>v')

        # Create a canvas
        canvas = Gtk.DrawingArea()
        canvas.set_size_request(Gdk.Screen.width(),
                                Gdk.Screen.height())
        self.set_canvas(canvas)
        canvas.show()
        self.show_all()

        # Initialize the canvas
        self.abacus = Abacus(canvas, self)

        self._setting_up = False

        # Read the current mode from the Journal
        if 'rods' in self.metadata:
            self._rods_spin.set_value(int(self.metadata['rods']))
        if 'top' in self.metadata:
            self._top_spin.set_value(int(self.metadata['top']))
        if 'bottom' in self.metadata:
            self._bottom_spin.set_value(int(self.metadata['bottom']))
        if 'factor' in self.metadata:
            self._value_spin.set_value(int(self.metadata['factor']))
        if 'base' in self.metadata:
            self._base_spin.set_value(int(self.metadata['base']))
        if 'abacus' in self.metadata:
            if self.metadata['abacus'] in self.abacus_buttons:
                _logger.debug('restoring %s', self.metadata['abacus'])
                if self.metadata['abacus'] == 'custom':
                    self._custom_cb()
                self.abacus_buttons[self.metadata['abacus']].set_active(True)
            else:  # Default is Chinese
                self.abacus_buttons['suanpan'].set_active(True)

            if 'value' in self.metadata:
                _logger.debug('restoring value %s', self.metadata['value'])
                self.abacus.mode.set_value(self.metadata['value'])
                self.abacus.mode.label(self.abacus.generate_label())

        self.abacus.init()

        # Start with abacus toolbar expanded and suanpan as default
        self.abacus_toolbar_button.set_expanded(True)
    def __init__(self):
        super(PyApp, self).__init__()

        self.set_title('Palettes')
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)

        vbox = Gtk.VBox()

        toolbarbox = ToolbarBox()
        vbox.add(toolbarbox)

        toolbar = toolbarbox.toolbar

        color_button = ColorToolButton()
        toolbar.insert(color_button, -1)

        button = ToolButton('list-add')
        button.set_tooltip('Palette with widgets')
        toolbar.insert(button, -1)

        palette = button.get_palette()
        palette_box = Gtk.VBox()
        palette.set_content(palette_box)

        checkbutton1 = Gtk.CheckButton('Option 1')
        palette_box.pack_start(checkbutton1, False, False, 0)

        checkbutton2 = Gtk.CheckButton('Option 2')
        palette_box.pack_start(checkbutton2, False, False, 0)

        checkbutton3 = Gtk.CheckButton('Option 3')
        palette_box.pack_start(checkbutton3, False, False, 0)

        separator = Gtk.VSeparator()
        palette_box.pack_start(separator, False, False, 0)

        radio_button1 = Gtk.RadioButton('Option 1')
        palette_box.pack_start(radio_button1, False, False, 0)

        radio_button2 = Gtk.RadioButton('Option 2', group=radio_button1)
        palette_box.pack_start(radio_button2, False, False, 0)

        radio_button3 = Gtk.RadioButton('Option 3', group=radio_button1)
        palette_box.pack_start(radio_button3, False, False, 0)

        palette_box.show_all()

        button = ToolButton(icon_name='format-justify-fill')
        button.props.tooltip = 'Select list'
        button.props.hide_tooltip_on_click = False
        button.palette_invoker.props.toggle_palette = True
        toolbar.insert(button, -1)

        menu_box = PaletteMenuBox()
        button.props.palette.set_content(menu_box)
        menu_box.show()

        menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-fill')
        menu_box.append_item(menu_item)

        menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-center')
        menu_box.append_item(menu_item)

        menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-left')
        menu_box.append_item(menu_item)

        menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-right')
        menu_box.append_item(menu_item)

        self.add(vbox)
        self.show_all()

        self.connect('destroy', Gtk.main_quit)
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)
        self.set_title('FotoToon')

        self._max_participants = 1
        self.page = None

        toolbar_box = ToolbarBox()
        activity_button = ActivityToolbarButton(self)
        activity_toolbar = activity_button.page
        toolbar_box.toolbar.insert(activity_button, 0)

        edit_toolbar_btn = ToolbarButton()
        edit_toolbar = Gtk.Toolbar()
        edit_toolbar_btn.props.page = edit_toolbar
        edit_toolbar_btn.props.icon_name = 'toolbar-edit'
        edit_toolbar_btn.label = _('Edit')
        toolbar_box.toolbar.insert(edit_toolbar_btn, -1)

        view_toolbar_btn = ToolbarButton()
        view_toolbar = Gtk.Toolbar()
        view_toolbar_btn.props.page = view_toolbar
        view_toolbar_btn.props.icon_name = 'toolbar-view'
        view_toolbar_btn.label = _('View')
        toolbar_box.toolbar.insert(view_toolbar_btn, -1)

        slideview_btn = ToggleToolButton('slideshow')
        slideview_btn.set_tooltip(_('Slideshow'))
        slideview_btn.set_active(False)
        slideview_btn.connect('clicked', self._switch_view_mode, False)
        view_toolbar.insert(slideview_btn, -1)
        slideview_btn.show()

        slideview_timings_btn = ToggleToolButton('slideshow-stopwatch')
        slideview_timings_btn.set_tooltip(_('Slideshow with Timings'))
        slideview_timings_btn.set_active(False)
        slideview_timings_btn.connect('clicked', self._switch_view_mode, True)
        view_toolbar.insert(slideview_timings_btn, -1)
        slideview_timings_btn.show()

        time_button = ToolButton('stopwatch')
        time_button.set_tooltip(_('Set Image Duration in Slideshow (Seconds)'))
        view_toolbar.insert(time_button, -1)
        time_button.show()

        self._time_spin = Gtk.SpinButton.new_with_range(MIN_TIME, MAX_TIME, 1)
        self._time_spin.connect('value-changed', self.__time_spin_changed_cb)
        self._time_spin.props.value = DEFAULT_TIME
        self._time_spin.props.update_policy = \
            Gtk.SpinButtonUpdatePolicy.IF_VALID

        palette = time_button.get_palette()
        palette.connect('popup', self.__time_button_popup_cb)
        time_button.connect(
            'clicked', lambda *args:
            palette.popup(immediate=True, state=Palette.SECONDARY))

        alignment = Gtk.Alignment()
        alignment.set_padding(style.DEFAULT_PADDING, style.DEFAULT_PADDING,
                              style.DEFAULT_PADDING, style.DEFAULT_PADDING)
        alignment.add(self._time_spin)
        self._time_spin.show()
        palette.set_content(alignment)
        alignment.show()

        fullscreen_btn = ToolButton('view-fullscreen')
        fullscreen_btn.set_tooltip(_('Fullscreen'))
        fullscreen_btn.props.accelerator = '<Alt>Return'
        fullscreen_btn.connect('clicked', lambda w: self.fullscreen())
        view_toolbar.insert(fullscreen_btn, -1)
        fullscreen_btn.show()

        self.set_toolbar_box(toolbar_box)

        toolbar = toolbar_box.toolbar

        self.page = Page()

        self.globes_manager = GlobesManager(toolbar, edit_toolbar, self)

        # fonts
        self._text_button = ToolbarButton()
        self._text_button.props.page = TextToolbar(self.page)
        self._text_button.props.icon_name = 'format-text-size'
        self._text_button.props.label = _('Text')
        self._toolbar_box.toolbar.insert(self._text_button, -1)

        reorder_img_btn = ToolButton('thumbs-view')
        reorder_img_btn.set_icon_name('thumbs-view')
        reorder_img_btn.set_tooltip(_('Change image order'))
        reorder_img_btn.connect('clicked', self.__image_order_cb)
        edit_toolbar.insert(reorder_img_btn, -1)
        reorder_img_btn.show()

        bgchange = ToolButton(icon_name='contract-coordinates')
        bgchange.set_tooltip(_('Edit background image'))
        bgchange.connect('clicked', self.__bgchange_clicked_cb)
        edit_toolbar.insert(bgchange, -1)
        bgchange.show()

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)

        toolbar_box.toolbar.insert(separator, -1)

        stop = StopButton(self)
        toolbar_box.toolbar.insert(stop, -1)

        toolbar_box.show_all()

        # add export button

        separator_2 = Gtk.SeparatorToolItem()
        separator_2.show()
        activity_toolbar.insert(separator_2, -1)

        self.bt_save_as_image = ToolButton()
        self.bt_save_as_image.props.icon_name = 'save-as-image'
        self.bt_save_as_image.connect('clicked', self.write_image)
        self.bt_save_as_image.set_tooltip(_('Save as Image'))
        activity_toolbar.insert(self.bt_save_as_image, -1)
        self.bt_save_as_image.show()

        save_as_pdf = ToolButton()
        save_as_pdf.props.icon_name = 'save-as-pdf'
        save_as_pdf.connect('clicked', self._save_as_pdf)
        save_as_pdf.set_tooltip(_('Save as a Book (PDF)'))
        activity_toolbar.insert(save_as_pdf, -1)
        save_as_pdf.show()

        save_as_ogg = ToolButton()
        save_as_ogg.props.icon_name = 'save-as-ogg'
        save_as_ogg.connect('clicked', self.__save_as_ogg_cb)
        save_as_ogg.set_tooltip(_('Save as a Movie (OGG)'))
        activity_toolbar.insert(save_as_ogg, -1)
        save_as_ogg.show()

        activity_button.page.title.connect("focus-in-event", self.on_title)

        scrolled = Gtk.ScrolledWindow()
        # scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS)
        scrolled.add_with_viewport(self.page)
        scrolled.set_kinetic_scrolling(False)
        scrolled.show_all()

        self._slideview = SlideView(self)
        self._slideview.show_all()

        self._notebook = Gtk.Notebook()
        self._notebook.set_show_tabs(False)
        self._notebook.append_page(scrolled, None)
        self._notebook.append_page(self._slideview, None)
        self._notebook.show_all()

        if self._jobject.file_path is None or self._jobject.file_path == '':
            empty_widget = EmptyWidget()
            empty_widget.connect('choose-image', self.__add_image)
            self.set_canvas(empty_widget)
        else:
            self.set_canvas(self._notebook)

        self.show()
        self.metadata['mime_type'] = 'application/x-fototoon-activity'

        self.page.empty_page = handle.object_id is None
        self._key_press_signal_id = None
Beispiel #15
0
class InsertToolbar(Gtk.Toolbar):

    def __init__(self, abiword_canvas):
        GObject.GObject.__init__(self)

        self._abiword_canvas = abiword_canvas

        self._table_btn = ToolButton('create-table')
        self._table_btn.set_tooltip(_('Create table'))
        self.insert(self._table_btn, -1)
        self._grid_create = GridCreateWidget()
        self._grid_create.show()
        self._grid_create.connect('create-table', self._create_table_cb)
        palette = self._table_btn.get_palette()
        palette.set_content(self._grid_create)
        self._table_btn.connect('clicked', self._table_btn_clicked_cb)

        self._table_rows_after = ToolButton('row-insert')
        self._table_rows_after.set_tooltip(_('Insert Row'))
        self._table_rows_after_id = self._table_rows_after.connect(
            'clicked', self._table_rows_after_cb)
        self.insert(self._table_rows_after, -1)

        self._table_delete_rows = ToolButton('row-remove')
        self._table_delete_rows.set_tooltip(_('Delete Row'))
        self._table_delete_rows_id = self._table_delete_rows.connect(
            'clicked', self._table_delete_rows_cb)
        self.insert(self._table_delete_rows, -1)

        self._table_cols_after = ToolButton('column-insert')
        self._table_cols_after.set_tooltip(_('Insert Column'))
        self._table_cols_after_id = self._table_cols_after.connect(
            'clicked', self._table_cols_after_cb)
        self.insert(self._table_cols_after, -1)

        self._table_delete_cols = ToolButton('column-remove')
        self._table_delete_cols.set_tooltip(_('Delete Column'))
        self._table_delete_cols_id = self._table_delete_cols.connect(
            'clicked', self._table_delete_cols_cb)
        self.insert(self._table_delete_cols, -1)

        self.show_all()

        self._abiword_canvas.connect('table-state', self._isTable_cb)
        #self._abiword_canvas.connect('image-selected',
        #       self._image_selected_cb)

    def _table_btn_clicked_cb(self, button):
        button.get_palette().popup(True, button.get_palette().SECONDARY)

    def _create_table_cb(self, abi, rows, cols):
        self._abiword_canvas.insert_table(rows, cols)

    def _table_rows_after_cb(self, button):
        self._abiword_canvas.invoke_ex('insertRowsAfter', '', 0, 0)

    def _table_delete_rows_cb(self, button):
        self._abiword_canvas.invoke_ex('deleteRows', '', 0, 0)

    def _table_cols_after_cb(self, button):
        self._abiword_canvas.invoke_ex('insertColsAfter', '', 0, 0)

    def _table_delete_cols_cb(self, button):
        self._abiword_canvas.invoke_ex('deleteColumns', '', 0, 0)

    def _isTable_cb(self, abi, b):
        self._table_rows_after.set_sensitive(b)
        self._table_delete_rows.set_sensitive(b)
        self._table_cols_after.set_sensitive(b)
        self._table_delete_cols.set_sensitive(b)
Beispiel #16
0
class Toolbar(ToolbarBox):
    def __init__(self, activity):

        ToolbarBox.__init__(self)

        activity_button = ActivityToolbarButton(activity)
        self.toolbar.insert(activity_button, 0)
        activity_button.show()

        separator = Gtk.SeparatorToolItem()
        self.toolbar.insert(separator, -1)

        self.choose_button = RadioToolButton('view-list')
        self.choose_button.set_tooltip(_('Choose a Poll'))
        self.toolbar.insert(self.choose_button, -1)
        modes_group = self.choose_button

        self.create_button = RadioToolButton('new-poll')
        self.create_button.set_tooltip(_('Build a Poll'))
        self.toolbar.insert(self.create_button, -1)
        self.create_button.props.group = modes_group

        self.settings_button = ToolButton('preferences-system')
        self.settings_button.set_tooltip(_('Settings'))
        self.settings_button.palette_invoker.props.toggle_palette = True
        self.settings_button.palette_invoker.props.lock_palette = True
        self.settings_button.props.hide_tooltip_on_click = False

        palette = self.settings_button.get_palette()
        hbox = Gtk.HBox()
        self._options_palette = OptionsPalette(activity)
        hbox.pack_start(self._options_palette, True, True,
                        style.DEFAULT_SPACING)
        hbox.show_all()
        palette.set_content(hbox)
        self.toolbar.insert(self.settings_button, -1)

        self.toolbar.insert(Gtk.SeparatorToolItem(), -1)

        self.pie_chart_button = RadioToolButton('pie-chart')
        self.pie_chart_button.set_tooltip(_('Pie chart'))
        self.toolbar.insert(self.pie_chart_button, -1)
        charts_group = self.pie_chart_button

        self.vbar_chart_button = RadioToolButton('vbar-chart')
        self.vbar_chart_button.set_tooltip(_('Vertical bar chart'))
        self.toolbar.insert(self.vbar_chart_button, -1)
        self.vbar_chart_button.props.group = charts_group

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)
        self.toolbar.insert(separator, -1)
        separator.show()

        self.toolbar.insert(StopButton(activity), -1)

        # add the export buttons
        activity_button.page.insert(Gtk.SeparatorToolItem(), -1)

        self.export_data_bt = ToolButton('save-as-data')
        self.export_data_bt.props.tooltip = _('Export data')
        activity_button.page.insert(self.export_data_bt, -1)

        self.export_image_bt = ToolButton('save-as-image')
        self.export_image_bt.set_tooltip(_("Save as Image"))
        activity_button.page.insert(self.export_image_bt, -1)
        activity_button.page.show_all()

        self.show_all()

    def update_configs(self):
        self._options_palette.update_configs()
Beispiel #17
0
class PrimaryToolbar(ToolbarBase):
    __gtype_name__ = "PrimaryToolbar"

    __gsignals__ = {
        "add-link": (GObject.SignalFlags.RUN_FIRST, None, ([])),
        "go-home": (GObject.SignalFlags.RUN_FIRST, None, ([])),
        "set-home": (GObject.SignalFlags.RUN_FIRST, None, ([])),
        "reset-home": (GObject.SignalFlags.RUN_FIRST, None, ([])),
        "go-library": (GObject.SignalFlags.RUN_FIRST, None, ([])),
        "go-to-JSshell": (GObject.SignalFlags.RUN_FIRST, None, ([])),
        "get-shell-input": (GObject.SignalFlags.RUN_FIRST, None, ([])),
    }

    def __init__(self, tabbed_view, act):
        ToolbarBase.__init__(self)

        self._url_toolbar = UrlToolbar()

        self._activity = act

        self._tabbed_view = self._canvas = tabbed_view

        self._loading = False

        toolbar = self.toolbar
        activity_button = ActivityToolbarButton(self._activity)
        toolbar.insert(activity_button, 0)

        separator = Gtk.SeparatorToolItem()

        save_as_pdf = ToolButton("save-as-pdf")
        save_as_pdf.set_tooltip(_("Save page as pdf"))
        save_as_pdf.connect("clicked", self.save_as_pdf)

        activity_button.props.page.insert(separator, -1)
        activity_button.props.page.insert(save_as_pdf, -1)
        separator.show()
        save_as_pdf.show()

        self._go_home = ToolButton("go-home")
        self._go_home.set_tooltip(_("Home page"))
        self._go_home.connect("clicked", self._go_home_cb)
        # add a menu to save the home page
        menu_box = PaletteMenuBox()
        self._go_home.props.palette.set_content(menu_box)
        menu_item = PaletteMenuItem()
        menu_item.set_label(_("Select as initial page"))
        menu_item.connect("activate", self._set_home_cb)
        menu_box.append_item(menu_item)

        self._reset_home_menu = PaletteMenuItem()
        self._reset_home_menu.set_label(_("Reset initial page"))
        self._reset_home_menu.connect("activate", self._reset_home_cb)
        menu_box.append_item(self._reset_home_menu)

        if os.path.isfile(LIBRARY_PATH):
            library_menu = PaletteMenuItem()
            library_menu.set_label(_("Library"))
            library_menu.connect("activate", self._go_library_cb)
            menu_box.append_item(library_menu)

        menu_box.show_all()

        # verify if the home page is configured
        client = GConf.Client.get_default()
        self._reset_home_menu.set_visible(client.get_string(HOME_PAGE_GCONF_KEY) is not None)

        toolbar.insert(self._go_home, -1)
        self._go_home.show()

        self.entry = WebEntry()
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, "entry-stop")
        self.entry.connect("icon-press", self._stop_and_reload_cb)
        self.entry.connect("activate", self._entry_activate_cb)
        self.entry.connect("focus-in-event", self.__focus_in_event_cb)
        self.entry.connect("focus-out-event", self.__focus_out_event_cb)
        self.entry.connect("key-press-event", self.__key_press_event_cb)
        self.entry.connect("changed", self.__changed_cb)

        self._entry_item = Gtk.ToolItem()
        self._entry_item.set_expand(True)
        self._entry_item.add(self.entry)
        self.entry.show()

        toolbar.insert(self._entry_item, -1)

        self._entry_item.show()

        self._back = ToolButton("go-previous-paired")
        self._back.set_tooltip(_("Back"))
        self._back.props.sensitive = False
        self._back.connect("clicked", self._go_back_cb)
        toolbar.insert(self._back, -1)
        self._back.show()

        palette = self._back.get_palette()
        self._back_box_menu = Gtk.VBox()
        self._back_box_menu.show()
        palette.set_content(self._back_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._forward = ToolButton("go-next-paired")
        self._forward.set_tooltip(_("Forward"))
        self._forward.props.sensitive = False
        self._forward.connect("clicked", self._go_forward_cb)
        toolbar.insert(self._forward, -1)
        self._forward.show()

        palette = self._forward.get_palette()
        self._forward_box_menu = Gtk.VBox()
        self._forward_box_menu.show()
        palette.set_content(self._forward_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._link_add = ToolButton("emblem-favorite")
        self._link_add.set_tooltip(_("Bookmark"))
        self._link_add.connect("clicked", self._link_add_clicked_cb)
        toolbar.insert(self._link_add, -1)
        self._link_add.show()

        self._toolbar_separator = Gtk.SeparatorToolItem()
        self._toolbar_separator.props.draw = False
        self._toolbar_separator.set_expand(True)

        self._go_to_JSshell = ToolButton("go-to-JSshell")
        self._go_to_JSshell.set_tooltip(_("Go to Interactive Javascript Shell"))
        self._go_to_JSshell.connect("clicked", self._go_to_JSshell_cb)
        # adding a button for the Interactive Javascript shell
        toolbar.insert(self._go_to_JSshell, -1)
        self._go_to_JSshell.show()

        self._get_shell_input = ToolButton("get-shell-input")
        self._get_shell_input.set_tooltip(_("Get Interactive Javascript Shell Input"))
        self._get_shell_input.connect("clicked", self._get_shell_input_cb)
        # adding a button for the Interactive Javascript shell
        toolbar.insert(self._get_shell_input, -1)
        self._get_shell_input.show()

        stop_button = StopButton(self._activity)
        toolbar.insert(stop_button, -1)

        self._progress_listener = None
        self._browser = None

        self._loading_changed_hid = None
        self._progress_changed_hid = None
        self._session_history_changed_hid = None
        self._uri_changed_hid = None
        self._security_status_changed_hid = None

        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

        tabbed_view.connect_after("switch-page", self.__switch_page_cb)
        tabbed_view.connect_after("page-added", self.__page_added_cb)

        Gdk.Screen.get_default().connect("size-changed", self.__screen_size_changed_cb)

        self._configure_toolbar()

    def __key_press_event_cb(self, entry, event):
        self._tabbed_view.current_browser.loading_uri = entry.props.text

    def __switch_page_cb(self, tabbed_view, page, page_num):
        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

    def __page_added_cb(self, notebook, child, pagenum):
        self.entry._search_popdown()

    def _configure_toolbar(self, screen=None):
        # Adapt the toolbars for portrait or landscape mode.

        if screen is None:
            screen = Gdk.Screen.get_default()

        if screen.get_width() < screen.get_height():
            if self._entry_item in self._url_toolbar.toolbar.get_children():
                return

            self.toolbar.remove(self._entry_item)
            self._url_toolbar.toolbar.insert(self._entry_item, -1)

            separator_pos = len(self.toolbar.get_children()) - 1
            self.toolbar.insert(self._toolbar_separator, separator_pos)
            self._toolbar_separator.show()

            self.pack_end(self._url_toolbar, True, True, 0)
            self._url_toolbar.show()

        else:
            if self._entry_item in self.toolbar.get_children():
                return

            self.toolbar.remove(self._toolbar_separator)

            position = len(self.toolbar.get_children()) - 4
            self._url_toolbar.toolbar.remove(self._entry_item)
            self.toolbar.insert(self._entry_item, position)

            self._toolbar_separator.hide()
            self.remove(self._url_toolbar)

    def __screen_size_changed_cb(self, screen):
        self._configure_toolbar(screen)

    def _connect_to_browser(self, browser):
        if self._browser is not None:
            self._browser.disconnect(self._uri_changed_hid)
            self._browser.disconnect(self._progress_changed_hid)
            self._browser.disconnect(self._loading_changed_hid)
            self._browser.disconnect(self._security_status_changed_hid)

        self._browser = browser
        if not isinstance(self._browser, DummyBrowser):
            address = self._browser.props.uri or self._browser.loading_uri
        else:
            address = self._browser.props.uri
        self._set_address(address)
        self._set_progress(self._browser.props.progress)
        self._set_status(self._browser.props.load_status)
        self._set_security_status(self._browser.security_status)

        is_webkit_browser = isinstance(self._browser, Browser)
        self.entry.props.editable = is_webkit_browser

        self._uri_changed_hid = self._browser.connect("notify::uri", self.__uri_changed_cb)
        self._progress_changed_hid = self._browser.connect("notify::progress", self.__progress_changed_cb)
        self._loading_changed_hid = self._browser.connect("notify::load-status", self.__loading_changed_cb)
        self._security_status_changed_hid = self._browser.connect(
            "security-status-changed", self.__security_status_changed_cb
        )

        self._update_navigation_buttons()

    def __loading_changed_cb(self, widget, param):
        self._set_status(widget.get_load_status())

    def __security_status_changed_cb(self, widget):
        self._set_security_status(widget.security_status)

    def __progress_changed_cb(self, widget, param):
        self._set_progress(widget.get_progress())

    def _set_status(self, status):
        self._set_loading(status < WebKit.LoadStatus.FINISHED)

    def _set_security_status(self, security_status):
        # Display security status as a lock icon in the left side of
        # the URL entry.
        if security_status is None:
            self.entry.set_icon_from_pixbuf(iconentry.ICON_ENTRY_PRIMARY, None)
        elif security_status == Browser.SECURITY_STATUS_SECURE:
            self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, "channel-secure-symbolic")
        elif security_status == Browser.SECURITY_STATUS_INSECURE:
            self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, "channel-insecure-symbolic")

    def _set_progress(self, progress):
        if progress == 1.0:
            self.entry.set_progress_fraction(0.0)
        else:
            self.entry.set_progress_fraction(progress)

    def _set_address(self, uri):
        if uri is None:
            self.entry.props.address = ""
        else:
            self.entry.props.address = uri

    def __changed_cb(self, iconentry):
        # The WebEntry can be changed when we click on a link, then we
        # have to show the clear icon only if is the user who has
        # changed the entry
        if self.entry.has_focus():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_in_event_cb(self, entry, event):
        if not self._tabbed_view.is_current_page_pdf():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_out_event_cb(self, entry, event):
        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self._show_reload_icon()

    def _show_no_icon(self):
        self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY)

    def _show_stop_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, "entry-stop")

    def _show_reload_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, "entry-refresh")

    def _show_clear_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY, "entry-cancel")

    def _update_navigation_buttons(self):
        can_go_back = self._browser.can_go_back()
        self._back.props.sensitive = can_go_back

        can_go_forward = self._browser.can_go_forward()
        self._forward.props.sensitive = can_go_forward

        is_webkit_browser = isinstance(self._browser, Browser)
        self._link_add.props.sensitive = is_webkit_browser
        self._go_home.props.sensitive = is_webkit_browser
        if is_webkit_browser:
            self._reload_session_history()

    def _entry_activate_cb(self, entry):
        url = entry.props.text
        effective_url = self._tabbed_view.normalize_or_autosearch_url(url)
        self._browser.load_uri(effective_url)
        self._browser.loading_uri = effective_url
        self.entry.props.address = effective_url
        self._browser.grab_focus()

    def _go_home_cb(self, button):
        self.emit("go-home")

    def _go_library_cb(self, button):
        self.emit("go-library")

    def _set_home_cb(self, button):
        self._reset_home_menu.set_visible(True)
        self.emit("set-home")

    def _reset_home_cb(self, button):
        self._reset_home_menu.set_visible(False)
        self.emit("reset-home")

    def _go_to_JSshell_cb(self, button):
        self.emit("go-to-JSshell")

    def _get_shell_input_cb(self, button):
        self.emit("get-shell-input")

    def _go_back_cb(self, button):
        self._browser.go_back()

    def _go_forward_cb(self, button):
        self._browser.go_forward()

    def __uri_changed_cb(self, widget, param):
        self._set_address(widget.get_uri())
        self._update_navigation_buttons()
        filepicker.cleanup_temp_files()

    def _stop_and_reload_cb(self, entry, icon_pos, button):
        if entry.has_focus() and not self._tabbed_view.is_current_page_pdf():
            entry.set_text("")
        else:
            if self._loading:
                self._browser.stop_loading()
            else:
                self._browser.reload()

    def _set_loading(self, loading):
        self._loading = loading

        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self.set_sensitive(True)
                self._show_reload_icon()
            else:
                self.set_sensitive(False)
                self._show_no_icon()

    def _reload_session_history(self):
        back_forward_list = self._browser.get_back_forward_list()
        item_index = 0  # The index of the history item

        # Clear menus in palettes:
        for box_menu in (self._back_box_menu, self._forward_box_menu):
            for menu_item in box_menu.get_children():
                box_menu.remove(menu_item)

        def create_menu_item(history_item, item_index):
            """Create a MenuItem for the back or forward palettes."""
            title = history_item.get_title()
            if not isinstance(title, unicode):
                title = unicode(title, "utf-8")
            # This is a fix until the Sugar MenuItem is fixed:
            menu_item = PaletteMenuItem(text_label=title)
            menu_item.connect("activate", self._history_item_activated_cb, item_index)
            return menu_item

        back_list = back_forward_list.get_back_list_with_limit(_MAX_HISTORY_ENTRIES)
        back_list.reverse()
        for item in back_list:
            menu_item = create_menu_item(item, item_index)
            self._back_box_menu.pack_end(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

        # Increment the item index to count the current page:
        item_index += 1

        forward_list = back_forward_list.get_forward_list_with_limit(_MAX_HISTORY_ENTRIES)
        forward_list.reverse()
        for item in forward_list:
            menu_item = create_menu_item(item, item_index)
            self._forward_box_menu.pack_start(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

    def _history_item_activated_cb(self, menu_item, index):
        self._back.get_palette().popdown(immediate=True)
        self._forward.get_palette().popdown(immediate=True)
        self._browser.set_history_index(index)

    def _link_add_clicked_cb(self, button):
        self.emit("add-link")

    def save_as_pdf(self, widget):
        tmp_dir = os.path.join(self._activity.get_activity_root(), "tmp")
        fd, file_path = tempfile.mkstemp(dir=tmp_dir)
        os.close(fd)

        page = self._canvas.get_current_page()
        webview = self._canvas.get_children()[page].get_children()[0]

        operation = Gtk.PrintOperation.new()
        operation.set_export_filename(file_path)

        webview.get_main_frame().print_full(operation, Gtk.PrintOperationAction.EXPORT)

        client = GConf.Client.get_default()
        jobject = datastore.create()
        color = client.get_string("/desktop/sugar/user/color")
        try:
            jobject.metadata["title"] = _("Browse activity as PDF")
            jobject.metadata["icon-color"] = color
            jobject.metadata["mime_type"] = "application/pdf"
            jobject.file_path = file_path
            datastore.write(jobject)
        finally:
            self.__pdf_alert(jobject.object_id)
            jobject.destroy()
            del jobject

    def __pdf_alert(self, object_id):
        alert = Alert()
        alert.props.title = _("Page saved")
        alert.props.msg = _("The page has been saved as PDF to journal")

        alert.add_button(Gtk.ResponseType.APPLY, _("Show in Journal"), Icon(icon_name="zoom-activity"))
        alert.add_button(Gtk.ResponseType.OK, _("Ok"), Icon(icon_name="dialog-ok"))

        # Remove other alerts
        for alert in self._activity._alerts:
            self._activity.remove_alert(alert)

        self._activity.add_alert(alert)
        alert.connect("response", self.__pdf_response_alert, object_id)
        alert.show_all()

    def __pdf_response_alert(self, alert, response_id, object_id):

        if response_id is Gtk.ResponseType.APPLY:
            activity.show_object_in_journal(object_id)

        self._activity.remove_alert(alert)
class TextAttributesToolbar(Gtk.Toolbar):

    def __init__(self, main_area):

        Gtk.Toolbar.__init__(self)

        self._main_area = main_area
        self._font_list = ['ABC123', 'Sans', 'Serif', 'Monospace', 'Symbol']
        self._font_sizes = ['8', '9', '10', '11', '12', '14', '16', '20',
                            '22', '24', '26', '28', '36', '48', '72']

        self.font_button =  ToolButton('font-text')
        self.font_button.set_tooltip(_('Select font'))
        self.font_button.connect('clicked', self.__font_selection_cb)
        self.insert(self.font_button, -1)
        self._setup_font_palette()

        self.insert(Gtk.SeparatorToolItem(), -1)

        self.font_size_up = ToolButton('resize+')
        self.font_size_up.set_tooltip(_('Bigger'))
        self.font_size_up.connect('clicked', self.__font_sizes_cb, True)
        self.insert(self.font_size_up, -1)

        if len(self._main_area.selected) > 0:
            font_size = self._main_area.font_size

        else:
            font_size = utils.default_font_size

        self.size_label = Gtk.Label(str(font_size))
        self.size_label.show()
        toolitem = Gtk.ToolItem()
        toolitem.add(self.size_label)
        toolitem.show()
        self.insert(toolitem, -1)

        self.font_size_down = ToolButton('resize-')
        self.font_size_down.set_tooltip(_('Smaller'))
        self.font_size_down.connect('clicked', self.__font_sizes_cb, False)
        self.insert(self.font_size_down, -1)

        self.insert(Gtk.SeparatorToolItem(), -1)

        self.bold = ToolButton('bold-text')
        self.bold.set_tooltip(_('Bold'))
        self.bold.connect('clicked', self.__bold_cb)
        self.insert(self.bold, -1)

        self.italics = ToolButton('italics-text')
        self.italics.set_tooltip(_('Italics'))
        self.italics.connect('clicked', self.__italics_cb)
        self.insert(self.italics, -1)

        self.underline = ToolButton('underline-text')
        self.underline.set_tooltip(_('Underline'))
        self.underline.connect('clicked', self.__underline_cb)
        self.insert(self.underline, -1)

        foreground_color = ColorToolButton()
        foreground_color.set_title(_('Set font color'))
        foreground_color.connect('color-set', self.__foreground_color_cb)
        self.insert(foreground_color, -1)

        bakground_color = ColorToolButton()
        bakground_color.set_title(_('Set background color'))
        bakground_color.connect('color-set', self.__background_color_cb)
        bakground_color.set_color(Gdk.Color(65535, 65535, 65535))
        self.insert(bakground_color, -1)

        self.show_all()

    def __font_selection_cb(self, widget):
        if self._font_palette:
            if not self._font_palette.is_up():
                self._font_palette.popup(immediate=True,
                                    state=self._font_palette.SECONDARY)
            else:
                self._font_palette.popdown(immediate=True)
            return

    def _init_font_list(self):
        self._font_white_list = []
        self._font_white_list.extend(DEFAULT_FONTS)

        # check if there are a user configuration file
        if not os.path.exists(USER_FONTS_FILE_PATH):
            # verify if exists a file in /etc
            if os.path.exists(GLOBAL_FONTS_FILE_PATH):
                shutil.copy(GLOBAL_FONTS_FILE_PATH, USER_FONTS_FILE_PATH)

        if os.path.exists(USER_FONTS_FILE_PATH):
            # get the font names in the file to the white list
            fonts_file = open(USER_FONTS_FILE_PATH)
            # get the font names in the file to the white list
            for line in fonts_file:
                self._font_white_list.append(line.strip())
            # monitor changes in the file
            gio_fonts_file = Gio.File.new_for_path(USER_FONTS_FILE_PATH)
            self.monitor = gio_fonts_file.monitor_file(0, None)
            self.monitor.set_rate_limit(5000)
            self.monitor.connect('changed', self._reload_fonts)

    def _reload_fonts(self, monitor, gio_file, other_file, event):
        if event != Gio.FileMonitorEvent.CHANGES_DONE_HINT:
            return

        self._font_white_list = []
        self._font_white_list.extend(DEFAULT_FONTS)
        fonts_file = open(USER_FONTS_FILE_PATH)
        for line in fonts_file:
            self._font_white_list.append(line.strip())
        # update the menu
        for child in self._font_palette.menu.get_children():
            self._font_palette.menu.remove(child)
            child = None
        context = self.get_pango_context()
        tmp_list = []
        for family in context.list_families():
            name = family.get_name()
            if name in self._font_white_list:
                tmp_list.append(name)
        for font in sorted(tmp_list):
            menu_item = MyMenuItem(image=FontImage(font.replace(' ', '-')),
                                   text_label=font)
            menu_item.connect('activate', self.__font_selected_cb, font)
            self._font_palette.menu.append(menu_item)
            menu_item.show()

        return False

    def _setup_font_palette(self):
        self._init_font_list()
        context = self._main_area.pango_context
        for family in context.list_families():
            name = Pango.FontDescription(family.get_name()).to_string()
            if name not in self._font_list and \
                    name in self._font_white_list:
                self._font_list.append(name)

        self._font_palette = self.font_button.get_palette()
        for font in sorted(self._font_list):
            menu_item = MyMenuItem(image=FontImage(font.replace(' ', '-')),
                                   text_label=font)
            menu_item.connect('activate', self.__font_selected_cb, font)
            self._font_palette.menu.append(menu_item)
            menu_item.show()

    def __font_selected_cb(self, widget, font_name):
        if not hasattr(self._main_area, 'font_name'):
            return
        if len(self._main_area.selected) > 0:
            font_size = self._main_area.font_size
        else:
            font_size = utils.default_font_size
        self._main_area.set_font(font_name, font_size)
        self._main_area.font_name = font_name
        self._main_area.font_size = font_size

    def __attribute_values(self):
        thought = self._main_area.selected[0]
        return thought.attributes.copy()

    def __font_sizes_cb(self, button, increase):
        if not hasattr(self._main_area, 'font_size'):
            return
        if len(self._main_area.selected) < 1:
            return
        font_size = self._main_area.font_size
        if font_size in self._font_sizes:
            i = self._font_sizes.index(font_size)
            if increase:
                if i < len(self._font_sizes) - 2:
                    i += 1
            else:
                if i > 0:
                    i -= 1
        else:
            i = self._font_sizes.index(utils.default_font_size)

        font_size = self._font_sizes[i]
        self.size_label.set_text(str(font_size))
        self.font_size_down.set_sensitive(i != 0)
        self.font_size_up.set_sensitive(i < len(self._font_sizes) - 2)
        self._main_area.set_font(self._main_area.font_name, font_size)

    def __bold_cb(self, button):
        if len(self._main_area.selected) < 1:
            return
        value = not self.__attribute_values()["bold"]
        self._main_area.set_bold(value)

    def __italics_cb(self, button):
        if len(self._main_area.selected) < 1:
            return

        value = not self.__attribute_values()["italic"]
        self._main_area.set_italics(value)

    def __underline_cb(self, button):
        if len(self._main_area.selected) < 1:
            return
        value = not self.__attribute_values()["underline"]
        self._main_area.set_underline(value)

    def __foreground_color_cb(self, button):
        color = button.get_color()
        self._main_area.set_foreground_color(color)

    def __background_color_cb(self, button):
        color = button.get_color()
        self._parent._main_area.set_background_color(color)

    def change_active_font(self):
        # TODO: update the toolbar
        return
Beispiel #19
0
class ReadSDComics(activity.Activity):
    __gsignals__ = {
        'go-fullscreen': (GObject.SignalFlags.RUN_FIRST,
                          None,
                          ([]))
    }

    def __init__(self, handle):
        "The entry point to the Activity"
        activity.Activity.__init__(self, handle)

        self._object_id = handle.object_id
        self.zoom_image_to_fit = True
        self.total_pages = 0

        self.connect("draw", self.__draw_cb)
        self.connect("delete_event", self.delete_cb)
       
        if _NEW_TOOLBAR_SUPPORT:
            self.create_new_toolbar()
        else:
            self.create_old_toolbar()

        self.scrolled = Gtk.ScrolledWindow()
        self.scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        self.scrolled.props.shadow_type = Gtk.ShadowType.NONE
        self.image = Gtk.Image()
        self.eventbox = Gtk.EventBox()
        self.eventbox.add(self.image)
        self.image.show()
        self.eventbox.show()
        self.scrolled.add_with_viewport(self.eventbox)
        self.eventbox.set_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.BUTTON_PRESS_MASK)
        self.eventbox.set_can_focus(True)
        self.eventbox.connect("key_press_event", self.keypress_cb)
        self.eventbox.connect("button_press_event", self.buttonpress_cb)
        
        self._filechooser = Gtk.FileChooserWidget(
            action=Gtk.FileChooserAction.OPEN)
        filter = Gtk.FileFilter()
        filter.add_mime_type('application/zip')
        filter.add_mime_type('application/x-cbz')
        self._filechooser.set_filter(filter)
        self._filechooser.set_current_folder("/media")
        self.copy_button = Gtk.Button(_("Read Comic"))
        self.copy_button.connect('clicked',  self.select_comic_path)
        self.copy_button.show()
        self._filechooser.set_extra_widget(self.copy_button)
        preview = Gtk.Image()
        self._filechooser.set_preview_widget(preview)
        self._filechooser.connect("update-preview", 
                                  self.update_preview_cb, preview)

        vbox = Gtk.VBox()
        vbox.pack_start(self.scrolled, True, True, 0)
        vbox.pack_end(self._filechooser, True, True, 0)
        self.set_canvas(vbox)
        if self._object_id is None:
            self.scrolled.hide()
            self._filechooser.show()
        else:
            self.scrolled.show()
            self._filechooser.hide()
           
        vbox.show()

        self.page = 0
        self.saved_screen_width = 0
        self.eventbox.grab_focus()
        
        self.hidden_cursor = Gdk.Cursor.new(Gdk.CursorType.BLANK_CURSOR)
        self.cursor_visible = True

        self.link = None
        self._close_requested = False
        
    def select_comic_path(self,  widget,  data=None):
        filename = self._filechooser.get_filename()
        self._filechooser.hide()
        self.scrolled.show()
        self.link = filename
        self.metadata['title'] = self.make_new_filename(self.link)
        self._load_document(filename)   

    def create_old_toolbar(self):
        toolbox = activity.ActivityToolbox(self)
        activity_toolbar = toolbox.get_activity_toolbar()
        activity_toolbar.keep.props.visible = False
        activity_toolbar.share.props.visible = False
        
        self.read_toolbar = ReadToolbar()
        toolbox.add_toolbar(_('Read'), self.read_toolbar)
        self.read_toolbar.show()
        self.read_toolbar.set_activity(self)

        self.view_toolbar = ViewToolbar()
        toolbox.add_toolbar(_('View'), self.view_toolbar)
        self.view_toolbar.set_activity(self)
        self.view_toolbar.connect('go-fullscreen',
                self.__view_toolbar_go_fullscreen_cb)
        self.view_toolbar.show()

        self.set_toolbox(toolbox)
        toolbox.show()

        # start on the read toolbar
        self.toolbox.set_current_toolbar(_TOOLBAR_READ)

    def update_preview_cb(self, file_chooser, preview):
        filename = file_chooser.get_preview_filename()
        try:
            file_mimetype = mime.get_for_file(filename)
            if file_mimetype  == 'application/x-cbz' or file_mimetype == 'application/zip':
                fname = self.extract_image(filename)
                pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(fname, 
                    style.zoom(320), style.zoom(240))
                preview.set_from_pixbuf(pixbuf)
                have_preview = True
                os.remove(fname)
            else:
                have_preview = False
        except:
            have_preview = False
        file_chooser.set_preview_widget_active(have_preview)
        return

    def extract_image(self,  filename):
        zf = zipfile.ZipFile(filename, 'r')
        image_files = zf.namelist()
        image_files.sort()
        file_to_extract = image_files[0]
        extract_new_filename = self.make_new_filename(file_to_extract)
        if extract_new_filename is None or extract_new_filename == '':
            # skip over directory name if the images are in a subdirectory.
            file_to_extract = image_files[1]
            extract_new_filename = self.make_new_filename(file_to_extract)
            
        if len(image_files) > 0:
            if self.save_extracted_file(zf, file_to_extract):
                fname = os.path.join(self.get_activity_root(), 'instance',  
                                     extract_new_filename)
                return fname

    def create_new_toolbar(self):
        toolbar_box = ToolbarBox()

        activity_button = MyActivityToolbarButton(self)
        toolbar_box.toolbar.insert(activity_button, 0)
        activity_button.show()

        self.connect('go-fullscreen', \
            self.__view_toolbar_go_fullscreen_cb)

        self.back = ToolButton('go-previous')
        self.back.set_tooltip(_('Back'))
        self.back.props.sensitive = False
        palette = self.back.get_palette()
        self.menu_prev_page = MenuItem(text_label= _("Previous page"))
        palette.menu.append(self.menu_prev_page) 
        self.menu_prev_page.show_all()        
        self.back.connect('clicked', self.go_back_cb)
        self.menu_prev_page.connect('activate', self.go_back_cb)
        toolbar_box.toolbar.insert(self.back, -1)
        self.back.show()

        self.forward = ToolButton('go-next')
        self.forward.set_tooltip(_('Forward'))
        self.forward.props.sensitive = False
        palette = self.forward.get_palette()
        self.menu_next_page = MenuItem(text_label= _("Next page"))
        palette.menu.append(self.menu_next_page) 
        self.menu_next_page.show_all()        
        self.forward.connect('clicked', self.go_forward_cb)
        self.menu_next_page.connect('activate', self.go_forward_cb)
        toolbar_box.toolbar.insert(self.forward, -1)
        self.forward.show()

        num_page_item = Gtk.ToolItem()
        self.num_page_entry = Gtk.Entry()
        self.num_page_entry.set_text('0')
        self.num_page_entry.set_alignment(1)
        self.num_page_entry.connect('insert-text',
                               self.__new_num_page_entry_insert_text_cb)
        self.num_page_entry.connect('activate',
                               self.__new_num_page_entry_activate_cb)
        self.num_page_entry.set_width_chars(4)
        num_page_item.add(self.num_page_entry)
        self.num_page_entry.show()
        toolbar_box.toolbar.insert(num_page_item, -1)
        num_page_item.show()

        total_page_item = Gtk.ToolItem()
        self.total_page_label = Gtk.Label()

        self.total_page_label.set_text(' / 0')
        total_page_item.add(self.total_page_label)
        self.total_page_label.show()
        toolbar_box.toolbar.insert(total_page_item, -1)
        total_page_item.show()

        spacer = Gtk.SeparatorToolItem()
        toolbar_box.toolbar.insert(spacer, -1)
        spacer.show()
  
        self._zoom_out = ToolButton('zoom-out')
        self._zoom_out.set_tooltip(_('Zoom out'))
        self._zoom_out.connect('clicked', self._zoom_out_cb)
        toolbar_box.toolbar.insert(self._zoom_out, -1)
        self._zoom_out.props.sensitive = False
        self._zoom_out.show()

        self._zoom_in = ToolButton('zoom-in')
        self._zoom_in.set_tooltip(_('Zoom in'))
        self._zoom_in.connect('clicked', self._zoom_in_cb)
        toolbar_box.toolbar.insert(self._zoom_in, -1)
        self._zoom_in.props.sensitive = True
        self._zoom_in.show()

        self._fullscreen = ToolButton('view-fullscreen')
        self._fullscreen.set_tooltip(_('Fullscreen'))
        self._fullscreen.connect('clicked', self._fullscreen_cb)
        toolbar_box.toolbar.insert(self._fullscreen, -1)
        self._fullscreen.show()
        
        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)
        toolbar_box.toolbar.insert(separator, -1)
        separator.show()

        stop_button = StopButton(self)
        toolbar_box.toolbar.insert(stop_button, -1)
        stop_button.show()

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show()

    def _zoom_in_cb(self, button):
        self._zoom_in.props.sensitive = False
        self._zoom_out.props.sensitive = True
        self.zoom_to_width()
    
    def _zoom_out_cb(self, button):
        self._zoom_in.props.sensitive = True
        self._zoom_out.props.sensitive = False
        self.zoom_to_fit()

    def enable_zoom_in(self):
        self._zoom_in.props.sensitive = True
        self._zoom_out.props.sensitive = False

    def enable_zoom_out(self):
        self._zoom_in.props.sensitive = False
        self._zoom_out.props.sensitive = True

    def _fullscreen_cb(self, button):
        self.emit('go-fullscreen')

    def __new_num_page_entry_insert_text_cb(self, entry, text, length, position):
        for char in text:
            if not re.match('[0-9,-.]', char):
                entry.emit_stop_by_name('insert-text')
                return True
        return False

    def __new_num_page_entry_activate_cb(self, entry):
        if entry.props.text:
            page = int(entry.props.text) - 1
        else:
            page = 0

        if page >= self.total_pages:
            page = self.total_pages - 1
        elif page < 0:
            page = 0

        self.set_current_page(page)
        self.show_page(page)
        entry.props.text = str(page + 1)
        self.update_nav_buttons()

    def go_back_cb(self, button):
        self.previous_page()
    
    def go_forward_cb(self, button):
        self.next_page()
    
    def update_nav_buttons(self):
        current_page = self.page
        self.back.props.sensitive = current_page > 0
        self.forward.props.sensitive = \
            current_page < self.total_pages - 1
        
        self.num_page_entry.props.text = str(current_page + 1)
        self.total_page_label.props.label = \
            ' / ' + str(self.total_pages)

    def set_total_pages(self, pages):
        self.total_pages = pages

    def setToggleButtonState(self,button,b,id):
        button.handler_block(id)
        button.set_active(b)
        button.handler_unblock(id)

    def buttonpress_cb(self, widget, event):
        widget.grab_focus()

    def __view_toolbar_go_fullscreen_cb(self, view_toolbar):
        self.fullscreen()

    def zoom_to_width(self):
        self.zoom_image_to_fit = False
        self.show_page(self.page)

    def zoom_to_fit(self):
        self.zoom_image_to_fit = True
        self.show_page(self.page)

    def keypress_cb(self, widget, event):
        "Respond when the user presses Escape or one of the arrow keys"
        keyname = Gdk.keyval_name(event.keyval)
        if keyname == 'Page_Up':
            self.previous_page()
            return True
        if keyname == 'Page_Down' :
            self.next_page()
            return True
        if keyname == 'KP_Right':
            self.scroll_down()
            return True
        if keyname == 'Down' or keyname == 'KP_Down':
            self.scroll_down()
            return True
        if keyname == 'Up' or keyname == 'KP_Up':
            self.scroll_up()
            return True
        if keyname == 'KP_Left':
            self.scroll_up()
            return True
        if keyname == 'KP_Home':
            if self.cursor_visible:
                self.window.set_cursor(self.hidden_cursor)
                self.cursor_visible = False
            else:
                self.window.set_cursor(None)
                self.cursor_visible = True
            return True
        if keyname == 'plus':
            self.view_toolbar.enable_zoom_out()
            self.zoom_to_width()
            return True
        if keyname == 'minus':
            self.view_toolbar.enable_zoom_in()
            self.zoom_to_fit()
            return True
        return False

    def scroll_down(self):
        v_adjustment = self.scrolled.get_vadjustment()
        if v_adjustment.value == v_adjustment.upper - v_adjustment.page_size:
            self.next_page()
            return
        if v_adjustment.value < v_adjustment.upper - v_adjustment.page_size:
            new_value = v_adjustment.value + v_adjustment.step_increment
            if new_value > v_adjustment.upper - v_adjustment.page_size:
                new_value = v_adjustment.upper - v_adjustment.page_size
            v_adjustment.value = new_value

    def scroll_up(self):
        v_adjustment = self.scrolled.get_vadjustment()
        if v_adjustment.value == v_adjustment.lower:
            self.previous_page()
            return
        if v_adjustment.value > v_adjustment.lower:
            new_value = v_adjustment.value - v_adjustment.step_increment
            if new_value < v_adjustment.lower:
                new_value = v_adjustment.lower
            v_adjustment.value = new_value

    def previous_page(self):
        page = self.page
        page=page-1
        if page < 0: page=0
        if self.save_extracted_file(self.zf, self.image_files[page]) == True:
            fname = os.path.join(self.get_activity_root(), 'instance',  self.make_new_filename(self.image_files[page]))
            self.show_image(fname)
            os.remove(fname)
        v_adjustment = self.scrolled.get_vadjustment()
        v_adjustment.value = v_adjustment.upper - v_adjustment.page_size
        if _NEW_TOOLBAR_SUPPORT:
            self.set_current_page(page)
        else:
            self.read_toolbar.set_current_page(page)
        self.page = page

    def set_current_page(self, page):
        self.page = page
        if _NEW_TOOLBAR_SUPPORT:
            self.update_nav_buttons()

    def next_page(self):
        page = self.page
        page = page + 1
        if page >= len(self.image_files): page=len(self.image_files) - 1
        if self.save_extracted_file(self.zf, self.image_files[page]) == True:
            fname = os.path.join(self.get_activity_root(), 'instance',  self.make_new_filename(self.image_files[page]))
            self.show_image(fname)
            os.remove(fname)
        v_adjustment = self.scrolled.get_vadjustment()
        v_adjustment.value = v_adjustment.lower
        if _NEW_TOOLBAR_SUPPORT:
            self.set_current_page(page)
        else:
            self.read_toolbar.set_current_page(page)
        self.page = page

    def __draw_cb(self, widget, cr):
        screen_width = Gdk.Screen.width()
        screen_height = Gdk.Screen.height()
        if self.saved_screen_width != screen_width and self.saved_screen_width != 0:
            self.show_page(self.page)
        self.saved_screen_width = screen_width
        return False

    def show_page(self, page):
        if self.save_extracted_file(self.zf, self.image_files[page]) == True:
            fname = os.path.join(self.get_activity_root(), 'instance',  self.make_new_filename(self.image_files[page]))
            self.show_image(fname)
            os.remove(fname)
        
    def show_image(self, filename):
        "display a resized image in a full screen window"
        TOOLBOX_HEIGHT = 60
        BORDER_WIDTH =  30
        # get the size of the fullscreen display
        screen_width = Gdk.Screen.width()
        screen_width = screen_width - BORDER_WIDTH
        screen_height = Gdk.Screen.height()
        screen_height = screen_height - TOOLBOX_HEIGHT
        # get the size of the image.
        im = pygame.image.load(filename)
        image_width, image_height = im.get_size()
        getcontext().prec = 7
        s_a_ratio = Decimal(screen_height) / Decimal(screen_width)
        i_a_ratio = Decimal(image_height) / Decimal(image_width)
        new_width = image_width
        new_height = image_height
        if self.zoom_image_to_fit == True:
            if s_a_ratio >= i_a_ratio:
                new_width = screen_width
                new_height = image_height * screen_width
                if image_width > 1:
                    new_height /= image_width

                if new_height > screen_width:
                    new_height *= screen_width
                    if new_width > 1:
                        new_height /= new_width
                    new_width = screen_width
            else:
                new_height = screen_height
                new_width = image_width * screen_height
                if image_height > 1:
                    new_width /= image_height
                if new_width > screen_height:
                    new_width *= screen_height
                    if new_height > 1:
                        new_width /= new_height
                    new_height = screen_height
        else:
            new_width = screen_width
            new_height = image_height * screen_width
            if image_width > 1:
                new_height /= image_width

            if new_height > screen_width:
                new_height *= screen_width
                if new_width > 1:
                    new_height /= new_width
                new_width = screen_width
        
        pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename)
        scaled_buf = pixbuf.scale_simple(new_width, new_height, GdkPixbuf.InterpType.BILINEAR)
        self.image.set_from_pixbuf(scaled_buf)
        self.image.show()
 
    def save_extracted_file(self, zipfile, filename):
        "Extract the file to a temp directory for viewing"
        try:
            filebytes = zipfile.read(filename)
        except BadZipfile, err:
            print 'Error opening the zip file: %s' % (err)
            return False
        except KeyError,  err:
            self._alert('Key Error', 'Zipfile key not found: '  + str(filename))
            return
Beispiel #20
0
class PrimaryToolbar(ToolbarBase):
    __gtype_name__ = 'PrimaryToolbar'

    __gsignals__ = {
        'add-link': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'remove-link': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'set-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'reset-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'go-library': (GObject.SignalFlags.RUN_FIRST, None, ([])),
    }

    def __init__(self, tabbed_view, act):
        ToolbarBase.__init__(self)

        self._url_toolbar = UrlToolbar()

        self._activity = act
        self.model = act.model
        self.model.link_removed_signal.connect(self.__link_removed_cb)

        self._tabbed_view = self._canvas = tabbed_view

        self._loading = False
        self._download_running_hid = None

        toolbar = self.toolbar
        activity_button = ActivityToolbarButton(self._activity)
        toolbar.insert(activity_button, 0)

        separator = Gtk.SeparatorToolItem()

        '''
        Disabled since the python gi bindings don't expose the critical
        WebKit2.PrintOperation.print function

        save_as_pdf = ToolButton('save-as-pdf')
        save_as_pdf.set_tooltip(_('Save page as pdf'))
        save_as_pdf.connect('clicked', self.save_as_pdf)

        activity_button.props.page.insert(separator, -1)
        activity_button.props.page.insert(save_as_pdf, -1)
        separator.show()
        save_as_pdf.show()
        '''
        inspect_view = ToolButton('emblem-view-source')
        inspect_view.set_tooltip(_('Show Web Inspector'))
        inspect_view.connect('clicked', self.inspect_view)

        activity_button.props.page.insert(separator, -1)
        activity_button.props.page.insert(inspect_view, -1)
        separator.show()
        inspect_view.show()

        self._go_home = ToolButton('go-home')
        self._go_home.set_tooltip(_('Home page'))
        self._go_home.connect('clicked', self._go_home_cb)
        # add a menu to save the home page
        menu_box = PaletteMenuBox()
        self._go_home.props.palette.set_content(menu_box)
        menu_item = PaletteMenuItem()
        menu_item.set_label(_('Select as initial page'))
        menu_item.connect('activate', self._set_home_cb)
        menu_box.append_item(menu_item)

        self._reset_home_menu = PaletteMenuItem()
        self._reset_home_menu.set_label(_('Reset initial page'))
        self._reset_home_menu.connect('activate', self._reset_home_cb)
        menu_box.append_item(self._reset_home_menu)

        if os.path.isfile(LIBRARY_PATH):
            library_menu = PaletteMenuItem()
            library_menu.set_label(_('Library'))
            library_menu.connect('activate', self._go_library_cb)
            menu_box.append_item(library_menu)

        menu_box.show_all()

        # verify if the home page is configured
        client = GConf.Client.get_default()
        self._reset_home_menu.set_visible(
            client.get_string(HOME_PAGE_GCONF_KEY) is not None)

        toolbar.insert(self._go_home, -1)
        self._go_home.show()

        self.entry = WebEntry()
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-stop')
        self.entry.connect('icon-press', self._stop_and_reload_cb)
        self.entry.connect('activate', self._entry_activate_cb)
        self.entry.connect('focus-in-event', self.__focus_in_event_cb)
        self.entry.connect('focus-out-event', self.__focus_out_event_cb)
        self.entry.connect('key-press-event', self.__key_press_event_cb)
        self.entry.connect('changed', self.__changed_cb)

        # In an event box so that it can render the background
        entry_box = Gtk.EventBox()
        entry_box.add(self.entry)
        entry_box.show()

        self._entry_item = Gtk.ToolItem()
        self._entry_item.set_expand(True)
        self._entry_item.add(entry_box)
        self.entry.show()

        toolbar.insert(self._entry_item, -1)

        self._entry_item.show()

        self._back = ToolButton('go-previous-paired',
                                accelerator='<ctrl>Left')
        self._back.set_tooltip(_('Back'))
        self._back.props.sensitive = False
        self._back.connect('clicked', self._go_back_cb)
        toolbar.insert(self._back, -1)
        self._back.show()

        palette = self._back.get_palette()
        self._back_box_menu = Gtk.VBox()
        self._back_box_menu.show()
        palette.set_content(self._back_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._forward = ToolButton('go-next-paired',
                                   accelerator='<ctrl>Right')
        self._forward.set_tooltip(_('Forward'))
        self._forward.props.sensitive = False
        self._forward.connect('clicked', self._go_forward_cb)
        toolbar.insert(self._forward, -1)
        self._forward.show()

        palette = self._forward.get_palette()
        self._forward_box_menu = Gtk.VBox()
        self._forward_box_menu.show()
        palette.set_content(self._forward_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._download_icon = ProgressToolButton(
            icon_name='emblem-downloads',
            tooltip=_('No Downloads Running'))
        toolbar.insert(self._download_icon, -1)
        self._download_icon.show()
        downloadmanager.connect_download_started(self.__download_started_cb)

        self._link_add = ToggleToolButton('emblem-favorite')
        self._link_add.set_accelerator('<ctrl>d')
        self._link_add.set_tooltip(_('Bookmark'))
        self._link_add_toggled_hid = \
            self._link_add.connect('toggled', self.__link_add_toggled_cb)
        toolbar.insert(self._link_add, -1)
        self._link_add.show()

        self._toolbar_separator = Gtk.SeparatorToolItem()
        self._toolbar_separator.props.draw = False
        self._toolbar_separator.set_expand(True)

        self._stop_button = StopButton(self._activity)
        toolbar.insert(self._stop_button, -1)

        self._progress_listener = None
        self._browser = None

        self._loading_changed_hid = None
        self._progress_changed_hid = None
        self._session_history_changed_hid = None
        self._uri_changed_hid = None
        self._load_changed_hid = None
        self._security_status_changed_hid = None

        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

        tabbed_view.connect_after('switch-page', self.__switch_page_cb)
        tabbed_view.connect_after('page-added', self.__page_added_cb)

        Gdk.Screen.get_default().connect('size-changed',
                                         self.__screen_size_changed_cb)

        self._configure_toolbar()

    def __download_started_cb(self):
        if self._download_running_hid is None:
            self._download_running_hid = GLib.timeout_add(
                80, self.__download_running_cb)

    def __download_running_cb(self):
        progress = downloadmanager.overall_downloads_progress()
        self._download_icon.update(progress)
        if downloadmanager.num_downloads() > 0:
            self._download_icon.props.tooltip = \
                _('{}% Downloaded').format(int(progress*100))
            return True
        else:
            self._download_running_hid = None
            self._download_icon.props.tooltip = _('No Downloads Running')
            return False

    def __key_press_event_cb(self, entry, event):
        self._tabbed_view.current_browser.loading_uri = entry.props.text

    def __switch_page_cb(self, tabbed_view, page, page_num):
        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

    def __page_added_cb(self, notebook, child, pagenum):
        self.entry._search_popdown()

    def _configure_toolbar(self, screen=None):
        # Adapt the toolbars for portrait or landscape mode.

        if screen is None:
            screen = Gdk.Screen.get_default()

        if screen.get_width() < screen.get_height():
            if self._entry_item in self._url_toolbar.toolbar.get_children():
                return

            self.toolbar.remove(self._entry_item)
            self._url_toolbar.toolbar.insert(self._entry_item, -1)

            separator_pos = len(self.toolbar.get_children()) - 1
            self.toolbar.insert(self._toolbar_separator, separator_pos)
            self._toolbar_separator.show()

            self.pack_end(self._url_toolbar, True, True, 0)
            self._url_toolbar.show()

        else:
            if self._entry_item in self.toolbar.get_children():
                return

            self.toolbar.remove(self._toolbar_separator)

            position = len(self.toolbar.get_children()) - 4
            self._url_toolbar.toolbar.remove(self._entry_item)
            self.toolbar.insert(self._entry_item, position)

            self._toolbar_separator.hide()
            self.remove(self._url_toolbar)

    def __screen_size_changed_cb(self, screen):
        self._configure_toolbar(screen)

    def _connect_to_browser(self, browser):
        if self._browser is not None:
            self._browser.disconnect(self._uri_changed_hid)
            self._browser.disconnect(self._load_changed_hid)
            self._browser.disconnect(self._progress_changed_hid)
            self._browser.disconnect(self._security_status_changed_hid)

        self._browser = browser
        if not isinstance(self._browser, DummyBrowser):
            address = self._browser.props.uri or self._browser.loading_uri
        else:
            address = self._browser.props.uri
        self._set_address(address)
        self._set_progress(self._browser.props.estimated_load_progress)
        self._set_loading(self._browser.props.estimated_load_progress < 1.0)
        self._set_security_status(self._browser.security_status)

        is_webkit_browser = isinstance(self._browser, Browser)
        self.entry.props.editable = is_webkit_browser

        self._uri_changed_hid = self._browser.connect(
            'notify::uri', self.__uri_changed_cb)
        self._load_changed_hid = self._browser.connect(
            'load-changed', self.__load_changed_cb)
        self._progress_changed_hid = self._browser.connect(
            'notify::estimated-load-progress', self.__progress_changed_cb)
        self._security_status_changed_hid = self._browser.connect(
            'security-status-changed', self.__security_status_changed_cb)

        self._update_navigation_buttons()

    def __security_status_changed_cb(self, widget):
        self._set_security_status(widget.security_status)

    def __progress_changed_cb(self, widget, param):
        self._set_progress(widget.props.estimated_load_progress)
        self._set_loading(widget.props.estimated_load_progress < 1.0)

    def _set_security_status(self, security_status):
        # Display security status as a lock icon in the left side of
        # the URL entry.
        if security_status is None:
            self.entry.set_icon_from_pixbuf(
                iconentry.ICON_ENTRY_PRIMARY, None)
        elif security_status == Browser.SECURITY_STATUS_SECURE:
            self.entry.set_icon_from_name(
                iconentry.ICON_ENTRY_PRIMARY, 'channel-secure-symbolic')
        elif security_status == Browser.SECURITY_STATUS_INSECURE:
            self.entry.set_icon_from_name(
                iconentry.ICON_ENTRY_PRIMARY, 'channel-insecure-symbolic')

    def _set_progress(self, progress):
        if progress == 1.0:
            self.entry.set_progress_fraction(0.0)
        else:
            self.entry.set_progress_fraction(progress)

    def _set_address(self, uri):
        if uri is None:
            self.entry.props.address = ''
        else:
            self.entry.props.address = uri

    def __changed_cb(self, iconentry):
        # The WebEntry can be changed when we click on a link, then we
        # have to show the clear icon only if is the user who has
        # changed the entry
        if self.entry.has_focus():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_in_event_cb(self, entry, event):
        if not self._tabbed_view.is_current_page_pdf():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_out_event_cb(self, entry, event):
        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self._show_reload_icon()

    def _show_no_icon(self):
        self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY)

    def _show_stop_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-stop')

    def _show_reload_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-refresh')

    def _show_clear_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-cancel')

    def _update_navigation_buttons(self):
        can_go_back = self._browser.can_go_back()
        self._back.props.sensitive = can_go_back

        can_go_forward = self._browser.can_go_forward()
        self._forward.props.sensitive = can_go_forward

        is_webkit_browser = isinstance(self._browser, Browser)
        self._go_home.props.sensitive = is_webkit_browser
        if is_webkit_browser:
            self._reload_session_history()

        with self._link_add.handler_block(self._link_add_toggled_hid):
            uri = self._browser.get_uri()
            self._link_add.props.active = self.model.has_link(uri)

    def __link_removed_cb(self, model):
        self._update_navigation_buttons()

    def _entry_activate_cb(self, entry):
        url = entry.props.text
        effective_url = self._tabbed_view.normalize_or_autosearch_url(url)
        self._browser.load_uri(effective_url)
        self._browser.loading_uri = effective_url
        self.entry.props.address = effective_url
        self._browser.grab_focus()

    def _go_home_cb(self, button):
        self.emit('go-home')

    def _go_library_cb(self, button):
        self.emit('go-library')

    def _set_home_cb(self, button):
        self._reset_home_menu.set_visible(True)
        self.emit('set-home')

    def _reset_home_cb(self, button):
        self._reset_home_menu.set_visible(False)
        self.emit('reset-home')

    def _go_back_cb(self, button):
        self._browser.go_back()

    def _go_forward_cb(self, button):
        self._browser.go_forward()

    def __uri_changed_cb(self, widget, param):
        self._set_address(widget.get_uri())
        self._update_navigation_buttons()
        filepicker.cleanup_temp_files()

    def __load_changed_cb(self, widget, event):
        self._update_navigation_buttons()

    def _stop_and_reload_cb(self, entry, icon_pos, button):
        if entry.has_focus() and \
                not self._tabbed_view.is_current_page_pdf():
            entry.set_text('')
        else:
            if self._loading:
                self._browser.stop_loading()
            else:
                self._browser.reload()

    def _set_loading(self, loading):
        self._loading = loading

        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self._set_sensitive(True)
                self._show_reload_icon()
            else:
                self._set_sensitive(False)
                self._show_no_icon()

    def _set_sensitive(self, value):
        for widget in self.toolbar:
            if widget not in (self._stop_button,
                              self._link_add):
                widget.set_sensitive(value)

    def _reload_session_history(self):
        back_forward_list = self._browser.get_back_forward_list()
        item_index = 0  # The index of the history item

        # Clear menus in palettes:
        for box_menu in (self._back_box_menu, self._forward_box_menu):
            for menu_item in box_menu.get_children():
                box_menu.remove(menu_item)

        def create_menu_item(history_item):
            """Create a MenuItem for the back or forward palettes."""
            title = history_item.get_title() or _('No Title')
            if not isinstance(title, unicode):
                title = unicode(title, 'utf-8')
            # This is a fix until the Sugar MenuItem is fixed:
            menu_item = PaletteMenuItem(text_label=title)
            menu_item.connect('activate', self._history_item_activated_cb,
                              history_item)
            return menu_item

        back_list = back_forward_list.get_back_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        back_list.reverse()
        for item in back_list:
            menu_item = create_menu_item(item)
            self._back_box_menu.pack_end(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

        # Increment the item index to count the current page:
        item_index += 1

        forward_list = back_forward_list.get_forward_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        forward_list.reverse()
        for item in forward_list:
            menu_item = create_menu_item(item)
            self._forward_box_menu.pack_start(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

    def _history_item_activated_cb(self, menu_item, history_item):
        self._back.get_palette().popdown(immediate=True)
        self._forward.get_palette().popdown(immediate=True)
        # self._browser.set_history_index(index)
        self._browser.go_to_back_forward_list_item(history_item)

    def __link_add_toggled_cb(self, button):
        if button.props.active:
            self.emit('add-link')
        else:
            self.emit('remove-link')

    def inspect_view(self, button):
        page = self._canvas.get_current_page()
        webview = self._canvas.get_children()[page].props.browser

        # If get_inspector returns None, it is not a real WebView
        inspector = webview.get_inspector()
        if inspector is not None:
            # Inspector window will be blank if disabled
            web_settings = webview.get_settings()
            web_settings.props.enable_developer_extras = True

            inspector.show()
            inspector.attach()

    '''
Beispiel #21
0
class TuningToolbar(Gtk.Toolbar):
    ''' The toolbar for tuning instruments '''

    def __init__(self, activity):
        super(type(self), self).__init__()

        self.activity = activity
        self._show_tuning_line = False
        self._updating_note = True
        self._tuning_tool = None

        self._instrument_button = ToolButton('instruments')
        self._instrument_button.set_tooltip(_('Tune an instrument.'))
        self._instrument_button.connect('clicked',
                                        self._button_selection_cb)
        self.insert(self._instrument_button, -1)
        self._setup_instrument_palette()

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = True
        self.insert(separator, -1)

        self._note = 'A'
        self._notes_button = ToolButton('notes')
        self._notes_button.set_tooltip(_('Notes'))
        self._notes_button.connect('clicked',
                                   self._button_selection_cb)
        self.insert(self._notes_button, -1)
        self._setup_notes_palette()

        self._octave = 4
        self._octaves_button = ToolButton('octaves')
        self._octaves_button.set_tooltip(_('Octaves'))
        self._octaves_button.connect('clicked',
                                     self._button_selection_cb)
        self.insert(self._octaves_button, -1)
        self._setup_octaves_palette()

        # The entry is used to display a note or for direct user input
        self._freq_entry = Gtk.Entry()
        self._freq_entry.set_text('440')  # A
        self._freq_entry_changed_id = self._freq_entry.connect(
            'changed', self._update_freq_entry)
        if hasattr(self._freq_entry, 'set_tooltip_text'):
            self._freq_entry.set_tooltip_text(
                _('Enter a frequency to display.'))
        self._freq_entry.set_width_chars(8)
        self._freq_entry.show()
        toolitem = Gtk.ToolItem()
        toolitem.add(self._freq_entry)
        self.insert(toolitem, -1)
        toolitem.show()

        self._new_tuning_line = ToolButton('tuning-tools')
        self._new_tuning_line.show()
        self.insert(self._new_tuning_line, -1)
        self._new_tuning_line.set_tooltip(_('Show tuning line.'))
        self._new_tuning_line.connect('clicked', self.tuning_line_cb)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = True
        self.insert(separator, -1)

        self._harmonic = ToolButton('harmonics')
        self._harmonic.show()
        self.insert(self._harmonic, -1)
        self._harmonic.set_tooltip(_('Show harmonics.'))
        self._harmonic.connect('clicked', self.harmonic_cb)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = True
        self.insert(separator, -1)

        self._play_tone = ToolButton('media-playback-start')
        self._play_tone.show()
        self.insert(self._play_tone, -1)
        self._play_tone.set_tooltip(_('Play a note.'))
        self._play_tone.connect('clicked', self.play_cb)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)
        self.insert(separator, -1)

        self.label = Gtk.Label(label='')
        self.label.set_use_markup(True)
        self.label.show()
        toolitem = Gtk.ToolItem()
        toolitem.add(self.label)
        self.insert(toolitem, -1)
        toolitem.show()

        self.show_all()

    def _update_note(self):
        ''' Calculate the frequency based on note and octave '''
        if not hasattr(self, '_freq_entry'):  # Still setting up toolbar
            return
        i = self._octave * 12 + NOTES.index(self._note)
        freq = A0 * pow(TWELTHROOT2, i)
        self._updating_note = True
        self._freq_entry.set_text('%0.3f' % (freq))
        self.label.set_markup(SPAN % (style.COLOR_WHITE.get_html(),
                                      self._note + str(self._octave)))
        if self._show_tuning_line:
            self.activity.wave.tuning_line = freq
        return

    def _update_freq_entry(self, widget):
        # Calculate a note from a frequency
        if not self._updating_note:  # Only if user types in a freq.
            try:
                freq = float(self._freq_entry.get_text())
                # Only consider notes in piano range
                if freq < A0 * 0.97:
                    self.label.set_text('< A0')
                    return
                if freq > C8 * 1.03:
                    self.label.set_text('> C8')
                    return
                self.label.set_markup(freq_note(freq, flatsharp=True))
            except ValueError:
                return

        self._updating_note = False

    def _button_selection_cb(self, widget):
        palette = widget.get_palette()
        if palette:
            if not palette.is_up():
                palette.popup(immediate=True)
            else:
                palette.popdown(immediate=True)
            return

    def _setup_notes_palette(self):
        self._notes_palette = self._notes_button.get_palette()

        for note in NOTES:
            menu_item = MenuItem(icon_name='',
                                 text_label=note)
            menu_item.connect('activate', self._note_selected_cb, note)
            self._notes_palette.menu.append(menu_item)
            menu_item.show()

    def _note_selected_cb(self, widget, note):
        self._note = note
        self._update_note()

    def _setup_octaves_palette(self):
        self._octaves_palette = self._octaves_button.get_palette()

        for octave in range(9):
            menu_item = MenuItem(icon_name='',
                                 text_label=str(octave))
            menu_item.connect('activate', self._octave_selected_cb, octave)
            self._octaves_palette.menu.append(menu_item)
            menu_item.show()

    def _octave_selected_cb(self, widget, octave):
        self._octave = octave
        self._update_note()

    def _setup_instrument_palette(self):
        self.instrument_palette = self._instrument_button.get_palette()

        self.instrument = []
        for k in INSTRUMENT_DICT.keys():
            self.instrument.append(k)
            menu_item = MenuItem(icon_name='',
                                 text_label=k)
            menu_item.connect('activate', self.instrument_selected_cb, k)
            self.instrument_palette.menu.append(menu_item)
            menu_item.show()

    def instrument_selected_cb(self, button, instrument):
        ''' Callback for instrument control '''
        logging.debug(instrument)
        if self._tuning_tool is not None:
            self.remove(self._tuning_tool)

        if instrument == _('None'):
            self.activity.wave.instrument = None

            # Remove any previous tuning button
            if hasattr(self, '_tuning_button'):
                self._tuning_button.destroy()

            # Restore the notes, octaves buttons
            if hasattr(self, '_notes_button'):
                self.insert(self._notes_button, 2)
                self.insert(self._octaves_button, 3)
            return

        self.remove(self._notes_button)
        self.remove(self._octaves_button)

        self.activity.wave.instrument = instrument

        # If we are not already in freq. base, switch.
        if not self.activity.wave.get_fft_mode():
            self.activity.timefreq_control()

        # Add a Tuning palette for this instrument
        self._tuning_button = ToolButton('notes')
        self._tuning_button.set_tooltip(instrument)
        self._tuning_button.connect('clicked', self._button_selection_cb)
        self.insert(self._tuning_button, 1)
        self._setup_tuning_palette(instrument)

    def _setup_tuning_palette(self, instrument):
        self._tuning_palette = self._tuning_button.get_palette()

        self.tuning = []
        self.tuning.append(_('All notes'))
        menu_item = MenuItem(icon_name='', text_label=_('All notes'))
        menu_item.connect('activate', self._tuning_selected_cb,
                          instrument, -1)
        self._tuning_palette.menu.append(menu_item)
        menu_item.show()

        for i, f in enumerate(INSTRUMENT_DICT[instrument]):
            self.tuning.append(freq_note(f))
            menu_item = MenuItem(icon_name='',
                                 text_label=freq_note(f))
            menu_item.connect('activate', self._tuning_selected_cb,
                              instrument, i)
            self._tuning_palette.menu.append(menu_item)
            menu_item.show()

        self.show_all()

    def _tuning_selected_cb(self, widget, instrument, fidx):
        ''' Update note '''
        if not hasattr(self, '_freq_entry'):  # Still setting up toolbar?
            return

        if instrument not in INSTRUMENT_DICT:
            return

        if fidx == -1:  # All notes
            self.activity.wave.instrument = instrument
            self.activity.wave.tuning_line = 0.0
            self._new_tuning_line.set_icon('tuning-tools')
            self._new_tuning_line.set_tooltip(_('Show tuning line.'))
            self._show_tuning_line = False
        else:
            freq = INSTRUMENT_DICT[instrument][fidx]
            self.activity.wave.instrument = None
            self.activity.wave.tuning_line = freq
            self._new_tuning_line.set_icon('tuning-tools-off')
            self._new_tuning_line.set_tooltip(_('Hide tuning line.'))
            self._show_tuning_line = True

        self._updating_note = False

    def harmonic_cb(self, *args):
        ''' Callback for harmonics control '''
        self.activity.wave.harmonics = not self.activity.wave.harmonics
        if self.activity.wave.harmonics:
            self._harmonic.set_icon_name('harmonics-off')
            self._harmonic.set_tooltip(_('Hide harmonics.'))
            if self.activity.wave.instrument is None and \
               self.activity.wave.tuning_line == 0.0:
                self._load_tuning_line()
        else:
            self._harmonic.set_icon_name('harmonics')
            self._harmonic.set_tooltip(_('Show harmonics.'))

    def tuning_line_cb(self, *args):
        ''' Callback for tuning insert '''
        if self._show_tuning_line:
            self.activity.wave.tuning_line = 0.0
            self._new_tuning_line.set_icon_name('tuning-tools')
            self._new_tuning_line.set_tooltip(_('Show tuning line.'))
            self._show_tuning_line = False
        else:
            self._load_tuning_line()

    def _load_tuning_line(self):
        ''' Read the freq entry and use value to set tuning line '''
        freq = self._freq_entry.get_text()
        try:
            self.activity.wave.tuning_line = float(freq)
            if freq < 0:
                freq = -freq
            self._new_tuning_line.set_icon_name('tuning-tools-off')
            self._new_tuning_line.set_tooltip(_('Hide tuning line.'))
            self._show_tuning_line = True
        except ValueError:
            self.activity.wave.tuning_line = 0.0
            self._freq_entry.set_text('0')
        # If we are not already in freq. base, switch.
        if not self.activity.wave.get_fft_mode():
            self.activity.timefreq_control()

    def play_cb(self, *args):
        ''' Save settings, turn off display, and then play a tone at
        the current frequency '''
        channels = []
        for c in range(self.activity.audiograb.channels):
            channels.append(self.activity.wave.get_visibility(channel=c))
            self.activity.wave.set_visibility(False, channel=c)
        wave_status = self.activity.wave.get_active()
        self.activity.wave.set_context_off()
        self.activity.wave.set_active(False)
        if self.activity.hw in [XO4, XO175]:
            self.activity.audiograb.stop_grabbing()

        freq = float(self._freq_entry.get_text())
        GLib.timeout_add(200, self.play_sound, freq, channels, wave_status)

    def play_sound(self, freq, channels, wave_status):
        ''' Play the sound and then restore wave settings '''
        self._play_sinewave(freq, 5000, 1)

        if self.activity.hw in [XO4, XO175]:
            self.activity.sensor_toolbar.set_mode('sound')
            self.activity.sensor_toolbar.set_sound_context()
            self.activity.audiograb.start_grabbing()
        for c in range(self.activity.audiograb.channels):
            self.activity.wave.set_visibility(channels[c], channel=c)
        self.activity.wave.set_context_on()
        self.activity.wave.set_active(wave_status)

    def _play_sinewave(self, pitch, amplitude=5000, duration=1):
        """ Create a Csound score to play a sine wave. """
        self.orchlines = []
        self.scorelines = []
        self.instrlist = []

        try:
            pitch = abs(float(pitch))
            amplitude = abs(float(amplitude))
            duration = abs(float(duration))
        except ValueError:
            logging.error('bad args to _play_sinewave')
            return

        self._prepare_sinewave(pitch, amplitude, duration)

        path = os.path.join(self.activity.get_activity_root(), 'instance',
                            'tmp.csd')
        # Create a csound file from the score.
        self._audio_write(path)

        # Play the csound file.
        check_output(['csound', path], 'call to csound failed?')

    def _prepare_sinewave(self, pitch, amplitude, duration, starttime=0,
                          pitch_envelope=99, amplitude_envelope=100,
                          instrument=1):

        pitenv = pitch_envelope
        ampenv = amplitude_envelope
        if 1 not in self.instrlist:
            self.orchlines.append("instr 1\n")
            self.orchlines.append("kpitenv oscil 1, 1/p3, p6\n")
            self.orchlines.append("aenv oscil 1, 1/p3, p7\n")
            self.orchlines.append("asig oscil p5*aenv, p4*kpitenv, p8\n")
            self.orchlines.append("out asig\n")
            self.orchlines.append("endin\n\n")
            self.instrlist.append(1)

        self.scorelines.append("i1 %s %s %s %s %s %s %s\n" %
                               (str(starttime), str(duration), str(pitch),
                                str(amplitude), str(pitenv), str(ampenv),
                                str(instrument)))

    def _audio_write(self, file):
        """ Compile a .csd file. """

        csd = open(file, "w")
        csd.write("<CsoundSynthesizer>\n\n")
        csd.write("<CsOptions>\n")
        csd.write("-+rtaudio=alsa -odevaudio -m0 -d -b256 -B512\n")
        csd.write("</CsOptions>\n\n")
        csd.write("<CsInstruments>\n\n")
        csd.write("sr=16000\n")
        csd.write("ksmps=50\n")
        csd.write("nchnls=1\n\n")
        for line in self.orchlines:
            csd.write(line)
        csd.write("\n</CsInstruments>\n\n")
        csd.write("<CsScore>\n\n")
        csd.write("f1 0 2048 10 1\n")
        csd.write("f2 0 2048 10 1 0 .33 0 .2 0 .143 0 .111\n")
        csd.write("f3 0 2048 10 1 .5 .33 .25 .2 .175 .143 .125 .111 .1\n")
        csd.write("f10 0 2048 10 1 0 0 .3 0 .2 0 0 .1\n")
        csd.write("f99 0 2048 7 1 2048 1\n")
        csd.write("f100 0 2048 7 0. 10 1. 1900 1. 132 0.\n")
        csd.write(self.scorelines.pop())
        csd.write("e\n")
        csd.write("\n</CsScore>\n")
        csd.write("\n</CsoundSynthesizer>")
        csd.close()
Beispiel #22
0
class InstrumentToolbar(Gtk.Toolbar):
    ''' The toolbar for adding new instruments '''

    def __init__(self, activity):
        super(type(self), self).__init__()
        self.activity = activity
        self.new_instruments = []

        self._name_entry = Gtk.Entry()
        self._name_entry.set_text(_('my instrument'))
        self._name_entry_changed_id = self._name_entry.connect(
            'changed', self.update_name_entry)
        if hasattr(self._name_entry, 'set_tooltip_text'):
            self._name_entry.set_tooltip_text(
                _('Enter instrument name.'))
        self._name_entry.set_width_chars(24)
        self._name_entry.show()
        toolitem = Gtk.ToolItem()
        toolitem.add(self._name_entry)
        self.insert(toolitem, -1)
        toolitem.show()

        self._note = 'A'
        self._notes_button = ToolButton('notes')
        self._notes_button.set_tooltip(_('Notes'))
        self._notes_button.connect('clicked',
                                   self._button_selection_cb)
        self.insert(self._notes_button, -1)
        self._setup_notes_palette()
        self._notes_button.show()

        self._octave = 4
        self._octaves_button = ToolButton('octaves')
        self._octaves_button.set_tooltip(_('Octaves'))
        self._octaves_button.connect('clicked',
                                     self._button_selection_cb)
        self.insert(self._octaves_button, -1)
        self._setup_octaves_palette()
        self._octaves_button.show()

        self._new_note = ToolButton('list-add')
        self._new_note.show()
        self.insert(self._new_note, -1)
        self._new_note.set_tooltip(_('Add a new note.'))
        self._new_note.connect('clicked', self.new_note_cb)
        self._new_note.show()

    def _button_selection_cb(self, widget):
        palette = widget.get_palette()
        if palette:
            if not palette.is_up():
                palette.popup(immediate=True)
            else:
                palette.popdown(immediate=True)
            return

    def _setup_notes_palette(self):
        self._notes_palette = self._notes_button.get_palette()

        for note in NOTES:
            menu_item = MenuItem(icon_name='',
                                 text_label=note)
            menu_item.connect('activate', self._note_selected_cb, note)
            self._notes_palette.menu.append(menu_item)
            menu_item.show()

    def _note_selected_cb(self, widget, note):
        self._note = note

    def _setup_octaves_palette(self):
        self._octaves_palette = self._octaves_button.get_palette()

        for octave in range(9):
            menu_item = MenuItem(icon_name='',
                                 text_label=str(octave))
            menu_item.connect('activate', self._octave_selected_cb, octave)
            self._octaves_palette.menu.append(menu_item)
            menu_item.show()

    def _octave_selected_cb(self, widget, octave):
        self._octave = octave

    def update_name_entry(self, *args):
        ''' Add name to INSTRUMENT_DICT and combo box '''
        # Wait until a note has been added...
        return

    def new_note_cb(self, *args):
        ''' Add a new note to instrument tuning list '''
        name = self._name_entry.get_text()
        if name not in INSTRUMENT_DICT:
            INSTRUMENT_DICT[name] = []
            self.activity.tuning_toolbar.instrument.append(name)
            menu_item = MenuItem(icon_name='',
                                 text_label=name)
            menu_item.connect(
                'activate',
                self.activity.tuning_toolbar.instrument_selected_cb,
                name)
            self.activity.tuning_toolbar.instrument_palette.menu.append(
                menu_item)
            menu_item.show()
            self.new_instruments.append(name)

        freq = A0 * pow(TWELTHROOT2,
                        self._octave * 12 + NOTES.index(self._note))
        if freq not in INSTRUMENT_DICT[name]:
            INSTRUMENT_DICT[name].append(freq)
Beispiel #23
0
    def __init__(self):
        super(PyApp, self).__init__()

        self.set_title('Palettes')
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)

        vbox = Gtk.VBox()

        toolbarbox = ToolbarBox()
        vbox.add(toolbarbox)

        toolbar = toolbarbox.toolbar

        color_button = ColorToolButton()
        toolbar.insert(color_button, -1)

        button = ToolButton('list-add')
        button.set_tooltip('Palette with widgets')
        toolbar.insert(button, -1)

        palette = button.get_palette()
        palette_box = Gtk.VBox()
        palette.set_content(palette_box)

        checkbutton1 = Gtk.CheckButton(label='Option 1')
        palette_box.pack_start(checkbutton1, False, False, 0)

        checkbutton2 = Gtk.CheckButton(label='Option 2')
        palette_box.pack_start(checkbutton2, False, False, 0)

        checkbutton3 = Gtk.CheckButton(label='Option 3')
        palette_box.pack_start(checkbutton3, False, False, 0)

        separator = Gtk.VSeparator()
        palette_box.pack_start(separator, False, False, 0)

        radio_button1 = Gtk.RadioButton(label='Option 1')
        palette_box.pack_start(radio_button1, False, False, 0)

        radio_button2 = Gtk.RadioButton(label='Option 2', group=radio_button1)
        palette_box.pack_start(radio_button2, False, False, 0)

        radio_button3 = Gtk.RadioButton(label='Option 3', group=radio_button1)
        palette_box.pack_start(radio_button3, False, False, 0)

        palette_box.show_all()

        button = ToolButton(icon_name='format-justify-fill')
        button.props.tooltip = 'Select list'
        button.props.hide_tooltip_on_click = False
        button.palette_invoker.props.toggle_palette = True
        toolbar.insert(button, -1)

        menu_box = PaletteMenuBox()
        button.props.palette.set_content(menu_box)
        menu_box.show()

        menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-fill')
        menu_box.append_item(menu_item)

        menu_item = PaletteMenuItem('Item 1',
                                    icon_name='format-justify-center')
        menu_box.append_item(menu_item)

        menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-left')
        menu_box.append_item(menu_item)

        menu_item = PaletteMenuItem('Item 1', icon_name='format-justify-right')
        menu_box.append_item(menu_item)

        self.add(vbox)
        self.show_all()

        self.connect('destroy', Gtk.main_quit)
Beispiel #24
0
class ViewToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ViewToolbar'

    __gsignals__ = {
        'go-fullscreen': (GObject.SignalFlags.RUN_FIRST, None, ([])),
    }

    def __init__(self):
        Gtk.Toolbar.__init__(self)

        self._view = None
        self._bookmarkmanager = None
        self._update_offset = True

        self._zoom_out = ToolButton('zoom-out')
        self._zoom_out.set_tooltip(_('Zoom out'))
        self._zoom_out.connect('clicked', self._zoom_out_cb)
        self.insert(self._zoom_out, -1)
        self._zoom_out.show()

        self._zoom_in = ToolButton('zoom-in')
        self._zoom_in.set_tooltip(_('Zoom in'))
        self._zoom_in.connect('clicked', self._zoom_in_cb)
        self.insert(self._zoom_in, -1)
        self._zoom_in.show()

        self._zoom_to_width = ToolButton('zoom-best-fit')
        self._zoom_to_width.set_tooltip(_('Zoom to width'))
        self._zoom_to_width.connect('clicked', self._zoom_to_width_cb)
        self.insert(self._zoom_to_width, -1)
        self._zoom_to_width.show()

        palette = self._zoom_to_width.get_palette()
        menu_item = MenuItem(_('Zoom to fit'))
        menu_item.connect('activate', self._zoom_to_fit_menu_item_activate_cb)
        palette.menu.append(menu_item)
        menu_item.show()

        menu_item = MenuItem(_('Actual size'))
        menu_item.connect('activate', self._actual_size_menu_item_activate_cb)
        palette.menu.append(menu_item)
        menu_item.show()

        tool_item = Gtk.ToolItem()
        self.insert(tool_item, -1)
        tool_item.show()

        self._zoom_spin = Gtk.SpinButton()
        self._zoom_spin.set_range(5.409, 400)
        self._zoom_spin.set_increments(1, 10)
        self._zoom_spin_notify_value_handler = self._zoom_spin.connect(
                'notify::value', self._zoom_spin_notify_value_cb)
        tool_item.add(self._zoom_spin)
        self._zoom_spin.show()

        zoom_perc_label = Gtk.Label(_("%"))
        zoom_perc_label.show()
        tool_item_zoom_perc_label = Gtk.ToolItem()
        tool_item_zoom_perc_label.add(zoom_perc_label)
        self.insert(tool_item_zoom_perc_label, -1)
        tool_item_zoom_perc_label.show()

        spacer = Gtk.SeparatorToolItem()
        spacer.props.draw = False
        self.insert(spacer, -1)
        spacer.show()

        self._fullscreen = ToolButton('view-fullscreen')
        self._fullscreen.set_tooltip(_('Fullscreen'))
        self._fullscreen.connect('clicked', self._fullscreen_cb)
        self.insert(self._fullscreen, -1)
        self._fullscreen.show()

        self._view_notify_zoom_handler = None

    def set_view(self, view):
        self._view = view

    def set_bookmarkmanager(self, bookmarkmanager):
        self._bookmarkmanager = bookmarkmanager

    def _zoom_spin_notify_value_cb(self, zoom_spin, pspec):
        self._view.set_zoom(zoom_spin.props.value)

    def _view_notify_zoom_cb(self, model, pspec):
        self._zoom_spin.disconnect(self._zoom_spin_notify_value_handler)
        try:
            self._zoom_spin.props.value = round(self._view.get_zoom())
        finally:
            self._zoom_spin_notify_value_handler = self._zoom_spin.connect(
                    'notify::value', self._zoom_spin_notify_value_cb)

    def __set_progress_if_applicable(self):
        if (self._view.show_progress_bar() is True) and \
           (self._update_offset is True):
            self._view.get_maximum_offset_possible()

    def zoom_in(self, zoom_amount):
        self._view.zoom_in(zoom_amount)
        self._view._main_instance.window.force_ui_updates()
        self.__set_progress_if_applicable()

    def _zoom_in_cb(self, button, zoom_amount = 1):
        if self._view.can_zoom_in():
            self.zoom_in(zoom_amount)
            self._view._number_of_times_zoomed = \
                    self._view._number_of_times_zoomed + zoom_amount

    def zoom_out(self, zoom_amount):
        self._view.zoom_out(zoom_amount)
        self._view._main_instance.window.force_ui_updates()
        self.__set_progress_if_applicable()


    def _zoom_out_cb(self, button, zoom_amount = 1):
        if self._view.can_zoom_out():
            self.zoom_out(zoom_amount)
            self._view._number_of_times_zoomed = \
                    self._view._number_of_times_zoomed - zoom_amount

    def update_offset(self, update):
        self._update_offset = update

    def zoom_to_width(self):
        self._view.zoom_to_width()

    def _zoom_to_width_cb(self, button):
        self.zoom_to_width()

    def _zoom_to_fit_menu_item_activate_cb(self, menu_item):
        self._view.zoom_to_best_fit()

    def _actual_size_menu_item_activate_cb(self, menu_item):
        self._view.zoom_to_actual_size()

    def _fullscreen_cb(self, button):
        self.emit('go-fullscreen')
class PrimaryToolbar(ToolbarBase):
    __gtype_name__ = 'PrimaryToolbar'

    __gsignals__ = {
        'add-link': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'remove-link': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'set-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'reset-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'go-library': (GObject.SignalFlags.RUN_FIRST, None, ([])),
    }

    def __init__(self, tabbed_view, act):
        ToolbarBase.__init__(self)

        self._url_toolbar = UrlToolbar()

        self._activity = act
        self.model = act.model
        self.model.link_removed_signal.connect(self.__link_removed_cb)

        self._tabbed_view = self._canvas = tabbed_view

        self._loading = False
        self._download_running_hid = None

        toolbar = self.toolbar
        activity_button = ActivityToolbarButton(self._activity)
        toolbar.insert(activity_button, 0)

        separator = Gtk.SeparatorToolItem()
        '''
        Disabled since the python gi bindings don't expose the critical
        WebKit2.PrintOperation.print function

        save_as_pdf = ToolButton('save-as-pdf')
        save_as_pdf.set_tooltip(_('Save page as pdf'))
        save_as_pdf.connect('clicked', self.save_as_pdf)

        activity_button.props.page.insert(separator, -1)
        activity_button.props.page.insert(save_as_pdf, -1)
        separator.show()
        save_as_pdf.show()
        '''
        inspect_view = ToolButton('emblem-view-source')
        inspect_view.set_tooltip(_('Show Web Inspector'))
        inspect_view.connect('clicked', self.inspect_view)

        activity_button.props.page.insert(separator, -1)
        activity_button.props.page.insert(inspect_view, -1)
        separator.show()
        inspect_view.show()

        self._go_home = ToolButton('go-home')
        self._go_home.set_tooltip(_('Home page'))
        self._go_home.connect('clicked', self._go_home_cb)
        # add a menu to save the home page
        menu_box = PaletteMenuBox()
        self._go_home.props.palette.set_content(menu_box)
        menu_item = PaletteMenuItem()
        menu_item.set_label(_('Select as initial page'))
        menu_item.connect('activate', self._set_home_cb)
        menu_box.append_item(menu_item)

        self._reset_home_menu = PaletteMenuItem()
        self._reset_home_menu.set_label(_('Reset initial page'))
        self._reset_home_menu.connect('activate', self._reset_home_cb)
        menu_box.append_item(self._reset_home_menu)

        if os.path.isfile(LIBRARY_PATH):
            library_menu = PaletteMenuItem()
            library_menu.set_label(_('Library'))
            library_menu.connect('activate', self._go_library_cb)
            menu_box.append_item(library_menu)

        menu_box.show_all()

        # verify if the home page is configured
        client = GConf.Client.get_default()
        self._reset_home_menu.set_visible(
            client.get_string(HOME_PAGE_GCONF_KEY) is not None)

        toolbar.insert(self._go_home, -1)
        self._go_home.show()

        self.entry = WebEntry()
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-stop')
        self.entry.connect('icon-press', self._stop_and_reload_cb)
        self.entry.connect('activate', self._entry_activate_cb)
        self.entry.connect('focus-in-event', self.__focus_in_event_cb)
        self.entry.connect('focus-out-event', self.__focus_out_event_cb)
        self.entry.connect('key-press-event', self.__key_press_event_cb)
        self.entry.connect('changed', self.__changed_cb)

        # In an event box so that it can render the background
        entry_box = Gtk.EventBox()
        entry_box.add(self.entry)
        entry_box.show()

        self._entry_item = Gtk.ToolItem()
        self._entry_item.set_expand(True)
        self._entry_item.add(entry_box)
        self.entry.show()

        toolbar.insert(self._entry_item, -1)

        self._entry_item.show()

        self._back = ToolButton('go-previous-paired', accelerator='<ctrl>Left')
        self._back.set_tooltip(_('Back'))
        self._back.props.sensitive = False
        self._back.connect('clicked', self._go_back_cb)
        toolbar.insert(self._back, -1)
        self._back.show()

        palette = self._back.get_palette()
        self._back_box_menu = Gtk.VBox()
        self._back_box_menu.show()
        palette.set_content(self._back_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._forward = ToolButton('go-next-paired', accelerator='<ctrl>Right')
        self._forward.set_tooltip(_('Forward'))
        self._forward.props.sensitive = False
        self._forward.connect('clicked', self._go_forward_cb)
        toolbar.insert(self._forward, -1)
        self._forward.show()

        palette = self._forward.get_palette()
        self._forward_box_menu = Gtk.VBox()
        self._forward_box_menu.show()
        palette.set_content(self._forward_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._download_icon = ProgressToolButton(
            icon_name='emblem-downloads', tooltip=_('No Downloads Running'))
        toolbar.insert(self._download_icon, -1)
        self._download_icon.show()
        downloadmanager.connect_donwload_started(self.__download_started_cb)

        self._link_add = ToggleToolButton('emblem-favorite')
        self._link_add.set_accelerator('<ctrl>d')
        self._link_add.set_tooltip(_('Bookmark'))
        self._link_add_toggled_hid = \
            self._link_add.connect('toggled', self.__link_add_toggled_cb)
        toolbar.insert(self._link_add, -1)
        self._link_add.show()

        self._toolbar_separator = Gtk.SeparatorToolItem()
        self._toolbar_separator.props.draw = False
        self._toolbar_separator.set_expand(True)

        self._stop_button = StopButton(self._activity)
        toolbar.insert(self._stop_button, -1)

        self._progress_listener = None
        self._browser = None

        self._loading_changed_hid = None
        self._progress_changed_hid = None
        self._session_history_changed_hid = None
        self._uri_changed_hid = None
        self._load_changed_hid = None
        self._security_status_changed_hid = None

        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

        tabbed_view.connect_after('switch-page', self.__switch_page_cb)
        tabbed_view.connect_after('page-added', self.__page_added_cb)

        Gdk.Screen.get_default().connect('size-changed',
                                         self.__screen_size_changed_cb)

        self._configure_toolbar()

    def __download_started_cb(self):
        if self._download_running_hid is None:
            self._download_running_hid = GLib.timeout_add(
                80, self.__download_running_cb)

    def __download_running_cb(self):
        print('__DLR')
        progress = downloadmanager.overall_downloads_progress()
        self._download_icon.update(progress)
        if downloadmanager.num_downloads() > 0:
            self._download_icon.props.tooltip = \
                _('{}% Downloaded').format(int(progress*100))
            self._download_icon.props.xo_color = XoColor(None)
            return True
        else:
            GLib.source_remove(self._download_running_hid)
            self._download_running_hid = None
            self._download_icon.props.tooltip = _('No Downloads Running')
            self._download_icon.props.xo_color = XoColor('insensitive')
            return False

    def __key_press_event_cb(self, entry, event):
        self._tabbed_view.current_browser.loading_uri = entry.props.text

    def __switch_page_cb(self, tabbed_view, page, page_num):
        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

    def __page_added_cb(self, notebook, child, pagenum):
        self.entry._search_popdown()

    def _configure_toolbar(self, screen=None):
        # Adapt the toolbars for portrait or landscape mode.

        if screen is None:
            screen = Gdk.Screen.get_default()

        if screen.get_width() < screen.get_height():
            if self._entry_item in self._url_toolbar.toolbar.get_children():
                return

            self.toolbar.remove(self._entry_item)
            self._url_toolbar.toolbar.insert(self._entry_item, -1)

            separator_pos = len(self.toolbar.get_children()) - 1
            self.toolbar.insert(self._toolbar_separator, separator_pos)
            self._toolbar_separator.show()

            self.pack_end(self._url_toolbar, True, True, 0)
            self._url_toolbar.show()

        else:
            if self._entry_item in self.toolbar.get_children():
                return

            self.toolbar.remove(self._toolbar_separator)

            position = len(self.toolbar.get_children()) - 4
            self._url_toolbar.toolbar.remove(self._entry_item)
            self.toolbar.insert(self._entry_item, position)

            self._toolbar_separator.hide()
            self.remove(self._url_toolbar)

    def __screen_size_changed_cb(self, screen):
        self._configure_toolbar(screen)

    def _connect_to_browser(self, browser):
        if self._browser is not None:
            self._browser.disconnect(self._uri_changed_hid)
            self._browser.disconnect(self._load_changed_hid)
            self._browser.disconnect(self._progress_changed_hid)
            self._browser.disconnect(self._security_status_changed_hid)

        self._browser = browser
        if not isinstance(self._browser, DummyBrowser):
            address = self._browser.props.uri or self._browser.loading_uri
        else:
            address = self._browser.props.uri
        self._set_address(address)
        self._set_progress(self._browser.props.estimated_load_progress)
        self._set_loading(self._browser.props.estimated_load_progress < 1.0)
        self._set_security_status(self._browser.security_status)

        is_webkit_browser = isinstance(self._browser, Browser)
        self.entry.props.editable = is_webkit_browser

        self._uri_changed_hid = self._browser.connect('notify::uri',
                                                      self.__uri_changed_cb)
        self._load_changed_hid = self._browser.connect('load-changed',
                                                       self.__load_changed_cb)
        self._progress_changed_hid = self._browser.connect(
            'notify::estimated-load-progress', self.__progress_changed_cb)
        self._security_status_changed_hid = self._browser.connect(
            'security-status-changed', self.__security_status_changed_cb)

        self._update_navigation_buttons()

    def __security_status_changed_cb(self, widget):
        self._set_security_status(widget.security_status)

    def __progress_changed_cb(self, widget, param):
        self._set_progress(widget.props.estimated_load_progress)
        self._set_loading(widget.props.estimated_load_progress < 1.0)

    def _set_security_status(self, security_status):
        # Display security status as a lock icon in the left side of
        # the URL entry.
        if security_status is None:
            self.entry.set_icon_from_pixbuf(iconentry.ICON_ENTRY_PRIMARY, None)
        elif security_status == Browser.SECURITY_STATUS_SECURE:
            self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                          'channel-secure-symbolic')
        elif security_status == Browser.SECURITY_STATUS_INSECURE:
            self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                          'channel-insecure-symbolic')

    def _set_progress(self, progress):
        if progress == 1.0:
            self.entry.set_progress_fraction(0.0)
        else:
            self.entry.set_progress_fraction(progress)

    def _set_address(self, uri):
        if uri is None:
            self.entry.props.address = ''
        else:
            self.entry.props.address = uri

    def __changed_cb(self, iconentry):
        # The WebEntry can be changed when we click on a link, then we
        # have to show the clear icon only if is the user who has
        # changed the entry
        if self.entry.has_focus():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_in_event_cb(self, entry, event):
        if not self._tabbed_view.is_current_page_pdf():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_out_event_cb(self, entry, event):
        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self._show_reload_icon()

    def _show_no_icon(self):
        self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY)

    def _show_stop_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-stop')

    def _show_reload_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-refresh')

    def _show_clear_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-cancel')

    def _update_navigation_buttons(self):
        can_go_back = self._browser.can_go_back()
        self._back.props.sensitive = can_go_back

        can_go_forward = self._browser.can_go_forward()
        self._forward.props.sensitive = can_go_forward

        is_webkit_browser = isinstance(self._browser, Browser)
        self._go_home.props.sensitive = is_webkit_browser
        if is_webkit_browser:
            self._reload_session_history()

        with self._link_add.handler_block(self._link_add_toggled_hid):
            uri = self._browser.get_uri()
            print(self.model.has_link(uri), uri)
            self._link_add.props.active = self.model.has_link(uri)

    def __link_removed_cb(self, model):
        self._update_navigation_buttons()

    def _entry_activate_cb(self, entry):
        url = entry.props.text
        effective_url = self._tabbed_view.normalize_or_autosearch_url(url)
        self._browser.load_uri(effective_url)
        self._browser.loading_uri = effective_url
        self.entry.props.address = effective_url
        self._browser.grab_focus()

    def _go_home_cb(self, button):
        self.emit('go-home')

    def _go_library_cb(self, button):
        self.emit('go-library')

    def _set_home_cb(self, button):
        self._reset_home_menu.set_visible(True)
        self.emit('set-home')

    def _reset_home_cb(self, button):
        self._reset_home_menu.set_visible(False)
        self.emit('reset-home')

    def _go_back_cb(self, button):
        self._browser.go_back()

    def _go_forward_cb(self, button):
        self._browser.go_forward()

    def __uri_changed_cb(self, widget, param):
        self._set_address(widget.get_uri())
        self._update_navigation_buttons()
        filepicker.cleanup_temp_files()

    def __load_changed_cb(self, widget, event):
        self._update_navigation_buttons()

    def _stop_and_reload_cb(self, entry, icon_pos, button):
        if entry.has_focus() and \
                not self._tabbed_view.is_current_page_pdf():
            entry.set_text('')
        else:
            if self._loading:
                self._browser.stop_loading()
            else:
                self._browser.reload()

    def _set_loading(self, loading):
        self._loading = loading

        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self._set_sensitive(True)
                self._show_reload_icon()
            else:
                self._set_sensitive(False)
                self._show_no_icon()

    def _set_sensitive(self, value):
        for widget in self.toolbar:
            if widget not in (self._stop_button, self._link_add):
                widget.set_sensitive(value)

    def _reload_session_history(self):
        back_forward_list = self._browser.get_back_forward_list()
        item_index = 0  # The index of the history item

        # Clear menus in palettes:
        for box_menu in (self._back_box_menu, self._forward_box_menu):
            for menu_item in box_menu.get_children():
                box_menu.remove(menu_item)

        def create_menu_item(history_item):
            """Create a MenuItem for the back or forward palettes."""
            title = history_item.get_title() or _('No Title')
            if not isinstance(title, unicode):
                title = unicode(title, 'utf-8')
            # This is a fix until the Sugar MenuItem is fixed:
            menu_item = PaletteMenuItem(text_label=title)
            menu_item.connect('activate', self._history_item_activated_cb,
                              history_item)
            return menu_item

        back_list = back_forward_list.get_back_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        back_list.reverse()
        for item in back_list:
            menu_item = create_menu_item(item)
            self._back_box_menu.pack_end(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

        # Increment the item index to count the current page:
        item_index += 1

        forward_list = back_forward_list.get_forward_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        forward_list.reverse()
        for item in forward_list:
            menu_item = create_menu_item(item)
            self._forward_box_menu.pack_start(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

    def _history_item_activated_cb(self, menu_item, history_item):
        self._back.get_palette().popdown(immediate=True)
        self._forward.get_palette().popdown(immediate=True)
        # self._browser.set_history_index(index)
        self._browser.go_to_back_forward_list_item(history_item)

    def __link_add_toggled_cb(self, button):
        if button.props.active:
            self.emit('add-link')
        else:
            self.emit('remove-link')

    def inspect_view(self, button):
        page = self._canvas.get_current_page()
        webview = self._canvas.get_children()[page].props.browser

        # If get_inspector returns None, it is not a real WebView
        inspector = webview.get_inspector()
        if inspector is not None:
            # Inspector window will be blank if disabled
            web_settings = webview.get_settings()
            web_settings.props.enable_developer_extras = True

            inspector.show()
            inspector.attach()

    '''
Beispiel #26
0
class ReadToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ReadToolbar'

    def __init__(self):
        GObject.GObject.__init__(self)
        self.back = ToolButton('go-previous')
        self.back.set_tooltip(_('Back'))
        self.back.props.sensitive = False
        palette = self.back.get_palette()
        self.prev_page = MenuItem(text_label= _("Previous page"))
        palette.menu.append(self.prev_page) 
        self.prev_page.show_all()        
        self.back.connect('clicked', self.go_back_cb)
        self.prev_page.connect('activate', self.go_back_cb)
        self.insert(self.back, -1)
        self.back.show()

        self.forward = ToolButton('go-next')
        self.forward.set_tooltip(_('Forward'))
        self.forward.props.sensitive = False
        palette = self.forward.get_palette()
        self.next_page = MenuItem(text_label= _("Next page"))
        palette.menu.append(self.next_page) 
        self.next_page.show_all()        
        self.forward.connect('clicked', self.go_forward_cb)
        self.next_page.connect('activate', self.go_forward_cb)
        self.insert(self.forward, -1)
        self.forward.show()

        num_page_item = Gtk.ToolItem()

        self._num_page_entry = Gtk.Entry()
        self._num_page_entry.set_text('0')
        self._num_page_entry.set_alignment(1)
        self._num_page_entry.connect('insert-text',
                                     self._num_page_entry_insert_text_cb)
        self._num_page_entry.connect('activate',
                                     self._num_page_entry_activate_cb)

        self._num_page_entry.set_width_chars(4)

        num_page_item.add(self._num_page_entry)
        self._num_page_entry.show()

        self.insert(num_page_item, -1)
        num_page_item.show()

        total_page_item = Gtk.ToolItem()

        self._total_page_label = Gtk.Label()

        self._total_page_label.set_text(' / 0')
        total_page_item.add(self._total_page_label)
        self._total_page_label.show()

        self.insert(total_page_item, -1)
        total_page_item.show()

    def _num_page_entry_insert_text_cb(self, entry, text, length, position):
        if not re.match('[0-9]', text):
            entry.emit_stop_by_name('insert-text')
            return True
        return False

    def _num_page_entry_activate_cb(self, entry):
        if entry.props.text:
            page = int(entry.props.text) - 1
        else:
            page = 0

        if page >= self.total_pages:
            page = self.total_pages - 1
        elif page < 0:
            page = 0

        self.current_page = page
        self.activity.set_current_page(page)
        self.activity.show_page(page)
        entry.props.text = str(page + 1)
        self._update_nav_buttons()
        
    def go_back_cb(self, button):
        self.activity.previous_page()
    
    def go_forward_cb(self, button):
        self.activity.next_page()
    
    def _update_nav_buttons(self):
        current_page = self.current_page
        self.back.props.sensitive = current_page > 0
        self.forward.props.sensitive = \
            current_page < self.total_pages - 1
        
        self._num_page_entry.props.text = str(current_page + 1)
        self._total_page_label.props.label = \
            ' / ' + str(self.total_pages)

    def set_total_pages(self, pages):
        self.total_pages = pages
        
    def set_current_page(self, page):
        self.current_page = page
        self._update_nav_buttons()
        
    def set_activity(self, activity):
        self.activity = activity

    def setToggleButtonState(self,button,b,id):
        button.handler_block(id)
        button.set_active(b)
        button.handler_unblock(id)
Beispiel #27
0
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'))
Beispiel #28
0
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        # abiword uses the current directory for all its file dialogs
        os.chdir(os.path.expanduser('~'))

        # create our main abiword canvas
        self.abiword_canvas = DocumentView()
        self._new_instance = True
        toolbar_box = ToolbarBox()

        self.activity_button = ActivityToolbarButton(self)
        toolbar_box.toolbar.insert(self.activity_button, -1)

        separator = Gtk.SeparatorToolItem()
        separator.show()
        self.activity_button.props.page.insert(separator, 2)
        ExportButtonFactory(self, self.abiword_canvas)
        self.activity_button.show()

        edit_toolbar = ToolbarButton()
        edit_toolbar.props.page = EditToolbar(self, toolbar_box)
        edit_toolbar.props.icon_name = 'toolbar-edit'
        edit_toolbar.props.label = _('Edit')
        toolbar_box.toolbar.insert(edit_toolbar, -1)

        view_toolbar = ToolbarButton()
        view_toolbar.props.page = ViewToolbar(self.abiword_canvas)
        view_toolbar.props.icon_name = 'toolbar-view'
        view_toolbar.props.label = _('View')
        toolbar_box.toolbar.insert(view_toolbar, -1)

        # due to http://bugzilla.abisource.com/show_bug.cgi?id=13585
        if self.abiword_canvas.get_version() != '3.0':
            self.speech_toolbar_button = ToolbarButton(icon_name='speak')
            toolbar_box.toolbar.insert(self.speech_toolbar_button, -1)
            self._init_speech()

        separator = Gtk.SeparatorToolItem()
        toolbar_box.toolbar.insert(separator, -1)

        text_toolbar = ToolbarButton()
        text_toolbar.props.page = TextToolbar(self.abiword_canvas)
        text_toolbar.props.icon_name = 'format-text'
        text_toolbar.props.label = _('Text')
        toolbar_box.toolbar.insert(text_toolbar, -1)

        para_toolbar = ToolbarButton()
        para_toolbar.props.page = ParagraphToolbar(self.abiword_canvas)
        para_toolbar.props.icon_name = 'paragraph-bar'
        para_toolbar.props.label = _('Paragraph')
        toolbar_box.toolbar.insert(para_toolbar, -1)

        insert_toolbar = ToolbarButton()
        insert_toolbar.props.page = InsertToolbar(self.abiword_canvas)
        insert_toolbar.props.icon_name = 'insert-table'
        insert_toolbar.props.label = _('Table')
        toolbar_box.toolbar.insert(insert_toolbar, -1)

        image = ToolButton('insert-picture')
        image.set_tooltip(_('Insert Image'))
        self._image_id = image.connect('clicked', self.__image_cb)
        toolbar_box.toolbar.insert(image, -1)

        palette = image.get_palette()
        box = PaletteMenuBox()
        palette.set_content(box)
        box.show()
        menu_item = PaletteMenuItem(_('Floating'))
        menu_item.connect('activate', self.__image_cb, True)
        box.append_item(menu_item)
        menu_item.show()

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_size_request(0, -1)
        separator.set_expand(True)
        separator.show()
        toolbar_box.toolbar.insert(separator, -1)

        stop = StopButton(self)
        toolbar_box.toolbar.insert(stop, -1)

        toolbar_box.show_all()
        self.set_toolbar_box(toolbar_box)

        # add a overlay to be able to show a icon while joining a shared doc
        overlay = Gtk.Overlay()
        overlay.add(self.abiword_canvas)
        overlay.show()

        self._connecting_box = ConnectingBox()
        overlay.add_overlay(self._connecting_box)

        self.set_canvas(overlay)

        # we want a nice border so we can select paragraphs easily
        self.abiword_canvas.set_show_margin(True)

        # Set default font face and size
        self._default_font_face = 'Sans'
        self._default_font_size = 12

        # activity sharing
        self.participants = {}
        self.joined = False

        self.connect('shared', self._shared_cb)

        if self.shared_activity:
            # we are joining the activity
            logger.debug('We are joining an activity')
            # display a icon while joining
            self._connecting_box.show()
            # disable the abi widget
            self.abiword_canvas.set_sensitive(False)
            self._new_instance = False
            self.connect('joined', self._joined_cb)
            self.shared_activity.connect('buddy-joined', self._buddy_joined_cb)
            self.shared_activity.connect('buddy-left', self._buddy_left_cb)
            if self.get_shared():
                self._joined_cb(self)
        else:
            # we are creating the activity
            logger.debug("We are creating an activity")

        self.abiword_canvas.zoom_width()
        self.abiword_canvas.show()
        self.connect_after('map-event', self.__map_activity_event_cb)

        self.abiword_canvas.connect('size-allocate', self.size_allocate_cb)
class SensorToolbar(Gtk.Toolbar):
    ''' The toolbar for specifiying the sensor: sound, resitance, or
    voltage '''

    LOWER = 0.0
    UPPER = 1.0
    STR_DC_R = \
        _("Resistive sensor (connect sensor to pink 'Mic In' on left side \
of XO)"       ) + ' '
    STR_DC_V = \
        _("Voltage sensor (connect sensor to pink 'Mic In' on left side \
of XO)"       ) + ' '
    STR_AC = _('Sound') + ' '
    STR_RESISTANCE = _('Resistance') + ' (' + _('Ohms') + ') '
    STR_VOLTAGE = _('Voltage') + ' (' + _('Volts') + ') '
    STR_TIME = _('Time Base') + ' '
    STR_FREQUENCY = _('Frequency Base') + ' '
    STR_INVERT = ' ' + _('Invert') + ' '
    STR_XAXIS_TEXT = _('X Axis Scale: 1 division = %(division)s %(unit)s')
    # TRANSLATORS: This is milli seconds.
    MS = _('ms')
    # TRANSLATORS: This is Hertz, so 1/second.
    HZ = _('Hz')

    def __init__(self, activity, channels):
        ''' By default, start with resistance mode '''

        super(type(self), self).__init__()

        self.activity = activity
        self._channels = channels
        self._lock_radio_buttons = False
        self._radio_button_pushed = False
        self.values = []
        for i in range(self._channels):
            self.values.append('')

        self.string_for_textbox = ''

        self.gain = 1.0
        self.y_mag = 3.0
        self.capture_gain = CAPTURE_GAIN
        self.mic_boost = MIC_BOOST

        self.mode = 'sound'

        # Set up Time-domain Button
        self.time = RadioToolButton(icon_name='media-audio', group=None)
        self.insert(self.time, -1)
        self.time.set_tooltip(_('Sound'))
        self.time.connect('clicked', self.analog_resistance_voltage_mode_cb,
                          'sound')

        # Set up Resistance Button
        self.resistance = RadioToolButton(icon_name='resistance',
                                          group=self.time)
        if _can_use_dc(self.activity.hw):
            self.insert(self.resistance, -1)
        self.resistance.show()
        self.resistance.set_tooltip(_('Resistance Sensor'))
        self.resistance.connect('clicked',
                                self.analog_resistance_voltage_mode_cb,
                                'resistance')

        # Set up Voltage Button
        self.voltage = RadioToolButton(icon_name='voltage', group=self.time)
        if _can_use_dc(self.activity.hw):
            self.insert(self.voltage, -1)
        self.voltage.set_tooltip(_('Voltage Sensor'))
        self.voltage.connect('clicked', self.analog_resistance_voltage_mode_cb,
                             'voltage')

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = True
        self.insert(separator, -1)

        self._log_value = LOG_TIMER_VALUES[1]
        self.log_label = Gtk.Label(self._log_to_string(self._log_value))
        toolitem = Gtk.ToolItem()
        toolitem.add(self.log_label)
        self.insert(toolitem, -1)

        self._log_button = ToolButton('timer-10')
        self._log_button.set_tooltip(_('Select logging interval'))
        self._log_button.connect('clicked', self._log_selection_cb)
        self.insert(self._log_button, -1)
        self._setup_log_palette()

        # Set up Logging/Stop Logging Button
        self._record = ToolButton('media-record')
        self.insert(self._record, -1)
        self._record.set_tooltip(_('Start logging'))
        self._record.connect('clicked', self.record_control_cb)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = True
        self.insert(separator, -1)

        toolitem = Gtk.ToolItem()
        self.trigger_label = Gtk.Label(_('Trigger'))
        toolitem.add(self.trigger_label)
        self.insert(toolitem, -1)

        # Set up Trigger Combo box
        self.trigger_none = RadioToolButton()
        self.trigger_none.set_icon_name('trigger-none')
        self.insert(self.trigger_none, -1)
        self.trigger_none.set_tooltip(_('None'))
        self.trigger_none.connect('clicked', self.update_trigger_control_cb,
                                  self.activity.wave.TRIGGER_NONE)

        self.trigger_rise = RadioToolButton(group=self.trigger_none)
        self.trigger_rise.set_icon_name('trigger-rise')
        self.insert(self.trigger_rise, -1)
        self.trigger_rise.set_tooltip(_('Rising Edge'))
        self.trigger_rise.connect('clicked', self.update_trigger_control_cb,
                                  self.activity.wave.TRIGGER_POS)

        self.trigger_fall = RadioToolButton(group=self.trigger_none)
        self.trigger_fall.set_icon_name('trigger-fall')
        self.insert(self.trigger_fall, -1)
        self.trigger_fall.set_tooltip(_('Falling Edge'))
        self.trigger_fall.connect('clicked', self.update_trigger_control_cb,
                                  self.activity.wave.TRIGGER_NEG)

        self.show_all()

    def get_log(self):
        return self._log_value

    def get_log_idx(self):
        if self._log_value in LOG_TIMER_VALUES:
            return LOG_TIMER_VALUES.index(self._log_value)
        else:
            return LOG_TIMER_VALUES[0]

    def set_log_idx(self, idx):
        self._log_value = LOG_TIMER_VALUES[idx]
        self.log_label.set_text(self._log_to_string(self._log_value))
        if hasattr(self, '_log_button'):
            self._log_button.set_icon('timer-%d' % (self._log_value))

    def _log_selection_cb(self, widget):
        if self._log_palette:
            if not self._log_palette.is_up():
                self._log_palette.popup(immediate=True)
            else:
                self._log_palette.popdown(immediate=True)
            return

    def _log_to_seconds(self, tenth_seconds):
        return tenth_seconds / 10.

    def _log_to_string(self, tenth_seconds):
        if tenth_seconds in LOG_TIMER_LABELS:
            return LOG_TIMER_LABELS[tenth_seconds]
        else:
            return _('1 second')

    def _setup_log_palette(self):
        self._log_palette = self._log_button.get_palette()

        for tenth_seconds in LOG_TIMER_VALUES:
            text = self._log_to_string(tenth_seconds)
            menu_item = MenuItem(icon_name='timer-%d' % (tenth_seconds),
                                 text_label=text)
            menu_item.connect('activate', self._log_selected_cb, tenth_seconds)
            self._log_palette.menu.append(menu_item)
            menu_item.show()

    def _log_selected_cb(self, button, seconds):
        self.set_log_idx(LOG_TIMER_VALUES.index(seconds))

    def add_frequency_slider(self, toolbox):
        ''' Either on the Sound toolbar or the Main toolbar '''
        self._freq_stepper_up = ToolButton('freq-high')
        self._freq_stepper_up.set_tooltip(_('Zoom out'))
        self._freq_stepper_up.connect('clicked', self._freq_stepper_up_cb)
        self._freq_stepper_up.show()
        self.activity.adjustmentf = Gtk.Adjustment(0.5, self.LOWER, self.UPPER,
                                                   0.01, 0.1, 0)
        self.activity.adjustmentf.connect('value_changed', self.cb_page_sizef)
        self._freq_range = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL,
                                     adjustment=self.activity.adjustmentf)
        self._freq_range.set_inverted(True)
        self._freq_range.set_draw_value(False)
        self._freq_range.set_size_request(120, 15)
        self._freq_range.show()

        self._freq_stepper_down = ToolButton('freq-low')
        self._freq_stepper_down.set_tooltip(_('Zoom in'))
        self._freq_stepper_down.connect('clicked', self._freq_stepper_down_cb)
        self._freq_stepper_down.show()

        self._freq_range_tool = Gtk.ToolItem()
        self._freq_range_tool.add(self._freq_range)
        self._freq_range_tool.show()

        toolbox.add(self._freq_stepper_up)
        toolbox.add(self._freq_range_tool)
        toolbox.add(self._freq_stepper_down)
        return

    def update_trigger_control_cb(self, button, value):
        if button is None:
            value = self.activity.wave.TRIGGER_NONE
        if self.activity.wave.get_fft_mode():
            self.trigger_none.set_active(True)
        else:
            self.activity.wave.set_trigger(value)

    def analog_resistance_voltage_mode_cb(self,
                                          button=None,
                                          mode_to_set='sound'):
        ''' Callback for Analog/Resistance/Voltage Buttons '''
        if self._lock_radio_buttons:
            logging.debug('mode selector locked')
            self._radio_button_pushed = True
            return
        if self.mode == mode_to_set:
            logging.debug('mode already set to %s' % mode_to_set)
            return
        self._lock_radio_buttons = True
        if self.activity.CONTEXT == 'sound':
            self.sound_context_off()
        else:
            self.sensor_context_off()

        # Force time domain when switching modes
        if self.activity.wave.get_fft_mode():
            self.activity.timefreq_control()
        # Turn off logging when switching modes
        if self.activity.audiograb.we_are_logging:
            self.record_control_cb()

        self.set_mode(mode_to_set)
        if mode_to_set == 'sound':
            self.set_sound_context()
        elif mode_to_set == 'resistance':
            self.set_sensor_context()
        elif mode_to_set == 'voltage':
            self.set_sensor_context()
        self.update_string_for_textbox()
        return False

    def unlock_radio_buttons(self):
        ''' Enable radio button selection '''
        logging.debug('unlocking radio buttons')
        if self._radio_button_pushed:
            if self.mode == 'sound':
                self.time.set_active(True)
            elif self.mode == 'resistance':
                self.resistance.set_active(True)
            elif self.mode == 'voltage':
                self.voltage.set_active(True)
        self._lock_radio_buttons = False
        self._radio_button_pushed = False

    def set_mode(self, mode='sound'):
        ''' Set the mixer settings to match the current mode. '''
        self.mode = mode
        self.activity.audiograb.set_sensor_type(self.mode)
        for i in range(self._channels):
            self.values[i] = 0.0
        return

    def get_mode(self):
        ''' Get the mixer settings. '''
        return self.mode

    def _freq_stepper_up_cb(self, button=None):
        ''' Moves the horizontal zoom slider to the left one notch,
        where one notch is 1/100 of the total range. This correspond
        to zooming out as a larger number of Hertz or milliseconds
        will be represented by the same space on the screen. '''
        new_value = self._freq_range.get_value() + \
            (self.UPPER - self.LOWER) / 100.0
        if new_value <= self.UPPER:
            self._freq_range.set_value(new_value)
        else:
            self._freq_range.set_value(self.UPPER)

    def _freq_stepper_down_cb(self, button=None):
        ''' Moves the horizontal zoom slider to the right one notch,
        where one notch is 1/100 of the total range. This corresponds
        to zooming in. '''
        new_value = self._freq_range.get_value() - \
            (self.UPPER - self.LOWER) / 100.0
        if new_value >= self.LOWER:
            self._freq_range.set_value(new_value)
        else:
            self._freq_range.set_value(self.LOWER)

    def cb_page_sizef(self, button=None):
        ''' Callback to scale the frequency range (zoom in and out) '''
        if self._update_page_size_id:
            GObject.source_remove(self._update_page_size_id)
        self._update_page_size_id =\
            GObject.timeout_add(250, self.update_page_size)
        return True

    def update_page_size(self):
        ''' Set up the scaling of the display. '''
        self._update_page_size_id = None
        value = self.activity.adjustmentf.get_value()
        new_value = round(value * 100.0) / 100.0
        if value != new_value:
            self.activity.adjustmentf.set_value(new_value)
            return False
        time_div = 0.001 * max(value, 0.05)
        freq_div = 1000 * max(value, 0.01)
        self.activity.wave.set_div(time_div, freq_div)
        self.update_string_for_textbox()
        return False

    def set_sound_context(self):
        ''' Called when analog sensing is selected '''
        self.set_show_hide_windows(mode='sound')
        GObject.timeout_add(500, self.sound_context_on)
        self.activity.CONTEXT = 'sound'

    def set_sensor_context(self):
        ''' Called when digital sensing is selected '''
        self.set_show_hide_windows(mode='sensor')
        GObject.timeout_add(500, self.sensor_context_on)
        self.activity.CONTEXT = 'sensor'

    def set_show_hide_windows(self, mode='sound'):
        ''' Shows the appropriate window identified by the mode '''
        self.activity.wave.set_context_on()
        for i in range(self._channels):
            self.activity.side_toolbars[i].set_show_hide(True, mode)

    def sensor_context_off(self):
        ''' Called when a DC sensor is no longer selected '''
        # self.activity.audiograb.pause_grabbing()
        self.activity.audiograb.stop_grabbing()

    def sensor_context_on(self):
        ''' Called when a DC sensor is selected '''
        self.update_string_for_textbox()
        self.activity.wave.set_trigger(self.activity.wave.TRIGGER_NONE)
        # self.activity.audiograb.resume_grabbing()
        self.activity.audiograb.start_grabbing()
        return False

    def sound_context_off(self):
        ''' Called when an analog sensor is no longer selected '''
        self.gain, self.y_mag = self.activity.wave.get_mag_params()
        self.capture_gain = self.activity.audiograb.get_capture_gain()
        self.mic_boost = self.activity.audiograb.get_mic_boost()
        self.activity.audiograb.stop_grabbing()

    def sound_context_on(self):
        ''' Called when an analog sensor is selected '''
        self.activity.wave.set_mag_params(self.gain, self.y_mag)
        self.update_string_for_textbox()
        self.update_trigger_control_cb(None, self.activity.wave.TRIGGER_NONE)
        self.activity.audiograb.start_grabbing()
        return False

    def set_sample_value(self, value='', channel=0):
        ''' Write a sample value to the textbox. '''
        self.values[channel] = value
        self.update_string_for_textbox()
        return

    def record_control_cb(self, button=None):
        ''' Depending upon the selected interval, does either a logging
        session, or just logs the current buffer. '''
        if self.activity.audiograb.we_are_logging:
            self.activity.audiograb.set_logging_params(start_stop=False)
            self._record.set_icon_name('media-record')
            self._record.show()
            self._record.set_tooltip(_('Start Recording'))
        else:
            Xscale = (1.00 / self.activity.audiograb.get_sampling_rate())
            Yscale = 0.0
            interval = self._log_value / 10.  # self.interval_convert()
            username = self.activity.nick
            if self.activity.wave.get_fft_mode():
                self.activity.data_logger.start_new_session(
                    username,
                    Xscale,
                    Yscale,
                    self._log_to_string(self._log_value),
                    channels=self._channels,
                    mode='frequency')
            else:
                self.activity.data_logger.start_new_session(
                    username,
                    Xscale,
                    Yscale,
                    self._log_to_string(self._log_value),
                    channels=self._channels,
                    mode=self.mode)
            self.activity.audiograb.set_logging_params(start_stop=True,
                                                       interval=interval)
            self._record.set_icon_name('record-stop')
            self._record.show()
            self._record.set_tooltip(_('Stop Recording'))
            self.activity.new_recording = True

    def update_string_for_textbox(self):
        ''' Update the status field at the bottom of the canvas. '''
        if self.mode == 'resistance':
            string_for_textbox = (self.STR_DC_R + '\n')
            string_for_textbox += self.STR_RESISTANCE
        elif self.mode == 'voltage':
            string_for_textbox = (self.STR_DC_V + '\n')
            string_for_textbox += self.STR_VOLTAGE
        else:
            string_for_textbox = (self.STR_AC + '\t')
        if self.activity.wave.get_fft_mode():
            scalex = self.STR_XAXIS_TEXT % {
                'unit': self.HZ,
                'division': self.activity.wave.freq_div
            }
            string_for_textbox += self.STR_FREQUENCY
            string_for_textbox += ('\n' + scalex)
        elif self.mode == 'sound':
            scalex = self.STR_XAXIS_TEXT % {
                'unit': self.MS,
                'division': self.activity.wave.time_div * 1000
            }
            string_for_textbox += self.STR_TIME
            string_for_textbox += ('\n' + scalex)
        else:
            for i in range(self._channels):
                string_for_textbox += '\t(%s)' % (self.values[i])
        invert = False
        for i in range(self._channels):
            if self.activity.wave.get_invert_state(channel=i):
                invert = True
        if invert:
            string_for_textbox += self.STR_INVERT
        self.activity.text_box.set_label(string_for_textbox)
Beispiel #30
0
class ReadToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ReadToolbar'

    def __init__(self):
        Gtk.Toolbar.__init__(self)

        self.back = ToolButton('go-previous')
        self.back.set_tooltip(_('Back'))
        self.back.props.sensitive = False
        palette = self.back.get_palette()
        self.prev_page = MenuItem(text_label=_("Previous page"))
        palette.menu.append(self.prev_page)
        self.prev_page.show_all()
        self.prev_bookmark = MenuItem(text_label=_("Previous bookmark"))
        palette.menu.append(self.prev_bookmark)
        self.prev_bookmark.show_all()
        self.back.connect('clicked', self.go_back_cb)
        self.prev_page.connect('activate', self.go_back_cb)
        self.prev_bookmark.connect('activate', self.prev_bookmark_activate_cb)
        self.insert(self.back, -1)
        self.back.show()

        self.forward = ToolButton('go-next')
        self.forward.set_tooltip(_('Forward'))
        self.forward.props.sensitive = False
        palette = self.forward.get_palette()
        self.next_page = MenuItem(text_label=_("Next page"))
        palette.menu.append(self.next_page)
        self.next_page.show_all()
        self.next_bookmark = MenuItem(text_label=_("Next bookmark"))
        palette.menu.append(self.next_bookmark)
        self.next_bookmark.show_all()
        self.forward.connect('clicked', self.go_forward_cb)
        self.next_page.connect('activate', self.go_forward_cb)
        self.next_bookmark.connect('activate', self.next_bookmark_activate_cb)
        self.insert(self.forward, -1)
        self.forward.show()

        num_page_item = Gtk.ToolItem()

        self.num_page_entry = Gtk.Entry()
        self.num_page_entry.set_text('0')
        self.num_page_entry.set_alignment(1)
        self.num_page_entry.connect('insert-text',
                                    self.num_page_entry_insert_text_cb)
        self.num_page_entry.connect('activate',
                                    self.num_page_entry_activate_cb)

        self.num_page_entry.set_width_chars(4)

        num_page_item.add(self.num_page_entry)
        self.num_page_entry.show()

        self.insert(num_page_item, -1)
        num_page_item.show()

        total_page_item = Gtk.ToolItem()

        self.total_page_label = Gtk.Label()
        self.total_page_label.set_markup(
            "<span size='14000' foreground='black'>")

        self.total_page_label.set_text(' / 0')
        total_page_item.add(self.total_page_label)
        self.total_page_label.show()

        self.insert(total_page_item, -1)
        total_page_item.show()

        spacer = Gtk.SeparatorToolItem()
        self.insert(spacer, -1)
        spacer.show()

        bookmarkitem = Gtk.ToolItem()
        self.bookmarker = ToggleToolButton('emblem-favorite')
        self.bookmarker.set_tooltip(_('Toggle Bookmark'))
        self.bookmarker_handler_id = self.bookmarker.connect(
            'clicked', self.bookmarker_clicked_cb)

        bookmarkitem.add(self.bookmarker)

        self.insert(bookmarkitem, -1)
        bookmarkitem.show_all()

        underline_item = Gtk.ToolItem()
        self.underline = ToggleToolButton('format-text-underline')
        self.underline.set_tooltip(_('Underline'))
        self.underline.props.sensitive = False
        self.underline_id = self.underline.connect('clicked',
                                                   self.underline_cb)
        underline_item.add(self.underline)
        self.insert(underline_item, -1)
        underline_item.show_all()

    def num_page_entry_insert_text_cb(self, entry, text, length, position):
        if not re.match('[0-9]', text):
            entry.emit_stop_by_name('insert-text')
            return True
        return False

    def num_page_entry_activate_cb(self, entry):
        if entry.props.text:
            page = int(entry.props.text) - 1
        else:
            page = 0

        if page >= self.total_pages:
            page = self.total_pages - 1
        elif page < 0:
            page = 0

        self.current_page = page
        self.activity.set_current_page(page)
        self.activity.show_page(page)
        entry.props.text = str(page + 1)
        self.update_nav_buttons()

    def go_back_cb(self, button):
        self.activity.page_previous()

    def go_forward_cb(self, button):
        self.activity.page_next()

    def update_nav_buttons(self):
        current_page = self.current_page
        self.back.props.sensitive = current_page > 0
        self.forward.props.sensitive = \
            current_page < self.total_pages - 1

        self.num_page_entry.props.text = str(current_page + 1)
        self.total_page_label.props.label = \
            ' / ' + str(self.total_pages)

    def set_total_pages(self, pages):
        self.total_pages = pages

    def set_current_page(self, page):
        self.current_page = page
        self.update_nav_buttons()

    def set_activity(self, activity):
        self.activity = activity

    def prev_bookmark_activate_cb(self, menuitem):
        self.activity.prev_bookmark()

    def next_bookmark_activate_cb(self, menuitem):
        self.activity.next_bookmark()

    def bookmarker_clicked_cb(self, button):
        self.activity.bookmarker_clicked(button)

    def underline_cb(self, button):
        self.activity.underline_clicked(button)

    def setToggleButtonState(self, button, b, id):
        button.handler_block(id)
        button.set_active(b)
        button.handler_unblock(id)

    def update_underline_button(self, state):
        self.setToggleButtonState(self.underline, state, self.underline_id)

    def update_bookmark_button(self, state):
        self.setToggleButtonState(self.bookmarker, state,
                                  self.bookmarker_handler_id)
Beispiel #31
0
class OneSupportActivity(activity.Activity):
    ''' An activity for sending bug reports '''

    def __init__(self, handle):
        ''' Initialize the toolbar '''
        try:
            super(OneSupportActivity, self).__init__(handle)
        except dbus.exceptions.DBusException as e:
            _logger.error(str(e))

        self.connect('realize', self.__realize_cb)

        if hasattr(self, 'metadata') and 'font_size' in self.metadata:
            self.font_size = int(self.metadata['font_size'])
        else:
            self.font_size = 8
        self.zoom_level = self.font_size / float(len(FONT_SIZES))
        _logger.debug('zoom level is %f' % self.zoom_level)

        # _check_gconf_settings()  # For debugging purposes

        self._setup_toolbars()
        self.modify_bg(Gtk.StateType.NORMAL,
                       style.COLOR_WHITE.get_gdk_color())

        self.bundle_path = activity.get_bundle_path()
        self.tmp_path = os.path.join(activity.get_activity_root(), 'tmp')

        self._copy_entry = None
        self._paste_entry = None
        self._about_panel_visible = False
        self._webkit = None
        self._clipboard_text = ''
        self._fixed = None
        self._notify_transfer_status = False

        get_power_manager().inhibit_suspend()
        self._launch_task_master()

    def can_close(self):
        get_power_manager().restore_suspend()
        return True

    def busy_cursor(self):
        self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))

    def reset_cursor(self):
        self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR))

    def _launch_task_master(self):
        # Most things need only be done once
        if self._fixed is None:
            self._fixed = Gtk.Fixed()
            self._fixed.set_size_request(Gdk.Screen.width(),
                                         Gdk.Screen.height())

            # Offsets from the bottom of the screen
            dy1 = 3 * style.GRID_CELL_SIZE
            dy2 = 2 * style.GRID_CELL_SIZE

            self._progress_area = Gtk.Alignment.new(0.5, 0, 0, 0)
            self._progress_area.set_size_request(Gdk.Screen.width(), -1)
            self._fixed.put(self._progress_area, 0, Gdk.Screen.height() - dy2)
            self._progress_area.show()

            self._button_area = Gtk.Alignment.new(0.5, 0, 0, 0)
            self._button_area.set_size_request(Gdk.Screen.width(), -1)
            self._fixed.put(self._button_area, 0, Gdk.Screen.height() - dy1)
            self._button_area.show()

            self._scrolled_window = Gtk.ScrolledWindow()
            self._scrolled_window.set_size_request(
                Gdk.Screen.width(), Gdk.Screen.height() - dy1)
            self._set_scroll_policy()
            self._graphics_area = Gtk.Alignment.new(0.5, 0, 0, 0)
            self._scrolled_window.add_with_viewport(self._graphics_area)
            self._graphics_area.show()
            self._fixed.put(self._scrolled_window, 0, 0)
            self._scrolled_window.show()

            self._task_master = TaskMaster(self)
            self._task_master.show()

            Gdk.Screen.get_default().connect('size-changed',
                                             self._configure_cb)
            self._toolbox.connect('hide', self._resize_hide_cb)
            self._toolbox.connect('show', self._resize_show_cb)

            self._task_master.set_events(Gdk.EventMask.KEY_PRESS_MASK)
            self._task_master.connect('key_press_event',
                                      self._task_master.keypress_cb)
            self._task_master.set_can_focus(True)
            self._task_master.grab_focus()

        self.set_canvas(self._fixed)
        self._fixed.show()

        self._task_master.task_master()

    def reset_scrolled_window_adjustments(self):
        adj = self._scrolled_window.get_hadjustment()
        if adj is not None:
            adj.set_value(0)
        adj = self._scrolled_window.get_vadjustment()
        if adj is not None:
            adj.set_value(0)

    def load_graphics_area(self, widget):
        self._graphics_area.add(widget)

    def load_button_area(self, widget):
        self._button_area.add(widget)

    def load_progress_area(self, widget):
        self._progress_area.add(widget)

    def _load_intro_graphics(self, file_name='generic-problem.html',
                             message=None):
        center_in_panel = Gtk.Alignment.new(0.5, 0, 0, 0)
        url = os.path.join(self.bundle_path, 'html-content', file_name)
        graphics = Graphics()
        if message is None:
            graphics.add_uri('file://' + url)
        else:
            graphics.add_uri('file://' + url + '?MSG=' +
                             utils.get_safe_text(message))
        graphics.set_zoom_level(0.667)
        center_in_panel.add(graphics)
        graphics.show()
        self.set_canvas(center_in_panel)
        center_in_panel.show()

    def _resize_hide_cb(self, widget):
        self._resize_canvas(widget, True)

    def _resize_show_cb(self, widget):
        self._resize_canvas(widget, False)

    def _configure_cb(self, event):
        self._fixed.set_size_request(Gdk.Screen.width(), Gdk.Screen.height())
        self._set_scroll_policy()
        self._resize_canvas(None)
        self._task_master.reload_graphics()

    def _resize_canvas(self, widget, fullscreen=False):
        # When a toolbar is expanded or collapsed, resize the canvas
        # to ensure that the progress bar is still visible.
        if hasattr(self, '_task_master'):
            if self.toolbar_expanded():
                dy1 = 4 * style.GRID_CELL_SIZE
                dy2 = 3 * style.GRID_CELL_SIZE
            else:
                dy1 = 3 * style.GRID_CELL_SIZE
                dy2 = 2 * style.GRID_CELL_SIZE

            if fullscreen:
                dy1 -= 2 * style.GRID_CELL_SIZE
                dy2 -= 2 * style.GRID_CELL_SIZE

            self._scrolled_window.set_size_request(
                Gdk.Screen.width(), Gdk.Screen.height() - dy1)
            self._fixed.move(self._progress_area, 0, Gdk.Screen.height() - dy2)
            self._fixed.move(self._button_area, 0, Gdk.Screen.height() - dy1)

        self._about_panel_visible = False

    def toolbar_expanded(self):
        if self.activity_button.is_expanded():
            return True
        elif self.edit_toolbar_button.is_expanded():
            return True
        elif self.view_toolbar_button.is_expanded():
            return True
        return False

    def get_activity_version(self):
        info_path = os.path.join(self.bundle_path, 'activity', 'activity.info')
        try:
            info_file = open(info_path, 'r')
        except Exception as e:
            _logger.error('Could not open %s: %s' % (info_path, e))
            return 'unknown'

        cp = ConfigParser()
        cp.readfp(info_file)

        section = 'Activity'

        if cp.has_option(section, 'activity_version'):
            activity_version = cp.get(section, 'activity_version')
        else:
            activity_version = 'unknown'
        return activity_version

    def get_uid(self):
        if len(self.volume_data) == 1:
            return self.volume_data[0]['uid']
        else:
            return 'unknown'

    def write_file(self, file_path):
        self.metadata['font_size'] = str(self.font_size)

    def _setup_toolbars(self):
        ''' Setup the toolbars. '''
        self.max_participants = 1  # No sharing

        self._toolbox = ToolbarBox()

        self.activity_button = ActivityToolbarButton(self)
        self.activity_button.connect('clicked', self._resize_canvas)
        self._toolbox.toolbar.insert(self.activity_button, 0)
        self.activity_button.show()

        self.set_toolbar_box(self._toolbox)
        self._toolbox.show()
        self.toolbar = self._toolbox.toolbar

        view_toolbar = Gtk.Toolbar()
        self.view_toolbar_button = ToolbarButton(
            page=view_toolbar,
            label=_('View'),
            icon_name='toolbar-view')
        self.view_toolbar_button.connect('clicked', self._resize_canvas)
        self._toolbox.toolbar.insert(self.view_toolbar_button, 1)
        view_toolbar.show()
        self.view_toolbar_button.show()

        button = ToolButton('view-fullscreen')
        button.set_tooltip(_('Fullscreen'))
        button.props.accelerator = '<Alt>Return'
        view_toolbar.insert(button, -1)
        button.show()
        button.connect('clicked', self._fullscreen_cb)

        self._zoom_in = ToolButton('zoom-in')
        self._zoom_in.set_tooltip(_('Increase size'))
        view_toolbar.insert(self._zoom_in, -1)
        self._zoom_in.show()
        self._zoom_in.connect('clicked', self._zoom_in_cb)

        self._zoom_out = ToolButton('zoom-out')
        self._zoom_out.set_tooltip(_('Decrease size'))
        view_toolbar.insert(self._zoom_out, -1)
        self._zoom_out.show()
        self._zoom_out.connect('clicked', self._zoom_out_cb)

        self._zoom_eq = ToolButton('zoom-original')
        self._zoom_eq.set_tooltip(_('Restore original size'))
        view_toolbar.insert(self._zoom_eq, -1)
        self._zoom_eq.show()
        self._zoom_eq.connect('clicked', self._zoom_eq_cb)

        self._set_zoom_buttons_sensitivity()

        edit_toolbar = Gtk.Toolbar()
        self.edit_toolbar_button = ToolbarButton(
            page=edit_toolbar,
            label=_('Edit'),
            icon_name='toolbar-edit')
        self.edit_toolbar_button.connect('clicked', self._resize_canvas)
        self._toolbox.toolbar.insert(self.edit_toolbar_button, 1)
        edit_toolbar.show()
        self.edit_toolbar_button.show()

        self._copy_button = ToolButton('edit-copy')
        self._copy_button.set_tooltip(_('Copy'))
        self._copy_button.props.accelerator = '<Ctrl>C'
        edit_toolbar.insert(self._copy_button, -1)
        self._copy_button.show()
        self._copy_button.connect('clicked', self._copy_cb)
        self._copy_button.set_sensitive(False)

        self._paste_button = ToolButton('edit-paste')
        self._paste_button.set_tooltip(_('Paste'))
        self._paste_button.props.accelerator = '<Ctrl>V'
        edit_toolbar.insert(self._paste_button, -1)
        self._paste_button.show()
        self._paste_button.connect('clicked', self._paste_cb)
        self._paste_button.set_sensitive(False)

        self._about_button = ToolButton('computer')
        self._about_button.set_tooltip(_('About my computer'))
        self._toolbox.toolbar.insert(self._about_button, -1)
        self._about_button.palette_invoker.props.lock_palette = True
        self._about_button.set_sensitive(True)
        self._about_button.show()
        self._about_button.connect('clicked', self._about_cb)

        about_panel = AboutPanel()
        about_panel.show()
        self._about_palette = self._about_button.get_palette()
        self._about_palette.set_content(about_panel)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)
        self._toolbox.toolbar.insert(separator, -1)
        separator.show()

        stop_button = StopButton(self)
        stop_button.props.accelerator = '<Ctrl>q'
        self._toolbox.toolbar.insert(stop_button, -1)
        stop_button.show()

    def __realize_cb(self, window):
        self.window_xid = window.get_window().get_xid()

    def set_copy_widget(self, webkit=None, text_entry=None):
        # Each task is responsible for setting a widget for copy
        if webkit is not None:
            self._webkit = webkit
        else:
            self._webkit = None
        if text_entry is not None:
            self._copy_entry = text_entry
        else:
            self._copy_entry = None

        self._copy_button.set_sensitive(webkit is not None or
                                        text_entry is not None)

    def _copy_cb(self, button):
        if self._copy_entry is not None:
            self._copy_entry.copy_clipboard()
        elif self._webkit is not None:
            self._webkit.copy_clipboard()
        else:
            _logger.debug('No widget set for copy.')

    def set_paste_widget(self, text_entry=None):
        # Each task is responsible for setting a widget for paste
        if text_entry is not None:
            self._paste_entry = text_entry
        self._paste_button.set_sensitive(text_entry is not None)

    def _paste_cb(self, button):
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
        self.clipboard_text = clipboard.wait_for_text()
        if self._paste_entry is not None:
            self._paste_entry.paste_clipboard()
        else:
            _logger.debug('No widget set for paste (%s).' %
                          self.clipboard_text)

    def _about_cb(self, button):
        if not self._about_palette.is_up() and not self._about_panel_visible:
            self._about_palette.popup(
                immediate=True, state=self._about_palette.SECONDARY)
            self._about_panel_visible = True
        else:
            self._about_palette.popdown(immediate=True)
            self._about_panel_visible = False

    def _fullscreen_cb(self, button):
        ''' Hide the Sugar toolbars. '''
        self.fullscreen()

    def _set_zoom_buttons_sensitivity(self):
        if self.font_size < len(FONT_SIZES) - 1:
            self._zoom_in.set_sensitive(True)
        else:
            self._zoom_in.set_sensitive(False)
        if self.font_size > 0:
            self._zoom_out.set_sensitive(True)
        else:
            self._zoom_out.set_sensitive(False)

        if hasattr(self, '_scrolled_window'):
            self._set_scroll_policy()

    def _set_scroll_policy(self):
        if Gdk.Screen.width() < Gdk.Screen.height() or self.zoom_level > 0.667:
            self._scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
                                             Gtk.PolicyType.AUTOMATIC)
        else:
            self._scrolled_window.set_policy(Gtk.PolicyType.NEVER,
                                             Gtk.PolicyType.AUTOMATIC)

    def _zoom_eq_cb(self, button):
        self.font_size = 8
        self.zoom_level = 0.667
        self._set_zoom_buttons_sensitivity()
        self._task_master.reload_graphics()

    def _zoom_in_cb(self, button):
        if self.font_size < len(FONT_SIZES) - 1:
            self.font_size += 1
            self.zoom_level *= 1.1
        self._set_zoom_buttons_sensitivity()
        self._task_master.reload_graphics()

    def _zoom_out_cb(self, button):
        if self.font_size > 0:
            self.font_size -= 1
            self.zoom_level /= 1.1
        self._set_zoom_buttons_sensitivity()
        self._task_master.reload_graphics()

    def _remove_alert_cb(self, alert, response_id):
        self.remove_alert(alert)

    def _close_alert_cb(self, alert, response_id):
        self.remove_alert(alert)
        if response_id is Gtk.ResponseType.OK:
            self.close()

    def _reboot_alert_cb(self, alert, response_id):
        self.remove_alert(alert)
        if response_id is Gtk.ResponseType.OK:
            try:
                utils.reboot()
            except Exception as e:
                _logger.error('Cannot reboot: %s' % e)

    def _mount_added_cb(self, volume_monitor, device):
        _logger.error('mount added')
        if self.check_volume_data():
            _logger.debug('launching')
            self._launcher()

    def _mount_removed_cb(self, volume_monitor, device):
        _logger.error('mount removed')
        if self.check_volume_data():
            _logger.debug('launching')
            self._launcher()
Beispiel #32
0
class TuningToolbar(Gtk.Toolbar):
    ''' The toolbar for tuning instruments '''
    def __init__(self, activity):
        super(type(self), self).__init__()

        self.activity = activity
        self._show_tuning_line = False
        self._updating_note = True
        self._tuning_tool = None

        self._instrument_button = ToolButton('instruments')
        self._instrument_button.set_tooltip(_('Tune an instrument.'))
        self._instrument_button.connect('clicked', self._button_selection_cb)
        self.insert(self._instrument_button, -1)
        self._setup_instrument_palette()

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = True
        self.insert(separator, -1)

        self._note = 'A'
        self._notes_button = ToolButton('notes')
        self._notes_button.set_tooltip(_('Notes'))
        self._notes_button.connect('clicked', self._button_selection_cb)
        self.insert(self._notes_button, -1)
        self._setup_notes_palette()

        self._octave = 4
        self._octaves_button = ToolButton('octaves')
        self._octaves_button.set_tooltip(_('Octaves'))
        self._octaves_button.connect('clicked', self._button_selection_cb)
        self.insert(self._octaves_button, -1)
        self._setup_octaves_palette()

        # The entry is used to display a note or for direct user input
        self._freq_entry = Gtk.Entry()
        self._freq_entry.set_text('440')  # A
        self._freq_entry_changed_id = self._freq_entry.connect(
            'changed', self._update_freq_entry)
        if hasattr(self._freq_entry, 'set_tooltip_text'):
            self._freq_entry.set_tooltip_text(
                _('Enter a frequency to display.'))
        self._freq_entry.set_width_chars(8)
        self._freq_entry.show()
        toolitem = Gtk.ToolItem()
        toolitem.add(self._freq_entry)
        self.insert(toolitem, -1)
        toolitem.show()

        self._new_tuning_line = ToolButton('tuning-tools')
        self._new_tuning_line.show()
        self.insert(self._new_tuning_line, -1)
        self._new_tuning_line.set_tooltip(_('Show tuning line.'))
        self._new_tuning_line.connect('clicked', self.tuning_line_cb)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = True
        self.insert(separator, -1)

        self._harmonic = ToolButton('harmonics')
        self._harmonic.show()
        self.insert(self._harmonic, -1)
        self._harmonic.set_tooltip(_('Show harmonics.'))
        self._harmonic.connect('clicked', self.harmonic_cb)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = True
        self.insert(separator, -1)

        self._play_tone = ToolButton('media-playback-start')
        self._play_tone.show()
        self.insert(self._play_tone, -1)
        self._play_tone.set_tooltip(_('Play a note.'))
        self._play_tone.connect('clicked', self.play_cb)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)
        self.insert(separator, -1)

        self.label = Gtk.Label(label='')
        self.label.set_use_markup(True)
        self.label.show()
        toolitem = Gtk.ToolItem()
        toolitem.add(self.label)
        self.insert(toolitem, -1)
        toolitem.show()

        self.show_all()

    def _update_note(self):
        ''' Calculate the frequency based on note and octave '''
        if not hasattr(self, '_freq_entry'):  # Still setting up toolbar
            return
        i = self._octave * 12 + NOTES.index(self._note)
        freq = A0 * pow(TWELTHROOT2, i)
        self._updating_note = True
        self._freq_entry.set_text('%0.3f' % (freq))
        self.label.set_markup(
            SPAN %
            (style.COLOR_WHITE.get_html(), self._note + str(self._octave)))
        if self._show_tuning_line:
            self.activity.wave.tuning_line = freq
        return

    def _update_freq_entry(self, widget):
        # Calculate a note from a frequency
        if not self._updating_note:  # Only if user types in a freq.
            try:
                freq = float(self._freq_entry.get_text())
                # Only consider notes in piano range
                if freq < A0 * 0.97:
                    self.label.set_text('< A0')
                    return
                if freq > C8 * 1.03:
                    self.label.set_text('> C8')
                    return
                self.label.set_markup(freq_note(freq, flatsharp=True))
            except ValueError:
                return

        self._updating_note = False

    def _button_selection_cb(self, widget):
        palette = widget.get_palette()
        if palette:
            if not palette.is_up():
                palette.popup(immediate=True)
            else:
                palette.popdown(immediate=True)
            return

    def _setup_notes_palette(self):
        self._notes_palette = self._notes_button.get_palette()

        for note in NOTES:
            menu_item = MenuItem(icon_name='', text_label=note)
            menu_item.connect('activate', self._note_selected_cb, note)
            self._notes_palette.menu.append(menu_item)
            menu_item.show()

    def _note_selected_cb(self, widget, note):
        self._note = note
        self._update_note()

    def _setup_octaves_palette(self):
        self._octaves_palette = self._octaves_button.get_palette()

        for octave in range(9):
            menu_item = MenuItem(icon_name='', text_label=str(octave))
            menu_item.connect('activate', self._octave_selected_cb, octave)
            self._octaves_palette.menu.append(menu_item)
            menu_item.show()

    def _octave_selected_cb(self, widget, octave):
        self._octave = octave
        self._update_note()

    def _setup_instrument_palette(self):
        self.instrument_palette = self._instrument_button.get_palette()

        self.instrument = []
        for k in INSTRUMENT_DICT.keys():
            self.instrument.append(k)
            menu_item = MenuItem(icon_name='', text_label=k)
            menu_item.connect('activate', self.instrument_selected_cb, k)
            self.instrument_palette.menu.append(menu_item)
            menu_item.show()

    def instrument_selected_cb(self, button, instrument):
        ''' Callback for instrument control '''
        logging.debug(instrument)
        if self._tuning_tool is not None:
            self.remove(self._tuning_tool)

        # Always remove previous buttons
        if hasattr(self, '_tuning_button'):
            self.remove(self._tuning_button)
        self.remove(self._notes_button)
        self.remove(self._octaves_button)

        if instrument == _('None'):
            self.activity.wave.instrument = None

            # Restore the notes, octaves buttons
            if hasattr(self, '_notes_button'):
                self.insert(self._notes_button, 2)
                self.insert(self._octaves_button, 3)
            return

        self.activity.wave.instrument = instrument

        # If we are not already in freq. base, switch.
        if not self.activity.wave.get_fft_mode():
            self.activity.timefreq_control()

        # Add a Tuning palette for this instrument
        self._tuning_button = ToolButton('notes')
        self._tuning_button.set_tooltip(instrument)
        self._tuning_button.connect('clicked', self._button_selection_cb)
        self.insert(self._tuning_button, 2)
        self._setup_tuning_palette(instrument)

    def _setup_tuning_palette(self, instrument):
        self._tuning_palette = self._tuning_button.get_palette()

        self.tuning = []
        self.tuning.append(_('All notes'))
        menu_item = MenuItem(icon_name='', text_label=_('All notes'))
        menu_item.connect('activate', self._tuning_selected_cb, instrument, -1)
        self._tuning_palette.menu.append(menu_item)
        menu_item.show()

        for i, f in enumerate(INSTRUMENT_DICT[instrument]):
            self.tuning.append(freq_note(f))
            menu_item = MenuItem(icon_name='', text_label=freq_note(f))
            menu_item.connect('activate', self._tuning_selected_cb, instrument,
                              i)
            self._tuning_palette.menu.append(menu_item)
            menu_item.show()

        self.show_all()

    def _tuning_selected_cb(self, widget, instrument, fidx):
        ''' Update note '''
        if not hasattr(self, '_freq_entry'):  # Still setting up toolbar?
            return

        if instrument not in INSTRUMENT_DICT:
            return

        if fidx == -1:  # All notes
            self.activity.wave.instrument = instrument
            self.activity.wave.tuning_line = 0.0
            self._new_tuning_line.set_icon_name('tuning-tools')
            self._new_tuning_line.set_tooltip(_('Show tuning line.'))
            self._show_tuning_line = False
        else:
            freq = INSTRUMENT_DICT[instrument][fidx]
            self.activity.wave.instrument = None
            self.activity.wave.tuning_line = freq
            self._new_tuning_line.set_icon_name('tuning-tools-off')
            self._new_tuning_line.set_tooltip(_('Hide tuning line.'))
            self._show_tuning_line = True

        # For consistency, update the freq_entry to make it audible too
        self._freq_entry.set_text(str(self.activity.wave.tuning_line))

        self._updating_note = False

    def harmonic_cb(self, *args):
        ''' Callback for harmonics control '''
        self.activity.wave.harmonics = not self.activity.wave.harmonics
        if self.activity.wave.harmonics:
            self._harmonic.set_icon_name('harmonics-off')
            self._harmonic.set_tooltip(_('Hide harmonics.'))
            if self.activity.wave.instrument is None and \
               self.activity.wave.tuning_line == 0.0:
                self._load_tuning_line()
        else:
            self._harmonic.set_icon_name('harmonics')
            self._harmonic.set_tooltip(_('Show harmonics.'))

    def tuning_line_cb(self, *args):
        ''' Callback for tuning insert '''
        if self._show_tuning_line:
            self.activity.wave.tuning_line = 0.0
            self._new_tuning_line.set_icon_name('tuning-tools')
            self._new_tuning_line.set_tooltip(_('Show tuning line.'))
            self._show_tuning_line = False
        else:
            self._load_tuning_line()

    def _load_tuning_line(self):
        ''' Read the freq entry and use value to set tuning line '''
        freq = self._freq_entry.get_text()
        try:
            self.activity.wave.tuning_line = float(freq)
            if freq < 0:
                freq = -freq
            self._new_tuning_line.set_icon_name('tuning-tools-off')
            self._new_tuning_line.set_tooltip(_('Hide tuning line.'))
            self._show_tuning_line = True
        except ValueError:
            self.activity.wave.tuning_line = 0.0
            self._freq_entry.set_text('0')
        # If we are not already in freq. base, switch.
        if not self.activity.wave.get_fft_mode():
            self.activity.timefreq_control()

    def play_cb(self, *args):
        ''' Save settings, turn off display, and then play a tone at
        the current frequency '''
        channels = []
        for c in range(self.activity.audiograb.channels):
            channels.append(self.activity.wave.get_visibility(channel=c))
            self.activity.wave.set_visibility(False, channel=c)
        wave_status = self.activity.wave.get_active()
        self.activity.wave.set_context_off()
        self.activity.wave.set_active(False)
        if self.activity.hw in [XO4, XO175]:
            self.activity.audiograb.stop_grabbing()

        freq = float(self._freq_entry.get_text())
        GLib.timeout_add(200, self.play_sound, freq, channels, wave_status)

    def play_sound(self, freq, channels, wave_status):
        ''' Play the sound and then restore wave settings '''
        self._play_sinewave(freq, 5000, 1)

        if self.activity.hw in [XO4, XO175]:
            self.activity.sensor_toolbar.set_mode('sound')
            self.activity.sensor_toolbar.set_sound_context()
            self.activity.audiograb.start_grabbing()
        for c in range(self.activity.audiograb.channels):
            self.activity.wave.set_visibility(channels[c], channel=c)
        self.activity.wave.set_context_on()
        self.activity.wave.set_active(wave_status)

    def _play_sinewave(self, pitch, amplitude=5000, duration=1):
        """ Create a Csound score to play a sine wave. """
        self.orchlines = []
        self.scorelines = []
        self.instrlist = []

        try:
            pitch = abs(float(pitch))
            amplitude = abs(float(amplitude))
            duration = abs(float(duration))
        except ValueError:
            logging.error('bad args to _play_sinewave')
            return

        self._prepare_sinewave(pitch, amplitude, duration)

        path = os.path.join(self.activity.get_activity_root(), 'instance',
                            'tmp.csd')
        # Create a csound file from the score.
        self._audio_write(path)

        # Play the csound file.
        check_output(['csound', path], 'call to csound failed?')

    def _prepare_sinewave(self,
                          pitch,
                          amplitude,
                          duration,
                          starttime=0,
                          pitch_envelope=99,
                          amplitude_envelope=100,
                          instrument=1):

        pitenv = pitch_envelope
        ampenv = amplitude_envelope
        if 1 not in self.instrlist:
            self.orchlines.append("instr 1\n")
            self.orchlines.append("kpitenv oscil 1, 1/p3, p6\n")
            self.orchlines.append("aenv oscil 1, 1/p3, p7\n")
            self.orchlines.append("asig oscil p5*aenv, p4*kpitenv, p8\n")
            self.orchlines.append("out asig\n")
            self.orchlines.append("endin\n\n")
            self.instrlist.append(1)

        self.scorelines.append(
            "i1 %s %s %s %s %s %s %s\n" %
            (str(starttime), str(duration), str(pitch), str(amplitude),
             str(pitenv), str(ampenv), str(instrument)))

    def _audio_write(self, file):
        """ Compile a .csd file. """

        csd = open(file, "w")
        csd.write("<CsoundSynthesizer>\n\n")
        csd.write("<CsOptions>\n")
        csd.write("-+rtaudio=alsa -odevaudio -m0 -d -b256 -B512\n")
        csd.write("</CsOptions>\n\n")
        csd.write("<CsInstruments>\n\n")
        csd.write("sr=16000\n")
        csd.write("ksmps=50\n")
        csd.write("nchnls=1\n\n")
        for line in self.orchlines:
            csd.write(line)
        csd.write("\n</CsInstruments>\n\n")
        csd.write("<CsScore>\n\n")
        csd.write("f1 0 2048 10 1\n")
        csd.write("f2 0 2048 10 1 0 .33 0 .2 0 .143 0 .111\n")
        csd.write("f3 0 2048 10 1 .5 .33 .25 .2 .175 .143 .125 .111 .1\n")
        csd.write("f10 0 2048 10 1 0 0 .3 0 .2 0 0 .1\n")
        csd.write("f99 0 2048 7 1 2048 1\n")
        csd.write("f100 0 2048 7 0. 10 1. 1900 1. 132 0.\n")
        csd.write(self.scorelines.pop())
        csd.write("e\n")
        csd.write("\n</CsScore>\n")
        csd.write("\n</CsoundSynthesizer>")
        csd.close()
Beispiel #33
0
class TextAttributesToolbar(Gtk.Toolbar):
    def __init__(self, main_area):

        Gtk.Toolbar.__init__(self)

        self._main_area = main_area
        self._font_list = ['ABC123', 'Sans', 'Serif', 'Monospace', 'Symbol']
        self._font_sizes = [
            '8', '9', '10', '11', '12', '14', '16', '20', '22', '24', '26',
            '28', '36', '48', '72'
        ]

        self.font_button = ToolButton('font-text')
        self.font_button.set_tooltip(_('Select font'))
        self.font_button.connect('clicked', self.__font_selection_cb)
        self.insert(self.font_button, -1)
        self._setup_font_palette()

        self.insert(Gtk.SeparatorToolItem(), -1)

        self.font_size_up = ToolButton('resize+')
        self.font_size_up.set_tooltip(_('Bigger'))
        self.font_size_up.connect('clicked', self.__font_sizes_cb, True)
        self.insert(self.font_size_up, -1)

        if len(self._main_area.selected) > 0:
            font_size = self._main_area.font_size

        else:
            font_size = utils.default_font_size

        self.size_label = Gtk.Label(str(font_size))
        self.size_label.show()
        toolitem = Gtk.ToolItem()
        toolitem.add(self.size_label)
        toolitem.show()
        self.insert(toolitem, -1)

        self.font_size_down = ToolButton('resize-')
        self.font_size_down.set_tooltip(_('Smaller'))
        self.font_size_down.connect('clicked', self.__font_sizes_cb, False)
        self.insert(self.font_size_down, -1)

        self.insert(Gtk.SeparatorToolItem(), -1)

        self.bold = ToolButton('bold-text')
        self.bold.set_tooltip(_('Bold'))
        self.bold.connect('clicked', self.__bold_cb)
        self.insert(self.bold, -1)

        self.italics = ToolButton('italics-text')
        self.italics.set_tooltip(_('Italics'))
        self.italics.connect('clicked', self.__italics_cb)
        self.insert(self.italics, -1)

        self.underline = ToolButton('underline-text')
        self.underline.set_tooltip(_('Underline'))
        self.underline.connect('clicked', self.__underline_cb)
        self.insert(self.underline, -1)

        foreground_color = ColorToolButton()
        foreground_color.set_title(_('Set font color'))
        foreground_color.connect('color-set', self.__foreground_color_cb)
        self.insert(foreground_color, -1)

        bakground_color = ColorToolButton()
        bakground_color.set_title(_('Set background color'))
        bakground_color.connect('color-set', self.__background_color_cb)
        bakground_color.set_color(Gdk.Color(65535, 65535, 65535))
        self.insert(bakground_color, -1)

        self.show_all()

    def __font_selection_cb(self, widget):
        if self._font_palette:
            if not self._font_palette.is_up():
                self._font_palette.popup(immediate=True,
                                         state=self._font_palette.SECONDARY)
            else:
                self._font_palette.popdown(immediate=True)
            return

    def _init_font_list(self):
        self._font_white_list = []
        self._font_white_list.extend(DEFAULT_FONTS)

        # check if there are a user configuration file
        if not os.path.exists(USER_FONTS_FILE_PATH):
            # verify if exists a file in /etc
            if os.path.exists(GLOBAL_FONTS_FILE_PATH):
                shutil.copy(GLOBAL_FONTS_FILE_PATH, USER_FONTS_FILE_PATH)

        if os.path.exists(USER_FONTS_FILE_PATH):
            # get the font names in the file to the white list
            fonts_file = open(USER_FONTS_FILE_PATH)
            # get the font names in the file to the white list
            for line in fonts_file:
                self._font_white_list.append(line.strip())
            # monitor changes in the file
            gio_fonts_file = Gio.File.new_for_path(USER_FONTS_FILE_PATH)
            self.monitor = gio_fonts_file.monitor_file(0, None)
            self.monitor.set_rate_limit(5000)
            self.monitor.connect('changed', self._reload_fonts)

    def _reload_fonts(self, monitor, gio_file, other_file, event):
        if event != Gio.FileMonitorEvent.CHANGES_DONE_HINT:
            return

        self._font_white_list = []
        self._font_white_list.extend(DEFAULT_FONTS)
        fonts_file = open(USER_FONTS_FILE_PATH)
        for line in fonts_file:
            self._font_white_list.append(line.strip())
        # update the menu
        for child in self._font_palette.menu.get_children():
            self._font_palette.menu.remove(child)
            child = None
        context = self.get_pango_context()
        tmp_list = []
        for family in context.list_families():
            name = family.get_name()
            if name in self._font_white_list:
                tmp_list.append(name)
        for font in sorted(tmp_list):
            menu_item = MyMenuItem(image=FontImage(font.replace(' ', '-')),
                                   text_label=font)
            menu_item.connect('activate', self.__font_selected_cb, font)
            self._font_palette.menu.append(menu_item)
            menu_item.show()

        return False

    def _setup_font_palette(self):
        self._init_font_list()
        context = self._main_area.pango_context
        for family in context.list_families():
            name = Pango.FontDescription(family.get_name()).to_string()
            if name not in self._font_list and \
                    name in self._font_white_list:
                self._font_list.append(name)

        self._font_palette = self.font_button.get_palette()
        for font in sorted(self._font_list):
            menu_item = MyMenuItem(image=FontImage(font.replace(' ', '-')),
                                   text_label=font)
            menu_item.connect('activate', self.__font_selected_cb, font)
            self._font_palette.menu.append(menu_item)
            menu_item.show()

    def __font_selected_cb(self, widget, font_name):
        if not hasattr(self._main_area, 'font_name'):
            return
        if len(self._main_area.selected) > 0:
            font_size = self._main_area.font_size
        else:
            font_size = utils.default_font_size
        self._main_area.set_font(font_name, font_size)
        self._main_area.font_name = font_name
        self._main_area.font_size = font_size

    def __attribute_values(self):
        thought = self._main_area.selected[0]
        return thought.attributes.copy()

    def __font_sizes_cb(self, button, increase):
        if not hasattr(self._main_area, 'font_size'):
            return
        if len(self._main_area.selected) < 1:
            return
        font_size = self._main_area.font_size
        if font_size in self._font_sizes:
            i = self._font_sizes.index(font_size)
            if increase:
                if i < len(self._font_sizes) - 2:
                    i += 1
            else:
                if i > 0:
                    i -= 1
        else:
            i = self._font_sizes.index(utils.default_font_size)

        font_size = self._font_sizes[i]
        self.size_label.set_text(str(font_size))
        self.font_size_down.set_sensitive(i != 0)
        self.font_size_up.set_sensitive(i < len(self._font_sizes) - 2)
        self._main_area.set_font(self._main_area.font_name, font_size)

    def __bold_cb(self, button):
        if len(self._main_area.selected) < 1:
            return
        value = not self.__attribute_values()["bold"]
        self._main_area.set_bold(value)

    def __italics_cb(self, button):
        if len(self._main_area.selected) < 1:
            return

        value = not self.__attribute_values()["italic"]
        self._main_area.set_italics(value)

    def __underline_cb(self, button):
        if len(self._main_area.selected) < 1:
            return
        value = not self.__attribute_values()["underline"]
        self._main_area.set_underline(value)

    def __foreground_color_cb(self, button):
        color = button.get_color()
        self._main_area.set_foreground_color(color)

    def __background_color_cb(self, button):
        color = button.get_color()
        self._parent._main_area.set_background_color(color)

    def change_active_font(self):
        # TODO: update the toolbar
        return
class GNUChessActivity(activity.Activity):
    ''' Gnuchess interface from Sugar '''
    def __init__(self, handle):
        ''' Initialize the toolbars and the gnuchess '''
        try:
            super(GNUChessActivity, self).__init__(handle)
        except dbus.exceptions.DBusException as e:
            _logger.error(str(e))

        self.game_data = None
        self.playing_white = True
        self.playing_mode = 'easy'
        self.playing_robot = True
        self.showing_game_history = False
        self._restoring = True
        self.stopwatch_running = False
        self.time_interval = None
        self.timer_panel_visible = False

        self.nick = profile.get_nick_name()
        if profile.get_color() is not None:
            self.colors = profile.get_color().to_string().split(',')
        else:
            self.colors = ['#A0FFA0', '#FF8080']
        self.buddy = None
        self.opponent_colors = None

        self.hardware = get_hardware()
        self._setup_toolbars()
        self._setup_dispatch_table()

        # Create a canvas
        canvas = Gtk.DrawingArea()
        canvas.set_size_request(Gdk.Screen.width(), Gdk.Screen.height())
        self.set_canvas(canvas)
        canvas.show()
        self.show_all()

        self.old_cursor = self.get_window().get_cursor()

        self._gnuchess = Gnuchess(canvas,
                                  parent=self,
                                  path=activity.get_bundle_path(),
                                  colors=self.colors)

        self.connect('shared', self._shared_cb)
        self.connect('joined', self._joined_cb)
        self._restoring = False

        self.collab = CollabWrapper(self)
        self.collab.connect('message', self._message_cb)
        self.collab.connect('joined', self._joined_cb)
        self.collab.setup()

        # Send the nick to our opponent
        if not self.collab.props.leader:
            self.send_nick()
            # And let the sharer know we've joined
            self.send_join()

        if self.game_data is not None:  # 'saved_game' in self.metadata:
            self._restore()
        else:
            self._gnuchess.new_game()

    def set_data(self, data):
        pass

    def get_data(self):
        return None

    def _alert_cancel_cb(self, alert, response_id):
        self.remove_alert(alert)

    def restore_cursor(self):
        ''' No longer thinking, so restore standard cursor. '''
        self.get_window().set_cursor(self.old_cursor)

    def set_thinking_cursor(self):
        ''' Thinking, so set watch cursor. '''
        self.old_cursor = self.get_window().get_cursor()
        Watch = Gdk.Cursor(Gdk.CursorType.WATCH)
        self.get_window().set_cursor(Watch)

    def _setup_toolbars(self):
        ''' Setup the toolbars. '''
        self.max_participants = 2

        self.edit_toolbar = Gtk.Toolbar()
        self.view_toolbar = Gtk.Toolbar()
        self.adjust_toolbar = Gtk.Toolbar()
        self.custom_toolbar = Gtk.Toolbar()

        toolbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        toolbox.toolbar.insert(activity_button, 0)
        activity_button.show()

        edit_toolbar_button = ToolbarButton(label=_("Edit"),
                                            page=self.edit_toolbar,
                                            icon_name='toolbar-edit')
        self.edit_toolbar.show()
        toolbox.toolbar.insert(edit_toolbar_button, -1)
        edit_toolbar_button.show()

        view_toolbar_button = ToolbarButton(label=_("View"),
                                            page=self.view_toolbar,
                                            icon_name='toolbar-view')
        self.view_toolbar.show()
        toolbox.toolbar.insert(view_toolbar_button, -1)
        view_toolbar_button.show()

        adjust_toolbar_button = ToolbarButton(label=_('Adjust'),
                                              page=self.adjust_toolbar,
                                              icon_name='preferences-system')
        self.adjust_toolbar.show()
        toolbox.toolbar.insert(adjust_toolbar_button, -1)
        adjust_toolbar_button.show()

        custom_toolbar_button = ToolbarButton(label=_("Custom"),
                                              page=self.custom_toolbar,
                                              icon_name='view-source')
        self.custom_toolbar.show()
        toolbox.toolbar.insert(custom_toolbar_button, -1)
        custom_toolbar_button.show()

        self.set_toolbar_box(toolbox)
        toolbox.show()
        self.toolbar = toolbox.toolbar

        adjust_toolbar_button.set_expanded(True)

        button_factory('edit-copy',
                       self.edit_toolbar,
                       self._copy_cb,
                       tooltip=_('Copy'),
                       accelerator='<Ctrl>c')

        button_factory('edit-paste',
                       self.edit_toolbar,
                       self._paste_cb,
                       tooltip=_('Paste'),
                       accelerator='<Ctrl>v')

        button_factory('view-fullscreen',
                       self.view_toolbar,
                       self.do_fullscreen_cb,
                       tooltip=_('Fullscreen'),
                       accelerator='<Alt>Return')

        button_factory('media-playback-start',
                       self.view_toolbar,
                       self._play_history_cb,
                       tooltip=_('Play game history'))

        self.history_button = button_factory('list-numbered',
                                             self.view_toolbar,
                                             self._show_history_cb,
                                             tooltip=_('Show game history'))

        separator_factory(self.view_toolbar, False, True)

        label_factory(self.view_toolbar, _('White: '))
        self.white_entry = entry_factory('',
                                         self.view_toolbar,
                                         tooltip=_("White's move"))

        separator_factory(self.view_toolbar, False, False)

        label_factory(self.view_toolbar, _('Black: '))
        self.black_entry = entry_factory('',
                                         self.view_toolbar,
                                         tooltip=_("Black's move"))

        separator_factory(self.view_toolbar, False, True)

        skin_button1 = radio_factory('white-knight',
                                     self.view_toolbar,
                                     self.do_default_skin_cb,
                                     tooltip=_('Default pieces'),
                                     group=None)

        skin_button2 = radio_factory('white-knight-sugar',
                                     self.view_toolbar,
                                     self.do_sugar_skin_cb,
                                     tooltip=_('Sugar-style pieces'),
                                     group=skin_button1)
        xocolors = XoColor(','.join(self.colors))
        icon = Icon(icon_name='white-knight-sugar', xo_color=xocolors)
        icon.show()
        skin_button2.set_icon_widget(icon)

        self.skin_button3 = radio_factory('white-knight-custom',
                                          self.view_toolbar,
                                          self.do_custom_skin_cb,
                                          tooltip=_('Custom pieces'),
                                          group=skin_button1)
        skin_button1.set_active(True)

        self.play_white_button = radio_factory('white-rook',
                                               self.adjust_toolbar,
                                               self._play_white_cb,
                                               group=None,
                                               tooltip=_('Play White'))

        self.play_black_button = radio_factory('black-rook',
                                               self.adjust_toolbar,
                                               self._play_black_cb,
                                               group=self.play_white_button,
                                               tooltip=_('Play Black'))

        self.play_white_button.set_active(True)

        separator_factory(self.adjust_toolbar, False, True)

        self.easy_button = radio_factory('beginner',
                                         self.adjust_toolbar,
                                         self._easy_cb,
                                         group=None,
                                         tooltip=_('Beginner'))

        self.hard_button = radio_factory('expert',
                                         self.adjust_toolbar,
                                         self._hard_cb,
                                         group=self.easy_button,
                                         tooltip=_('Expert'))

        self.easy_button.set_active(True)

        separator_factory(self.adjust_toolbar, False, True)

        self.robot_button = radio_factory(
            'robot',
            self.adjust_toolbar,
            self._robot_cb,
            group=None,
            tooltip=_('Play against the computer'))

        self.human_button = radio_factory('human',
                                          self.adjust_toolbar,
                                          self._human_cb,
                                          group=self.robot_button,
                                          tooltip=_('Play against a person'))

        separator_factory(self.adjust_toolbar, False, False)

        self.opponent = label_factory(self.adjust_toolbar, '')

        separator_factory(self.adjust_toolbar, False, True)

        self.timer_button = ToolButton('timer-0')
        self.timer_button.set_tooltip(_('Timer'))
        self.timer_button.connect('clicked', self._timer_button_cb)
        self.toolbar.insert(self.timer_button, -1)
        self._setup_timer_palette()
        self.timer_button.show()
        self.timer_button.set_sensitive(True)

        self.robot_button.set_active(True)

        button_factory('new-game',
                       self.toolbar,
                       self._new_gnuchess_cb,
                       tooltip=_('New game'))

        button_factory('edit-undo',
                       self.toolbar,
                       self._undo_cb,
                       tooltip=_('Undo'))

        button_factory('hint', self.toolbar, self._hint_cb, tooltip=_('Hint'))

        separator_factory(self.toolbar, False, False)
        self.status = label_factory(self.toolbar, '', width=150)
        self.status.set_label(_("It is White's move."))

        separator_factory(toolbox.toolbar, True, False)
        stop_button = StopButton(self)
        stop_button.props.accelerator = '<Ctrl>q'
        toolbox.toolbar.insert(stop_button, -1)
        stop_button.show()

        for piece in list(PIECES.keys()):
            for color in ['white', 'black']:
                button_factory('%s-%s' % (color, piece),
                               self.custom_toolbar,
                               self._reskin_cb,
                               cb_arg='%s_%s' % (color, piece),
                               tooltip=PIECES[piece][color])

    def do_default_skin_cb(self, button=None):
        for piece in list(PIECES.keys()):
            for color in ['white', 'black']:
                self._gnuchess.reskin_from_file(
                    '%s_%s' % (color, piece), '%s/icons/%s-%s.svg' %
                    (activity.get_bundle_path(), color, piece))

    def _black_pieces(self, colors):
        for piece in list(PIECES.keys()):
            self._gnuchess.reskin_from_svg('black_%s' % piece,
                                           colors,
                                           bw='#000000')

    def _white_pieces(self, colors):
        for piece in list(PIECES.keys()):
            self._gnuchess.reskin_from_svg('white_%s' % piece,
                                           colors,
                                           bw='#ffffff')

    def do_sugar_skin_cb(self, button=None):
        colors = self.colors
        if not self._gnuchess.we_are_sharing:
            self._black_pieces(colors)
            self._white_pieces(colors)
        else:
            if self.playing_white:
                self._white_pieces(colors)
                if self.opponent_colors is not None:
                    colors = self.opponent_colors
                self._black_pieces(colors)
            else:
                self._black_pieces(colors)
                if self.opponent_colors is not None:
                    colors = self.opponent_colors
                self._white_pieces(colors)

    def do_custom_skin_cb(self, button=None):
        for piece in list(PIECES.keys()):
            for color in ['white', 'black']:
                name = '%s_%s' % (color, piece)
                if name in self.metadata:
                    id = self.metadata[name]
                    jobject = datastore.get(id)
                    if jobject is not None and jobject.file_path is not None:
                        self._do_reskin(name, jobject.file_path)

    def _do_reskin(self, name, file_path):
        ''' If we are sharing, only reskin pieces of your color '''
        if self._gnuchess.we_are_sharing and self.buddy is not None:
            if 'white' in name and self.playing_white:
                pixbuf = self._gnuchess.reskin_from_file(name,
                                                         file_path,
                                                         return_pixbuf=True)
                self.send_piece(name, pixbuf)
            elif 'black' in name and not self.playing_white:
                pixbuf = self._gnuchess.reskin_from_file(name,
                                                         file_path,
                                                         return_pixbuf=True)
                self.send_piece(name, pixbuf)
        else:
            self._gnuchess.reskin_from_file(name, file_path)
        return

    def _timer_button_cb(self, button):
        if not self.timer_palette.is_up() and not self.timer_panel_visible:
            self.timer_palette.popup(immediate=True)
            self.timer_panel_visible = True
        else:
            self.timer_palette.popdown(immediate=True)
            self.timer_panel_visible = False

    def _setup_timer_palette(self):
        self.timer_values = [None, 30, 180, 600]
        self.timer_tooltips = [
            '', _('30 seconds'),
            _('3 minutes'),
            _('10 minutes')
        ]
        self.timer_labels = [
            _('Disabled'),
            # TRANS: Lightning chess 30 seconds between moves
            _('Lightning: %d seconds') % (30),
            # TRANS: Blitz chess 3 minutes between moves
            _('Blitz: %d minutes') % (3),
            # TRANS: Tournament chess 10 minutes between moves
            _('Tournament: %d minutes') % (10)
        ]
        self.timer_palette = self.timer_button.get_palette()

        for i, label in enumerate(self.timer_labels):
            menu_item = MenuItem(icon_name='timer-%d' % (i), text_label=label)
            menu_item.connect('activate', self._timer_selected_cb, i)
            self.timer_palette.menu.append(menu_item)
            menu_item.show()

    def _timer_selected_cb(self, button, index):
        game_already_started = 0
        if self.time_interval is not None:
            game_already_started = 1

        self.time_interval = self.timer_values[index]
        if self.time_interval is None:
            self.timer_button.set_tooltip(_('Timer off'))
        else:
            self.timer_button.set_tooltip(
                _('Timer') + ' (' + self.timer_tooltips[index] + ')')
            if game_already_started:
                self.alert_reset(self.timer_labels[index])
                if self.time_interval and self.time_interval is not None:
                    self.stopwatch(self.time_interval, self.alert_time)
                else:
                    GLib.source_remove(self.stopwatch_timer)
            else:
                self._gnuchess.new_game()

    def _reskin_cb(self, button, piece):
        object_id, file_path = self._choose_skin()
        if file_path is not None:
            self._do_reskin(piece, file_path)
            self.metadata[piece] = str(object_id)

    def do_fullscreen_cb(self, button):
        ''' Hide the Sugar toolbars. '''
        self.fullscreen()

    def _play_history_cb(self, button):
        self._gnuchess.play_game_history()
        return

    def _show_history_cb(self, button):
        self._gnuchess.show_game_history(self.tag_pairs())
        if self.showing_game_history:
            self.history_button.set_icon_name('checkerboard')
            self.history_button.set_tooltip(_('Show game board'))
        else:
            self.history_button.set_icon_name('list-numbered')
            self.history_button.set_tooltip(_('Show game history'))
        return

    def _copy_cb(self, *args):
        clipboard = Gtk.Clipboard()
        clipboard.set_text(self.tag_pairs() + self._gnuchess.copy_game())

    def _paste_cb(self, *args):
        ''' Pasting '''
        clipboard = Gtk.Clipboard()
        move_list = self._parse_move_list(clipboard.wait_for_text())
        if move_list is not None:
            self._gnuchess.restore_game(move_list)

    def _parse_move_list(self, text):
        ''' Take a standard game description and return a move list '''
        # Assuming of form ... 1. e4 e6 2. ...
        move_list = []
        found_one = False
        comment = False
        for move in text.split():
            if move[0] == '{':
                comment = True
            elif move[-1] == '}':
                comment = False
            if not comment:
                if move == '1.':
                    found_one = True
                    number = True
                    white = False
                elif found_one:
                    if not number:
                        number = True
                    elif not white:
                        move_list.append(move)
                        white = True
                    else:
                        move_list.append(move)
                        number = False
                        white = False
        return move_list

    def _undo_cb(self, *args):
        # No undo while sharing
        if self.collab.props.leader is None:
            self._gnuchess.undo()

    def _hint_cb(self, *args):
        self._gnuchess.hint()

    def _play_white_cb(self, *args):
        if not self.play_white_button.get_active():
            return
        if not self._restoring:
            self._new_game_alert('white')
        return True

    def _play_black_cb(self, *args):
        if not self.play_black_button.get_active():
            return
        if not self._restoring:
            self._new_game_alert('black')
        return True

    def _easy_cb(self, *args):
        if not self.easy_button.get_active():
            return
        if not self._restoring:
            self._new_game_alert('easy')
        return True

    def _hard_cb(self, *args):
        if not self.hard_button.get_active():
            return
        if not self._restoring:
            self._new_game_alert('hard')
        return True

    def _robot_cb(self, *args):
        if not self.robot_button.get_active():
            return
        if not self._restoring:
            self._new_game_alert('robot')
        return True

    def _human_cb(self, *args):
        if not self.human_button.get_active():
            return
        if not self._restoring:
            self._new_game_alert('human')
        return True

    def _new_gnuchess_cb(self, button=None):
        ''' Start a new gnuchess. '''
        self._new_game_alert('new')

    def tag_pairs(self):
        ''' Tag paris must be ascii '''
        if type(self.nick) is str:
            nick = self.nick.encode('ascii', 'replace')
        else:
            nick = self.nick
        if self.buddy is not None and type(self.buddy) is str:
            buddy = self.buddy.encode('ascii', 'replace')
        else:
            buddy = self.buddy
        if self.playing_white:
            white = nick
            if self.playing_robot:
                black = 'gnuchess (%s)' % (self.playing_mode)
            elif self._gnuchess.we_are_sharing and buddy is not None:
                black = buddy
            else:
                black = '?'
        else:
            black = nick
            if self.playing_robot:
                white = 'gnuchess (%s)' % (self.playing_mode)
            elif self._gnuchess.we_are_sharing and buddy is not None:
                white = buddy
            else:
                white = '?'
        return '[White "%s"]\n[Black "%s"]\n\n' % (white, black)

    def write_file(self, file_path):
        ''' Write the grid status to the Journal '''
        fd = open(file_path, 'w')
        fd.write(self.tag_pairs())
        fd.write(self._gnuchess.copy_game())
        fd.close()
        # self.metadata['saved_game'] = json_dump(self._gnuchess.save_game())
        if self.playing_white:
            self.metadata['playing_white'] = 'True'
        else:
            self.metadata['playing_white'] = 'False'
        self.metadata['playing_mode'] = self.playing_mode
        if self.playing_robot:
            self.metadata['playing_robot'] = 'True'
        else:
            self.metadata['playing_robot'] = 'False'
        '''
        self.metadata['timer_mode'] = self.timer.get_active_text()
        '''

    def read_file(self, file_path):
        ''' Read project file on relaunch '''
        fd = open(file_path, 'r')
        self.game_data = fd.read()
        fd.close()
        _logger.debug(self.game_data)

    def _restore(self):
        ''' Restore the gnuchess state from metadata '''
        if 'playing_white' in self.metadata:
            if self.metadata['playing_white'] == 'False':
                self.playing_white = False
                self.play_black_button.set_active(True)
        if 'playing_mode' in self.metadata:
            self.playing_mode = self.metadata['playing_mode']
            if self.playing_mode == 'hard':
                self.hard_button.set_active(True)
        if 'playing_robot' in self.metadata:
            if self.metadata['playing_robot'] == 'False':
                self.playing_robot = False
                self.human_button.set_active(True)
        '''
        if 'timer_mode' in self.metadata:
            self.timer_intervale.set_active(self.timer_list.index(
                                            self.metadata['timer_mode']))
        '''

        self._gnuchess.restore_game(self._parse_move_list(self.game_data))
        self.do_custom_skin_cb()

    def _choose_skin(self):
        ''' Select a skin from the Journal '''
        chooser = None
        name = None
        if hasattr(mime, 'GENERIC_TYPE_IMAGE'):
            if 'image/svg+xml' not in \
                    mime.get_generic_type(mime.GENERIC_TYPE_IMAGE).mime_types:
                mime.get_generic_type(
                    mime.GENERIC_TYPE_IMAGE).mime_types.append('image/svg+xml')
            chooser = ObjectChooser(parent=self,
                                    what_filter=mime.GENERIC_TYPE_IMAGE)
        else:
            try:
                chooser = ObjectChooser(parent=self, what_filter=None)
            except TypeError:
                chooser = ObjectChooser(
                    None, activity,
                    Gtk.DialogType.MODAL | Gtk.DialogType.DESTROY_WITH_PARENT)
        if chooser is not None:
            try:
                result = chooser.run()
                if result == Gtk.ResponseType.ACCEPT:
                    jobject = chooser.get_selected_object()
                    if jobject and jobject.file_path:
                        name = jobject.metadata['title']
            finally:
                jobject.destroy()
                chooser.destroy()
                del chooser
            if name is not None:
                return jobject.object_id, jobject.file_path
        else:
            return None, None

    def _take_button_action(self, button):
        if button == 'black':
            self.playing_white = False
        elif button == 'white':
            self.playing_white = True
        elif button == 'easy':
            self.playing_mode = 'easy'
        elif button == 'hard':
            self.playing_mode = 'hard'
        elif button == 'robot':
            self.playing_robot = True
        elif button == 'human':
            self.playing_robot = False
        self._gnuchess.new_game()

    def _no_action(self, button):
        if button == 'black':
            self.play_white_button.set_active(True)
            self.playing_white = True
        elif button == 'white':
            self.play_black_button.set_active(True)
            self.playing_white = False
        elif button == 'easy':
            self.hard_button.set_active(True)
            self.playing_mode = 'hard'
        elif button == 'hard':
            self.easy_button.set_active(True)
            self.playing_mode = 'easy'
        elif button == 'robot':
            self.human_button.set_active(True)
            self.playing_robot = False
        elif button == 'human':
            self.robot_button.set_active(True)
            self.playing_robot = True

    def _new_game_alert(self, button):
        ''' We warn the user if the game is in progress before loading
        a new game. '''
        if self.collab.props.leader is not None and not self.collab.props.leader:
            # joiner cannot push buttons
            self._restoring = True
            self._no_action(button)
            self._restoring = False
            return

        if len(self._gnuchess.move_list) == 0:
            self._take_button_action(button)
            return

        self._restoring = True
        alert = ConfirmationAlert()
        alert.props.title = _('Game in progress.')
        alert.props.msg = _('Do you want to start a new game?')

        def _new_game_alert_response_cb(alert, response_id, self, button):
            if response_id is Gtk.ResponseType.OK:
                self._take_button_action(button)
            elif response_id is Gtk.ResponseType.CANCEL:
                self._no_action(button)
            self._restoring = False
            self.remove_alert(alert)

        alert.connect('response', _new_game_alert_response_cb, self, button)
        self.add_alert(alert)
        alert.show()

    # Collaboration-related methods

    def _shared_cb(self, activity):
        ''' Either set up initial share...'''
        _logger.debug('shared')
        self.after_share_join(True)

    def _joined_cb(self, activity):
        ''' ...or join an exisiting share. '''
        _logger.debug('joined')
        self.after_share_join(False)
        self.send_nick()
        # And let the sharer know we've joined
        self.send_join()

    def after_share_join(self, sharer):
        self._gnuchess.set_sharing(True)
        self.restoring = True
        self.playing_robot = False
        self.human_button.set_active(True)
        self.robot_button.set_active(False)
        self.restoring = False

        self.easy_button.set_sensitive(False)
        self.hard_button.set_sensitive(False)
        self.robot_button.set_sensitive(False)

    def _setup_dispatch_table(self):
        ''' Associate tokens with commands. '''
        self._processing_methods = {
            'n': [self._receive_new_game, 'start a new game'],
            'm': [self._receive_move, 'make a move'],
            'r': [self._receive_restore, 'restore game state'],
            'N': [self._receive_nick, 'receive nick from opponent'],
            'C': [self._receive_colors, 'receive colors from opponent'],
            'j': [self._receive_join, 'receive new joiner'],
            'p': [self._receive_piece, 'receive new piece'],
        }

    def _message_cb(self, collab, buddy, msg):
        ''' Data from a tube has arrived. '''
        command = msg.get("command")
        payload = msg.get("payload")
        self._processing_methods[command][0](payload)

    def send_new_game(self):
        ''' Send a new game to joiner. '''
        if not self.collab.props.leader:
            return
        self.send_nick()
        if self.playing_white:
            _logger.debug('send_new_game: B')
            self.send_event("n", "B")
        else:
            _logger.debug('send_new_game: W')
            self.send_event("n", "W")

    def send_restore(self):
        ''' Send a new game to joiner. '''
        if not self.collab.props.leader:
            return
        _logger.debug('send_restore')
        self.send_event("r", self._gnuchess.copy_game())

    def send_join(self):
        _logger.debug('send_join')
        self.send_event("j", self.nick)

    def send_nick(self):
        _logger.debug('send_nick')
        self.send_event("N", self.nick)
        self.send_event("C", "%s,%s" % (self.colors[0], self.colors[1]))

    def alert_time(self):
        def _alert_response_cb(alert, response_id):
            self.remove_alert(alert)

        alert = NotifyAlert()
        alert.props.title = _('Time Up!')
        alert.props.msg = _('Your time is up.')
        alert.connect('response', _alert_response_cb)
        alert.show()
        self.add_alert(alert)

    def alert_reset(self, mode):
        def _alert_response_cb(alert, response_id):
            self.remove_alert(alert)

        alert = NotifyAlert()
        alert.props.title = _('Time Reset')
        alert.props.msg = _('The timer mode was reset to %s' % mode)
        alert.connect('response', _alert_response_cb)
        alert.show()
        self.add_alert(alert)

    def stopwatch(self, time, alert_callback):
        if self.stopwatch_running:
            GLib.source_remove(self.stopwatch_timer)
            time = self.time_interval
        self.stopwatch_timer = GLib.timeout_add(time * 1000, alert_callback)
        self.stopwatch_running = True

    def _receive_join(self, payload):
        _logger.debug('received_join %s' % (payload))
        if self.collab.props.leader:
            self.send_new_game()
            _logger.debug(self.game_data)
            if self.game_data is not None:
                self.send_restore()

    def _receive_nick(self, payload):
        _logger.debug('received_nick %s' % (payload))
        self.buddy = payload
        self.opponent.set_label(self.buddy)
        if self.collab.props.leader:
            self.send_nick()

    def _receive_colors(self, payload):
        _logger.debug('received_colors %s' % (payload))
        self.opponent_colors = payload.split(',')
        xocolors = XoColor(payload)
        icon = Icon(icon_name='human', xo_color=xocolors)
        icon.show()
        self.human_button.set_icon_widget(icon)
        self.human_button.show()

    def _receive_restore(self, payload):
        ''' Get game state from sharer. '''
        if self.collab.props.leader:
            return
        _logger.debug('received_restore %s' % (payload))
        self._gnuchess.restore_game(self._parse_move_list(payload))

    def _receive_move(self, payload):
        ''' Get a move from opponent. '''
        _logger.debug('received_move %s' % (payload))
        self._gnuchess.remote_move(payload)

    def _receive_new_game(self, payload):
        ''' Sharer can start a new gnuchess. '''
        _logger.debug('receive_new_game %s' % (payload))
        # The leader cannot receive new game
        if self.collab.props.leader:
            return
        self.send_nick()
        if payload == 'W':
            if not self.playing_white:
                self.restoring = True
                self.play_black_button.set_active(False)
                self.play_white_button.set_active(True)
                self.playing_white = True
        else:
            if self.playing_white:
                self.restoring = True
                self.play_white_button.set_active(False)
                self.play_black_button.set_active(True)
                self.playing_white = False
        self.robot_button.set_active(False)
        self.human_button.set_active(True)
        self.playing_robot = False
        self.restoring = False
        self._gnuchess.set_sharing(True)
        self._gnuchess.new_game()

    def send_event(self, command, payload):
        ''' Send event through the tube. '''
        if hasattr(self, 'collab') and self.collab is not None:
            self.collab.post(dict(command=command, payload=payload))

    # sharing pieces

    def send_piece(self, piece, pixbuf):
        _logger.debug('send_piece %s' % (piece))
        GLib.idle_add(self.send_event, ("p", self._dump(piece, pixbuf)))

    def _receive_piece(self, payload):
        piece, pixbuf = self._load(payload)
        _logger.debug('received_piece %s' % (piece))
        self._gnuchess.reskin(piece, pixbuf)

    def _dump(self, piece, pixbuf):
        ''' Dump data for sharing.'''
        _logger.debug('dumping %s' % (piece))
        data = [piece, pixbuf_to_base64(activity, pixbuf)]
        return json_dump(data)

    def _load(self, data):
        ''' Load game data from the journal. '''
        piece, pixbuf_data = json_load(data)
        pixbuf = base64_to_pixbuf(activity,
                                  pixbuf_data,
                                  width=self._gnuchess.scale,
                                  height=self._gnuchess.scale)
        return piece, pixbuf
Beispiel #35
0
class ViewToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ViewToolbar'

    __gsignals__ = {
        'go-fullscreen': (GObject.SignalFlags.RUN_FIRST, None, ([])),
    }

    def __init__(self):
        Gtk.Toolbar.__init__(self)

        self._view = None
        self._bookmarkmanager = None
        self._update_offset = True

        self._zoom_out = ToolButton('zoom-out')
        self._zoom_out.set_tooltip(_('Zoom out'))
        self._zoom_out.connect('clicked', self._zoom_out_cb)
        self.insert(self._zoom_out, -1)
        self._zoom_out.show()

        self._zoom_in = ToolButton('zoom-in')
        self._zoom_in.set_tooltip(_('Zoom in'))
        self._zoom_in.connect('clicked', self._zoom_in_cb)
        self.insert(self._zoom_in, -1)
        self._zoom_in.show()

        self._zoom_to_width = ToolButton('zoom-best-fit')
        self._zoom_to_width.set_tooltip(_('Zoom to width'))
        self._zoom_to_width.connect('clicked', self._zoom_to_width_cb)
        self.insert(self._zoom_to_width, -1)
        self._zoom_to_width.show()

        palette = self._zoom_to_width.get_palette()
        menu_item = MenuItem(_('Zoom to fit'))
        menu_item.connect('activate', self._zoom_to_fit_menu_item_activate_cb)
        palette.menu.append(menu_item)
        menu_item.show()

        menu_item = MenuItem(_('Actual size'))
        menu_item.connect('activate', self._actual_size_menu_item_activate_cb)
        palette.menu.append(menu_item)
        menu_item.show()

        tool_item = Gtk.ToolItem()
        self.insert(tool_item, -1)
        tool_item.show()

        self._zoom_spin = Gtk.SpinButton()
        self._zoom_spin.set_range(5.409, 400)
        self._zoom_spin.set_increments(1, 10)
        self._zoom_spin_notify_value_handler = self._zoom_spin.connect(
            'notify::value', self._zoom_spin_notify_value_cb)
        tool_item.add(self._zoom_spin)
        self._zoom_spin.show()

        zoom_perc_label = Gtk.Label(_("%"))
        zoom_perc_label.show()
        tool_item_zoom_perc_label = Gtk.ToolItem()
        tool_item_zoom_perc_label.add(zoom_perc_label)
        self.insert(tool_item_zoom_perc_label, -1)
        tool_item_zoom_perc_label.show()

        spacer = Gtk.SeparatorToolItem()
        spacer.props.draw = False
        self.insert(spacer, -1)
        spacer.show()

        self._fullscreen = ToolButton('view-fullscreen')
        self._fullscreen.set_tooltip(_('Fullscreen'))
        self._fullscreen.connect('clicked', self._fullscreen_cb)
        self.insert(self._fullscreen, -1)
        self._fullscreen.show()

        self._view_notify_zoom_handler = None

    def set_view(self, view):
        self._view = view

    def set_bookmarkmanager(self, bookmarkmanager):
        self._bookmarkmanager = bookmarkmanager

    def _zoom_spin_notify_value_cb(self, zoom_spin, pspec):
        self._view.set_zoom(zoom_spin.props.value)

    def _view_notify_zoom_cb(self, model, pspec):
        self._zoom_spin.disconnect(self._zoom_spin_notify_value_handler)
        try:
            self._zoom_spin.props.value = round(self._view.get_zoom())
        finally:
            self._zoom_spin_notify_value_handler = self._zoom_spin.connect(
                'notify::value', self._zoom_spin_notify_value_cb)

    def __set_progress_if_applicable(self):
        if (self._view.show_progress_bar() is True) and \
           (self._update_offset is True):
            self._view.get_maximum_offset_possible()

    def zoom_in(self, zoom_amount):
        self._view.zoom_in(zoom_amount)
        self._view._main_instance.window.force_ui_updates()
        self.__set_progress_if_applicable()

    def _zoom_in_cb(self, button, zoom_amount=1):
        if self._view.can_zoom_in():
            self.zoom_in(zoom_amount)
            self._view._number_of_times_zoomed = \
                    self._view._number_of_times_zoomed + zoom_amount

    def zoom_out(self, zoom_amount):
        self._view.zoom_out(zoom_amount)
        self._view._main_instance.window.force_ui_updates()
        self.__set_progress_if_applicable()

    def _zoom_out_cb(self, button, zoom_amount=1):
        if self._view.can_zoom_out():
            self.zoom_out(zoom_amount)
            self._view._number_of_times_zoomed = \
                    self._view._number_of_times_zoomed - zoom_amount

    def update_offset(self, update):
        self._update_offset = update

    def zoom_to_width(self):
        self._view.zoom_to_width()

    def _zoom_to_width_cb(self, button):
        self.zoom_to_width()

    def _zoom_to_fit_menu_item_activate_cb(self, menu_item):
        self._view.zoom_to_best_fit()

    def _actual_size_menu_item_activate_cb(self, menu_item):
        self._view.zoom_to_actual_size()

    def _fullscreen_cb(self, button):
        self.emit('go-fullscreen')
Beispiel #36
0
class ReadToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ReadToolbar'

    def __init__(self):
        Gtk.Toolbar.__init__(self)

        self.back = ToolButton('go-previous')
        self.back.set_tooltip(_('Back'))
        self.back.props.sensitive = False
        palette = self.back.get_palette()
        self.prev_page = MenuItem(text_label= _("Previous page"))
        palette.menu.append(self.prev_page) 
        self.prev_page.show_all()        
        self.prev_bookmark = MenuItem(text_label= _("Previous bookmark"))
        palette.menu.append(self.prev_bookmark) 
        self.prev_bookmark.show_all()
        self.back.connect('clicked', self.go_back_cb)
        self.prev_page.connect('activate', self.go_back_cb)
        self.prev_bookmark.connect('activate', self.prev_bookmark_activate_cb)
        self.insert(self.back, -1)
        self.back.show()

        self.forward = ToolButton('go-next')
        self.forward.set_tooltip(_('Forward'))
        self.forward.props.sensitive = False
        palette = self.forward.get_palette()
        self.next_page = MenuItem(text_label= _("Next page"))
        palette.menu.append(self.next_page) 
        self.next_page.show_all()        
        self.next_bookmark = MenuItem(text_label= _("Next bookmark"))
        palette.menu.append(self.next_bookmark) 
        self.next_bookmark.show_all()
        self.forward.connect('clicked', self.go_forward_cb)
        self.next_page.connect('activate', self.go_forward_cb)
        self.next_bookmark.connect('activate', self.next_bookmark_activate_cb)
        self.insert(self.forward, -1)
        self.forward.show()

        num_page_item = Gtk.ToolItem()

        self.num_page_entry = Gtk.Entry()
        self.num_page_entry.set_text('0')
        self.num_page_entry.set_alignment(1)
        self.num_page_entry.connect('insert-text',
                                     self.num_page_entry_insert_text_cb)
        self.num_page_entry.connect('activate',
                                     self.num_page_entry_activate_cb)

        self.num_page_entry.set_width_chars(4)

        num_page_item.add(self.num_page_entry)
        self.num_page_entry.show()

        self.insert(num_page_item, -1)
        num_page_item.show()

        total_page_item = Gtk.ToolItem()

        self.total_page_label = Gtk.Label()
        self.total_page_label.set_markup("<span size='14000' foreground='black'>")

        self.total_page_label.set_text(' / 0')
        total_page_item.add(self.total_page_label)
        self.total_page_label.show()

        self.insert(total_page_item, -1)
        total_page_item.show()

        spacer = Gtk.SeparatorToolItem()
        self.insert(spacer, -1)
        spacer.show()
  
        bookmarkitem = Gtk.ToolItem()
        self.bookmarker = ToggleToolButton('emblem-favorite')
        self.bookmarker.set_tooltip(_('Toggle Bookmark'))
        self.bookmarker_handler_id = self.bookmarker.connect('clicked',
                                      self.bookmarker_clicked_cb)
  
        bookmarkitem.add(self.bookmarker)

        self.insert(bookmarkitem, -1)
        bookmarkitem.show_all()

        underline_item = Gtk.ToolItem()
        self.underline = ToggleToolButton('format-text-underline')
        self.underline.set_tooltip(_('Underline'))
        self.underline.props.sensitive = False
        self.underline_id = self.underline.connect('clicked', self.underline_cb)
        underline_item.add(self.underline)
        self.insert(underline_item, -1)
        underline_item.show_all()

    def num_page_entry_insert_text_cb(self, entry, text, length, position):
        if not re.match('[0-9]', text):
            entry.emit_stop_by_name('insert-text')
            return True
        return False

    def num_page_entry_activate_cb(self, entry):
        if entry.props.text:
            page = int(entry.props.text) - 1
        else:
            page = 0

        if page >= self.total_pages:
            page = self.total_pages - 1
        elif page < 0:
            page = 0

        self.current_page = page
        self.activity.set_current_page(page)
        self.activity.show_page(page)
        entry.props.text = str(page + 1)
        self.update_nav_buttons()
        
    def go_back_cb(self, button):
        self.activity.page_previous()
    
    def go_forward_cb(self, button):
        self.activity.page_next()
    
    def update_nav_buttons(self):
        current_page = self.current_page
        self.back.props.sensitive = current_page > 0
        self.forward.props.sensitive = \
            current_page < self.total_pages - 1
        
        self.num_page_entry.props.text = str(current_page + 1)
        self.total_page_label.props.label = \
            ' / ' + str(self.total_pages)

    def set_total_pages(self, pages):
        self.total_pages = pages
        
    def set_current_page(self, page):
        self.current_page = page
        self.update_nav_buttons()
        
    def set_activity(self, activity):
        self.activity = activity

    def prev_bookmark_activate_cb(self, menuitem):
        self.activity.prev_bookmark()
 
    def next_bookmark_activate_cb(self, menuitem):
        self.activity.next_bookmark()
        
    def bookmarker_clicked_cb(self, button):
        self.activity.bookmarker_clicked(button)

    def underline_cb(self, button):
        self.activity.underline_clicked(button)

    def setToggleButtonState(self,button,b,id):
        button.handler_block(id)
        button.set_active(b)
        button.handler_unblock(id)
        
    def update_underline_button(self,  state):
        self.setToggleButtonState(self.underline,  state,  self.underline_id)

    def update_bookmark_button(self,  state):
        self.setToggleButtonState(self.bookmarker,  state,  self.bookmarker_handler_id)
Beispiel #37
0
class RecordControl():

    def __init__(self, toolbar):

        self._timer_value = TIMER_VALUES[0]
        self._timer_button = ToolButton('timer-0')
        self._timer_button.set_tooltip(_('Select timer'))
        self._timer_button.connect('clicked', self._timer_selection_cb)
        toolbar.insert(self._timer_button, -1)
        self._setup_timer_palette()

        self._duration_value = DURATION_VALUES[0]
        self._duration_button = ToolButton('duration-2')
        self._duration_button.set_tooltip(_('Select duration'))
        self._duration_button.connect('clicked', self._duration_selection_cb)
        toolbar.insert(self._duration_button, -1)
        self._setup_duration_palette()

        self._quality_value = 0
        self._quality_button = ToolButton('low-quality')
        self._quality_button.set_tooltip(_('Select quality'))
        self._quality_button.connect('clicked', self._quality_selection_cb)
        toolbar.insert(self._quality_button, -1)
        self._setup_quality_palette()

    def _timer_selection_cb(self, widget):
        if self._timer_palette:

            if not self._timer_palette.is_up():
                self._timer_palette.popup(immediate=True)
            else:
                self._timer_palette.popdown(immediate=True)
            return

    def _setup_timer_palette(self):
        self._timer_palette = self._timer_button.get_palette()
        box = PaletteMenuBox()
        self._timer_palette.set_content(box)
        box.show()

        for seconds in TIMER_VALUES:
            if seconds == 0:
                text = _('Immediate')
            else:
                text = ngettext('%s second', '%s seconds', seconds) % seconds
            menu_item = PaletteMenuItem(text, icon_name='timer-%d' % (seconds))
            menu_item.connect('activate', self._timer_selected_cb, seconds)
            box.append_item(menu_item)
            menu_item.show()

    def _timer_selected_cb(self, button, seconds):
        self.set_timer_idx(TIMER_VALUES.index(seconds))

    def _duration_selection_cb(self, widget):
        if self._duration_palette:
            if not self._duration_palette.is_up():
                self._duration_palette.popup(immediate=True)
            else:
                self._duration_palette.popdown(immediate=True)
            return

    def _setup_duration_palette(self):
        self._duration_palette = self._duration_button.get_palette()
        box = PaletteMenuBox()
        self._duration_palette.set_content(box)
        box.show()

        for minutes in DURATION_VALUES:
            if minutes == 0:
                text = Gtk.Label(_('Immediate'))
            else:
                text = ngettext('%s minute', '%s minutes', minutes) % minutes
            menu_item = PaletteMenuItem(text,
                                        icon_name='duration-%d' % (minutes))
            menu_item.connect('activate', self._duration_selected_cb, minutes)
            box.append_item(menu_item)
            menu_item.show()

    def _duration_selected_cb(self, button, minutes):
        self.set_duration_idx(DURATION_VALUES.index(minutes))

    def _quality_selection_cb(self, widget):
        if self._quality_palette:
            if not self._quality_palette.is_up():
                self._quality_palette.popup(immediate=True)
            else:
                self._quality_palette.popdown(immediate=True)
            return

    def _setup_quality_palette(self):
        self._quality_palette = self._quality_button.get_palette()
        box = PaletteMenuBox()
        self._quality_palette.set_content(box)
        box.show()

        for quality in QUALITY_VALUES:
            text = _('%s quality') % (quality)
            menu_item = PaletteMenuItem(text, icon_name=quality + '-quality')
            menu_item.connect('activate', self._quality_selected_cb, quality)
            box.append_item(menu_item)
            menu_item.show()

    def _quality_selected_cb(self, button, quality):
        self.set_quality(QUALITY_VALUES.index(quality))

    def set_mode(self, mode):
        if mode == constants.MODE_PHOTO:
            self._quality_button.set_sensitive(False)
            self._timer_button.set_sensitive(True)
            self._duration_button.set_sensitive(False)
        if mode == constants.MODE_VIDEO:
            self._quality_button.set_sensitive(True)
            self._timer_button.set_sensitive(True)
            self._duration_button.set_sensitive(True)
        if mode == constants.MODE_AUDIO:
            self._quality_button.set_sensitive(False)
            self._timer_button.set_sensitive(True)
            self._duration_button.set_sensitive(True)

    def get_timer(self):
        return self._timer_value

    def get_timer_idx(self):
        if self._timer_value in TIMER_VALUES:
            return TIMER_VALUES.index(self._timer_value)
        else:
            return TIMER_VALUES[0]

    def set_timer_idx(self, idx):
        self._timer_value = TIMER_VALUES[idx]
        if hasattr(self, '_timer_button'):
            self._timer_button.set_icon_name('timer-%d' % (self._timer_value))

    def get_duration(self):
        return self._duration_value

    def get_duration_idx(self):
        if self._duration_value in DURATION_VALUES:
            return DURATION_VALUES.index(self._duration_value)
        else:
            return DURATION_VALUES[0]

    def set_duration_idx(self, idx):
        self._duration_value = DURATION_VALUES[idx]
        if hasattr(self, '_duration_button'):
            self._duration_button.set_icon_name(
                'duration-%d' % (self._duration_value))

    def get_quality(self):
        return self._quality_value

    def set_quality(self, idx):
        self._quality_value = idx
        if hasattr(self, '_quality_button'):
            name = '%s-quality' % (QUALITY_VALUES[idx])
            self._quality_button.set_icon_name(name)
Beispiel #38
0
class DetailToolbox(ToolbarBox):
    __gsignals__ = {
        'volume-error': (GObject.SignalFlags.RUN_FIRST, None,
                         ([str, str])),
    }

    def __init__(self, journalactivity):
        ToolbarBox.__init__(self)
        self._journalactivity = journalactivity
        self._metadata = None
        self._temp_file_path = None
        self._refresh = None

        self._resume = ToolButton('activity-start')
        self._resume.connect('clicked', self._resume_clicked_cb)
        self.toolbar.insert(self._resume, -1)
        self._resume.show()
        self._resume_menu = None

        color = profile.get_color()
        self._copy = ToolButton()
        icon = Icon(icon_name='edit-copy', xo_color=color)
        self._copy.set_icon_widget(icon)
        icon.show()
        self._copy.set_tooltip(_('Copy to'))
        self._copy.connect('clicked', self._copy_clicked_cb)
        self.toolbar.insert(self._copy, -1)
        self._copy.show()

        self._duplicate = ToolButton()
        icon = Icon(icon_name='edit-duplicate', xo_color=color)
        self._duplicate.set_icon_widget(icon)
        self._duplicate.set_tooltip(_('Duplicate'))
        self._duplicate.connect('clicked', self._duplicate_clicked_cb)
        self.toolbar.insert(self._duplicate, -1)

        if accountsmanager.has_configured_accounts():
            self._refresh = ToolButton('entry-refresh')
            self._refresh.set_tooltip(_('Refresh'))
            self._refresh.connect('clicked', self._refresh_clicked_cb)
            self.toolbar.insert(self._refresh, -1)
            self._refresh.show()

        separator = Gtk.SeparatorToolItem()
        self.toolbar.insert(separator, -1)
        separator.show()

        erase_button = ToolButton('list-remove')
        erase_button.set_tooltip(_('Erase'))
        erase_button.connect('clicked', self._erase_button_clicked_cb)
        self.toolbar.insert(erase_button, -1)
        erase_button.show()

    def set_metadata(self, metadata):
        self._metadata = metadata
        self._refresh_copy_palette()
        self._refresh_duplicate_palette()
        self._refresh_refresh_palette()
        self._refresh_resume_palette()

    def _resume_clicked_cb(self, button):
        if not misc.can_resume(self._metadata):
            palette = self._resume.get_palette()
            palette.popup(immediate=True)

        misc.resume(self._metadata,
                    alert_window=journalwindow.get_journal_window())

    def _copy_clicked_cb(self, button):
        button.palette.popup(immediate=True)

    def _refresh_clicked_cb(self, button):
        button.palette.popup(immediate=True)

    def _duplicate_clicked_cb(self, button):
        try:
            model.copy(self._metadata, '/')
        except IOError as e:
            logging.exception('Error while copying the entry.')
            self.emit('volume-error',
                      _('Error while copying the entry. %s') % (e.strerror, ),
                      _('Error'))

    def _erase_button_clicked_cb(self, button):
        alert = Alert()
        erase_string = _('Erase')
        alert.props.title = erase_string
        alert.props.msg = _('Do you want to permanently erase \"%s\"?') \
            % self._metadata['title']
        icon = Icon(icon_name='dialog-cancel')
        alert.add_button(Gtk.ResponseType.CANCEL, _('Cancel'), icon)
        icon.show()
        ok_icon = Icon(icon_name='dialog-ok')
        alert.add_button(Gtk.ResponseType.OK, erase_string, ok_icon)
        ok_icon.show()
        alert.connect('response', self.__erase_alert_response_cb)
        journalwindow.get_journal_window().add_alert(alert)
        alert.show()

    def __erase_alert_response_cb(self, alert, response_id):
        journalwindow.get_journal_window().remove_alert(alert)
        if response_id is Gtk.ResponseType.OK:
            registry = bundleregistry.get_registry()
            bundle = misc.get_bundle(self._metadata)
            if bundle is not None and registry.is_installed(bundle):
                registry.uninstall(bundle)
            model.delete(self._metadata['uid'])

    def _resume_menu_item_activate_cb(self, menu_item, service_name):
        misc.resume(self._metadata, service_name,
                    alert_window=journalwindow.get_journal_window())

    def _refresh_copy_palette(self):
        palette = self._copy.get_palette()

        # Use the menu defined in CopyMenu
        for menu_item in palette.menu.get_children():
            palette.menu.remove(menu_item)
            menu_item.destroy()

        CopyMenuBuilder(self._journalactivity, self.__get_uid_list_cb,
                        self.__volume_error_cb, palette.menu)

    def __get_uid_list_cb(self):
        return [self._metadata['uid']]

    def _refresh_duplicate_palette(self):
        color = misc.get_icon_color(self._metadata)
        self._copy.get_icon_widget().props.xo_color = color
        if self._metadata['mountpoint'] == '/':
            self._duplicate.show()
            icon = self._duplicate.get_icon_widget()
            icon.props.xo_color = color
            icon.show()
        else:
            self._duplicate.hide()

    def _refresh_refresh_palette(self):
        if self._refresh is None:
            return

        color = misc.get_icon_color(self._metadata)
        self._refresh.get_icon_widget().props.xo_color = color

        palette = self._refresh.get_palette()
        for menu_item in palette.menu.get_children():
            palette.menu.remove(menu_item)

        for account in accountsmanager.get_configured_accounts():
            if hasattr(account, 'get_shared_journal_entry'):
                entry = account.get_shared_journal_entry()
                if hasattr(entry, 'get_refresh_menu'):
                    menu = entry.get_refresh_menu()
                    palette.menu.append(menu)
                    menu.set_metadata(self._metadata)

    def __volume_error_cb(self, menu_item, message, severity):
        self.emit('volume-error', message, severity)

    def _refresh_resume_palette(self):
        if self._metadata.get('activity_id', ''):
            # TRANS: Action label for resuming an activity.
            self._resume.set_tooltip(_('Resume'))
        else:
            # TRANS: Action label for starting an entry.
            self._resume.set_tooltip(_('Start'))

        palette = self._resume.get_palette()

        if self._resume_menu is not None:
            self._resume_menu.destroy()

        self._resume_menu = PaletteMenuBox()
        palette.set_content(self._resume_menu)
        self._resume_menu.show()

        for activity_info in misc.get_activities(self._metadata):
            menu_item = PaletteMenuItem(file_name=activity_info.get_icon(),
                                        text_label=activity_info.get_name())
            menu_item.connect('activate', self._resume_menu_item_activate_cb,
                              activity_info.get_bundle_id())
            self._resume_menu.append_item(menu_item)
            menu_item.show()

        if not misc.can_resume(self._metadata):
            self._resume.set_tooltip(_('No activity to start entry'))
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        # abiword uses the current directory for all its file dialogs
        os.chdir(os.path.expanduser('~'))

        # create our main abiword canvas
        self.abiword_canvas = DocumentView()
        self._new_instance = True
        toolbar_box = ToolbarBox()

        self.activity_button = ActivityToolbarButton(self)
        toolbar_box.toolbar.insert(self.activity_button, -1)

        separator = Gtk.SeparatorToolItem()
        separator.show()
        self.activity_button.props.page.insert(separator, 2)
        ExportButtonFactory(self, self.abiword_canvas)
        self.activity_button.show()

        edit_toolbar = ToolbarButton()
        edit_toolbar.props.page = EditToolbar(self, toolbar_box)
        edit_toolbar.props.icon_name = 'toolbar-edit'
        edit_toolbar.props.label = _('Edit')
        toolbar_box.toolbar.insert(edit_toolbar, -1)

        view_toolbar = ToolbarButton()
        view_toolbar.props.page = ViewToolbar(self.abiword_canvas)
        view_toolbar.props.icon_name = 'toolbar-view'
        view_toolbar.props.label = _('View')
        toolbar_box.toolbar.insert(view_toolbar, -1)

        # due to http://bugzilla.abisource.com/show_bug.cgi?id=13585
        if self.abiword_canvas.get_version() != '3.0':
            self.speech_toolbar_button = ToolbarButton(icon_name='speak')
            toolbar_box.toolbar.insert(self.speech_toolbar_button, -1)
            self._init_speech()

        separator = Gtk.SeparatorToolItem()
        toolbar_box.toolbar.insert(separator, -1)

        text_toolbar = ToolbarButton()
        text_toolbar.props.page = TextToolbar(self.abiword_canvas)
        text_toolbar.props.icon_name = 'format-text'
        text_toolbar.props.label = _('Text')
        toolbar_box.toolbar.insert(text_toolbar, -1)

        para_toolbar = ToolbarButton()
        para_toolbar.props.page = ParagraphToolbar(self.abiword_canvas)
        para_toolbar.props.icon_name = 'paragraph-bar'
        para_toolbar.props.label = _('Paragraph')
        toolbar_box.toolbar.insert(para_toolbar, -1)

        insert_toolbar = ToolbarButton()
        insert_toolbar.props.page = InsertToolbar(self.abiword_canvas)
        insert_toolbar.props.icon_name = 'insert-table'
        insert_toolbar.props.label = _('Table')
        toolbar_box.toolbar.insert(insert_toolbar, -1)

        image = ToolButton('insert-picture')
        image.set_tooltip(_('Insert Image'))
        self._image_id = image.connect('clicked', self._image_cb)
        toolbar_box.toolbar.insert(image, -1)

        palette = image.get_palette()
        content_box = Gtk.VBox()
        palette.set_content(content_box)
        image_floating_checkbutton = Gtk.CheckButton(_('Floating'))
        image_floating_checkbutton.connect(
            'toggled', self._image_floating_checkbutton_toggled_cb)
        content_box.pack_start(image_floating_checkbutton, True, True, 0)
        content_box.show_all()
        self.floating_image = False

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_size_request(0, -1)
        separator.set_expand(True)
        separator.show()
        toolbar_box.toolbar.insert(separator, -1)

        stop = StopButton(self)
        toolbar_box.toolbar.insert(stop, -1)

        toolbar_box.show_all()
        self.set_toolbar_box(toolbar_box)

        # add a overlay to be able to show a icon while joining a shared doc
        overlay = Gtk.Overlay()
        overlay.add(self.abiword_canvas)
        overlay.show()

        self._connecting_box = ConnectingBox()
        overlay.add_overlay(self._connecting_box)

        self.set_canvas(overlay)

        # we want a nice border so we can select paragraphs easily
        self.abiword_canvas.set_show_margin(True)

        # Read default font face and size
        client = GConf.Client.get_default()
        self._default_font_face = client.get_string(
            '/desktop/sugar/activities/write/font_face')
        if not self._default_font_face:
            self._default_font_face = 'Sans'
        self._default_font_size = client.get_int(
            '/desktop/sugar/activities/write/font_size')
        if self._default_font_size == 0:
            self._default_font_size = 12

        # activity sharing
        self.participants = {}
        self.joined = False

        self.connect('shared', self._shared_cb)

        if self.shared_activity:
            # we are joining the activity
            logger.error('We are joining an activity')
            # display a icon while joining
            self._connecting_box.show()
            # disable the abi widget
            self.abiword_canvas.set_sensitive(False)
            self._new_instance = False
            self.connect('joined', self._joined_cb)
            self.shared_activity.connect('buddy-joined',
                                         self._buddy_joined_cb)
            self.shared_activity.connect('buddy-left', self._buddy_left_cb)
            if self.get_shared():
                self._joined_cb(self)
        else:
            # we are creating the activity
            logger.error("We are creating an activity")

        self.abiword_canvas.zoom_width()
        self.abiword_canvas.show()
        self.connect_after('map-event', self.__map_activity_event_cb)

        self.abiword_canvas.connect('size-allocate', self.size_allocate_cb)
class PrimaryToolbar(ToolbarBase):
    __gtype_name__ = 'PrimaryToolbar'

    __gsignals__ = {
       'go-home': (GObject.SignalFlags.RUN_FIRST,
                     None,
                     ([])),
        'set-home': (GObject.SignalFlags.RUN_FIRST,
                     None,
                     ([])),
        'reset-home': (GObject.SignalFlags.RUN_FIRST,
                     None,
                     ([])),
        'go-library': (GObject.SignalFlags.RUN_FIRST,
                     None,
                     ([])),
    }

    def __init__(self, tabbed_view, act):
        ToolbarBase.__init__(self)

        self._url_toolbar = UrlToolbar()

        self._activity = act

        self._tabbed_view = tabbed_view

        self._loading = False

        toolbar = self.toolbar
        activity_button = ActivityToolbarButton(self._activity)
        toolbar.insert(activity_button, 0)

        self._go_home = ToolButton('go-home')
        self._go_home.set_tooltip(_('Home page'))
        self._go_home.connect('clicked', self._go_home_cb)
        # add a menu to save the home page
        menu_box = PaletteMenuBox()
        self._go_home.props.palette.set_content(menu_box)
        menu_item = PaletteMenuItem()
        menu_item.set_label(_('Select as initial page'))
        menu_item.connect('activate', self._set_home_cb)
        menu_box.append_item(menu_item)

        self._reset_home_menu = PaletteMenuItem()
        self._reset_home_menu.set_label(_('Reset initial page'))
        self._reset_home_menu.connect('activate', self._reset_home_cb)
        menu_box.append_item(self._reset_home_menu)

        if os.path.isfile(LIBRARY_PATH):
            library_menu = PaletteMenuItem()
            library_menu.set_label(_('Library'))
            library_menu.connect('activate', self._go_library_cb)
            menu_box.append_item(library_menu)

        menu_box.show_all()

        # verify if the home page is configured
        client = GConf.Client.get_default()
        self._reset_home_menu.set_visible(
            client.get_string(HOME_PAGE_GCONF_KEY) is not None)

        toolbar.insert(self._go_home, -1)
        self._go_home.show()

        self.entry = WebEntry()
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-stop')
        self.entry.connect('icon-press', self._stop_and_reload_cb)
        self.entry.connect('activate', self._entry_activate_cb)
        self.entry.connect('focus-in-event', self.__focus_in_event_cb)
        self.entry.connect('focus-out-event', self.__focus_out_event_cb)
        self.entry.connect('key-press-event', self.__key_press_event_cb)
        self.entry.connect('changed', self.__changed_cb)

        self._entry_item = Gtk.ToolItem()
        self._entry_item.set_expand(True)
        self._entry_item.add(self.entry)
        self.entry.show()

        toolbar.insert(self._entry_item, -1)

        self._entry_item.show()

        self._back = ToolButton('go-previous-paired')
        self._back.set_tooltip(_('Back'))
        self._back.props.sensitive = False
        self._back.connect('clicked', self._go_back_cb)
        toolbar.insert(self._back, -1)
        self._back.show()

        palette = self._back.get_palette()
        self._back_box_menu = Gtk.VBox()
        self._back_box_menu.show()
        palette.set_content(self._back_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._forward = ToolButton('go-next-paired')
        self._forward.set_tooltip(_('Forward'))
        self._forward.props.sensitive = False
        self._forward.connect('clicked', self._go_forward_cb)
        toolbar.insert(self._forward, -1)
        self._forward.show()

        palette = self._forward.get_palette()
        self._forward_box_menu = Gtk.VBox()
        self._forward_box_menu.show()
        palette.set_content(self._forward_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._toolbar_separator = Gtk.SeparatorToolItem()
        self._toolbar_separator.props.draw = False
        self._toolbar_separator.set_expand(True)

        stop_button = StopButton(self._activity)
        toolbar.insert(stop_button, -1)

        self._progress_listener = None
        self._browser = None

        self._loading_changed_hid = None
        self._progress_changed_hid = None
        self._session_history_changed_hid = None
        self._uri_changed_hid = None
        self._security_status_changed_hid = None

        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

        tabbed_view.connect_after('switch-page', self.__switch_page_cb)
        tabbed_view.connect_after('page-added', self.__page_added_cb)

        Gdk.Screen.get_default().connect('size-changed',
                                         self.__screen_size_changed_cb)

        self._configure_toolbar()

    def __key_press_event_cb(self, entry, event):
        self._tabbed_view.current_browser.loading_uri = entry.props.text

    def __switch_page_cb(self, tabbed_view, page, page_num):
        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

    def __page_added_cb(self, notebook, child, pagenum):
        self.entry._search_popdown()

    def _configure_toolbar(self, screen=None):
        # Adapt the toolbars for portrait or landscape mode.

        if screen is None:
            screen = Gdk.Screen.get_default()

        if screen.get_width() < screen.get_height():
            if self._entry_item in self._url_toolbar.toolbar.get_children():
                return

            self.toolbar.remove(self._entry_item)
            self._url_toolbar.toolbar.insert(self._entry_item, -1)

            separator_pos = len(self.toolbar.get_children()) - 1
            self.toolbar.insert(self._toolbar_separator, separator_pos)
            self._toolbar_separator.show()

            self.pack_end(self._url_toolbar, True, True, 0)
            self._url_toolbar.show()

        else:
            if self._entry_item in self.toolbar.get_children():
                return

            self.toolbar.remove(self._toolbar_separator)

            position = len(self.toolbar.get_children()) - 4
            self._url_toolbar.toolbar.remove(self._entry_item)
            self.toolbar.insert(self._entry_item, position)

            self._toolbar_separator.hide()
            self.remove(self._url_toolbar)

    def __screen_size_changed_cb(self, screen):
        self._configure_toolbar(screen)

    def _connect_to_browser(self, browser):
        if self._browser is not None:
            self._browser.disconnect(self._uri_changed_hid)
            self._browser.disconnect(self._progress_changed_hid)
            self._browser.disconnect(self._loading_changed_hid)
            self._browser.disconnect(self._security_status_changed_hid)

        self._browser = browser
        if not isinstance(self._browser, DummyBrowser):
            address = self._browser.props.uri or self._browser.loading_uri
        else:
            address = self._browser.props.uri
        self._set_address(address)
        self._set_progress(self._browser.props.progress)
        self._set_status(self._browser.props.load_status)
        self._set_security_status(self._browser.security_status)

        is_webkit_browser = isinstance(self._browser, Browser)
        self.entry.props.editable = is_webkit_browser

        self._uri_changed_hid = self._browser.connect(
                'notify::uri', self.__uri_changed_cb)
        self._progress_changed_hid = self._browser.connect(
                'notify::progress', self.__progress_changed_cb)
        self._loading_changed_hid = self._browser.connect(
                'notify::load-status', self.__loading_changed_cb)
        self._security_status_changed_hid = self._browser.connect(
                'security-status-changed', self.__security_status_changed_cb)

        self._update_navigation_buttons()

    def __loading_changed_cb(self, widget, param):
        self._set_status(widget.get_load_status())

    def __security_status_changed_cb(self, widget):
        self._set_security_status(widget.security_status)

    def __progress_changed_cb(self, widget, param):
        self._set_progress(widget.get_progress())

    def _set_status(self, status):
        self._set_loading(status < WebKit.LoadStatus.FINISHED)

    def _set_security_status(self, security_status):
        # Display security status as a lock icon in the left side of
        # the URL entry.
        if security_status is None:
            self.entry.set_icon_from_pixbuf(
                iconentry.ICON_ENTRY_PRIMARY, None)
        elif security_status == Browser.SECURITY_STATUS_SECURE:
            self.entry.set_icon_from_name(
                iconentry.ICON_ENTRY_PRIMARY, 'channel-secure-symbolic')
        elif security_status == Browser.SECURITY_STATUS_INSECURE:
            self.entry.set_icon_from_name(
                iconentry.ICON_ENTRY_PRIMARY, 'channel-insecure-symbolic')

    def _set_progress(self, progress):
        if progress == 1.0:
            self.entry.set_progress_fraction(0.0)
        else:
            self.entry.set_progress_fraction(progress)

    def _set_address(self, uri):
        if uri is None:
            self.entry.props.address = ''
        else:
            self.entry.props.address = uri

    def __changed_cb(self, iconentry):
        # The WebEntry can be changed when we click on a link, then we
        # have to show the clear icon only if is the user who has
        # changed the entry
        if self.entry.has_focus():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_in_event_cb(self, entry, event):
        if not self._tabbed_view.is_current_page_pdf():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_out_event_cb(self, entry, event):
        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self._show_reload_icon()

    def _show_no_icon(self):
        self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY)

    def _show_stop_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-stop')

    def _show_reload_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-refresh')

    def _show_clear_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-cancel')

    def _update_navigation_buttons(self):
        can_go_back = self._browser.can_go_back()
        self._back.props.sensitive = can_go_back

        can_go_forward = self._browser.can_go_forward()
        self._forward.props.sensitive = can_go_forward

        is_webkit_browser = isinstance(self._browser, Browser)
        self._go_home.props.sensitive = is_webkit_browser
        if is_webkit_browser:
            self._reload_session_history()

    def _entry_activate_cb(self, entry):
        url = entry.props.text
        effective_url = self._tabbed_view.normalize_or_autosearch_url(url)
        self._browser.load_uri(effective_url)
        self._browser.loading_uri = effective_url
        self.entry.props.address = effective_url
        self._browser.grab_focus()

    def _go_home_cb(self, button):
        self.emit('go-home')

    def _go_library_cb(self, button):
        self.emit('go-library')

    def _set_home_cb(self, button):
        self._reset_home_menu.set_visible(True)
        self.emit('set-home')

    def _reset_home_cb(self, button):
        self._reset_home_menu.set_visible(False)
        self.emit('reset-home')

    def _go_back_cb(self, button):
        self._browser.go_back()

    def _go_forward_cb(self, button):
        self._browser.go_forward()

    def __uri_changed_cb(self, widget, param):
        self._set_address(widget.get_uri())
        self._update_navigation_buttons()
        filepicker.cleanup_temp_files()

    def _stop_and_reload_cb(self, entry, icon_pos, button):
        if entry.has_focus() and \
                not self._tabbed_view.is_current_page_pdf():
            entry.set_text('')
        else:
            if self._loading:
                self._browser.stop_loading()
            else:
                self._browser.reload()

    def _set_loading(self, loading):
        self._loading = loading

        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self.set_sensitive(True)
                self._show_reload_icon()
            else:
                self.set_sensitive(False)
                self._show_no_icon()

    def _reload_session_history(self):
        back_forward_list = self._browser.get_back_forward_list()
        item_index = 0  # The index of the history item

        # Clear menus in palettes:
        for box_menu in (self._back_box_menu, self._forward_box_menu):
            for menu_item in box_menu.get_children():
                box_menu.remove(menu_item)

        def create_menu_item(history_item, item_index):
            """Create a MenuItem for the back or forward palettes."""
            title = history_item.get_title()
            if not isinstance(title, unicode):
                title = unicode(title, 'utf-8')
            # This is a fix until the Sugar MenuItem is fixed:
            menu_item = PaletteMenuItem(text_label=title)
            menu_item.connect('activate', self._history_item_activated_cb,
                              item_index)
            return menu_item

        back_list = back_forward_list.get_back_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        back_list.reverse()
        for item in back_list:
            menu_item = create_menu_item(item, item_index)
            self._back_box_menu.pack_end(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

        # Increment the item index to count the current page:
        item_index += 1

        forward_list = back_forward_list.get_forward_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        forward_list.reverse()
        for item in forward_list:
            menu_item = create_menu_item(item, item_index)
            self._forward_box_menu.pack_start(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

    def _history_item_activated_cb(self, menu_item, index):
        self._back.get_palette().popdown(immediate=True)
        self._forward.get_palette().popdown(immediate=True)
        self._browser.set_history_index(index)
Beispiel #41
0
class InstrumentToolbar(Gtk.Toolbar):
    ''' The toolbar for adding new instruments '''
    def __init__(self, activity):
        super(type(self), self).__init__()
        self.activity = activity
        self.new_instruments = []

        self._name_entry = Gtk.Entry()
        self._name_entry.set_text(_('my instrument'))
        self._name_entry_changed_id = self._name_entry.connect(
            'changed', self.update_name_entry)
        if hasattr(self._name_entry, 'set_tooltip_text'):
            self._name_entry.set_tooltip_text(_('Enter instrument name.'))
        self._name_entry.set_width_chars(24)
        self._name_entry.show()
        toolitem = Gtk.ToolItem()
        toolitem.add(self._name_entry)
        self.insert(toolitem, -1)
        toolitem.show()

        self._note = 'A'
        self._notes_button = ToolButton('notes')
        self._notes_button.set_tooltip(_('Notes'))
        self._notes_button.connect('clicked', self._button_selection_cb)
        self.insert(self._notes_button, -1)
        self._setup_notes_palette()
        self._notes_button.show()

        self._octave = 4
        self._octaves_button = ToolButton('octaves')
        self._octaves_button.set_tooltip(_('Octaves'))
        self._octaves_button.connect('clicked', self._button_selection_cb)
        self.insert(self._octaves_button, -1)
        self._setup_octaves_palette()
        self._octaves_button.show()

        self._new_note = ToolButton('list-add')
        self._new_note.show()
        self.insert(self._new_note, -1)
        self._new_note.set_tooltip(_('Add a new note.'))
        self._new_note.connect('clicked', self.new_note_cb)
        self._new_note.show()

    def _button_selection_cb(self, widget):
        palette = widget.get_palette()
        if palette:
            if not palette.is_up():
                palette.popup(immediate=True)
            else:
                palette.popdown(immediate=True)
            return

    def _setup_notes_palette(self):
        self._notes_palette = self._notes_button.get_palette()

        for note in NOTES:
            menu_item = MenuItem(icon_name='', text_label=note)
            menu_item.connect('activate', self._note_selected_cb, note)
            self._notes_palette.menu.append(menu_item)
            menu_item.show()

    def _note_selected_cb(self, widget, note):
        self._note = note

    def _setup_octaves_palette(self):
        self._octaves_palette = self._octaves_button.get_palette()

        for octave in range(9):
            menu_item = MenuItem(icon_name='', text_label=str(octave))
            menu_item.connect('activate', self._octave_selected_cb, octave)
            self._octaves_palette.menu.append(menu_item)
            menu_item.show()

    def _octave_selected_cb(self, widget, octave):
        self._octave = octave

    def update_name_entry(self, *args):
        ''' Add name to INSTRUMENT_DICT and combo box '''
        # Wait until a note has been added...
        return

    def new_note_cb(self, *args):
        ''' Add a new note to instrument tuning list '''
        name = self._name_entry.get_text()
        if name not in INSTRUMENT_DICT:
            INSTRUMENT_DICT[name] = []
            self.activity.tuning_toolbar.instrument.append(name)
            menu_item = MenuItem(icon_name='', text_label=name)
            menu_item.connect(
                'activate',
                self.activity.tuning_toolbar.instrument_selected_cb, name)
            self.activity.tuning_toolbar.instrument_palette.menu.append(
                menu_item)
            menu_item.show()
            self.new_instruments.append(name)

        freq = A0 * pow(TWELTHROOT2,
                        self._octave * 12 + NOTES.index(self._note))
        if freq not in INSTRUMENT_DICT[name]:
            INSTRUMENT_DICT[name].append(freq)
    def _load_custom_buttons(self, toolbar):
        self.numerator = Gtk.Entry()
        self.numerator.set_text('')
        self.numerator.set_tooltip_text(_('numerator'))
        self.numerator.set_width_chars(3)
        toolitem = Gtk.ToolItem()
        toolitem.add(self.numerator)
        self.numerator.show()
        toolbar.insert(toolitem, -1)
        toolitem.show()

        label = Gtk.Label('   /   ')
        toolitem = Gtk.ToolItem()
        toolitem.add(label)
        label.show()
        toolbar.insert(toolitem, -1)
        toolitem.show()

        self.denominator = Gtk.Entry()
        self.denominator.set_text('')
        self.denominator.set_tooltip_text(_('denominator'))
        self.denominator.set_width_chars(3)
        toolitem = Gtk.ToolItem()
        toolitem.add(self.denominator)
        self.denominator.show()
        toolbar.insert(toolitem, -1)
        toolitem.show()

        button = ToolButton('list-add')
        button.set_tooltip(_('add new fraction'))
        button.props.sensitive = True
        button.props.accelerator = 'Return'
        button.connect('clicked', self._add_fraction_cb)
        toolbar.insert(button, -1)
        button.show()

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(False)
        toolbar.insert(separator, -1)
        separator.show()

        button = ToolButton('soccerball')
        button.set_tooltip(_('choose a ball'))
        button.props.sensitive = True
        button.connect('clicked', self._button_palette_cb)
        toolbar.insert(button, -1)
        button.show()
        self._ball_palette = button.get_palette()
        button_grid = Gtk.Grid()
        row = 0
        for ball in BALLDICT.keys():
            if ball == 'custom':
                button = ToolButton('view-source')
            else:
                button = ToolButton(ball)
            button.connect('clicked', self._load_ball_cb, None, ball)
            eventbox = Gtk.EventBox()
            eventbox.connect('button_press_event', self._load_ball_cb,
                             ball)
            label = Gtk.Label(BALLDICT[ball][0])
            eventbox.add(label)
            label.show()
            button_grid.attach(button, 0, row, 1, 1)
            button.show()
            button_grid.attach(eventbox, 1, row, 1, 1)
            eventbox.show()
            row += 1
        self._ball_palette.set_content(button_grid)
        button_grid.show()

        button = ToolButton('insert-picture')
        button.set_tooltip(_('choose a background'))
        button.props.sensitive = True
        button.connect('clicked', self._button_palette_cb)
        toolbar.insert(button, -1)
        button.show()
        self._bg_palette = button.get_palette()
        button_grid = Gtk.Grid()
        row = 0
        for bg in BGDICT.keys():
            if bg == 'custom':
                button = ToolButton('view-source')
            else:
                button = ToolButton(bg)
            button.connect('clicked', self._load_bg_cb, None, bg)
            eventbox = Gtk.EventBox()
            eventbox.connect('button_press_event', self._load_bg_cb, bg)
            label = Gtk.Label(BGDICT[bg][0])
            eventbox.add(label)
            label.show()
            button_grid.attach(button, 0, row, 1, 1)
            button.show()
            button_grid.attach(eventbox, 1, row, 1, 1)
            eventbox.show()
            row += 1
        self._bg_palette.set_content(button_grid)
        button_grid.show()
class ViewToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ViewToolbar'

    __gsignals__ = {
        'go-fullscreen':
        (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([])),
    }

    def __init__(self):
        Gtk.Toolbar.__init__(self)

        self._view = None

        self._zoom_out = ToolButton('zoom-out')
        self._zoom_out.set_tooltip(_('Zoom out'))
        self._zoom_out.connect('clicked', self._zoom_out_cb)
        self.insert(self._zoom_out, -1)
        self._zoom_out.show()

        self._zoom_in = ToolButton('zoom-in')
        self._zoom_in.set_tooltip(_('Zoom in'))
        self._zoom_in.connect('clicked', self._zoom_in_cb)
        self.insert(self._zoom_in, -1)
        self._zoom_in.show()

        self._zoom_to_width = ToolButton('zoom-best-fit')
        self._zoom_to_width.set_tooltip(_('Zoom to width'))
        self._zoom_to_width.connect('clicked', self._zoom_to_width_cb)
        self.insert(self._zoom_to_width, -1)
        self._zoom_to_width.show()

        vbox_menu = Gtk.VBox()
        fit_menu = SugarMenuItem(text_label=_('Zoom to fit'))
        fit_menu.connect('clicked', self._zoom_to_fit_menu_item_activate_cb)
        vbox_menu.add(fit_menu)
        actual_size_menu = SugarMenuItem(text_label=_('Actual size'))
        actual_size_menu.connect('clicked',
                                 self._actual_size_menu_item_activate_cb)
        vbox_menu.add(actual_size_menu)
        vbox_menu.show_all()

        palette = self._zoom_to_width.get_palette()
        palette.set_content(vbox_menu)
        # HACK
        palette._content.set_border_width(1)

        tool_item = Gtk.ToolItem()
        self.insert(tool_item, -1)
        tool_item.show()

        self._zoom_spin = Gtk.SpinButton()
        self._zoom_spin.set_range(5.409, 400)
        self._zoom_spin.set_increments(1, 10)
        self._zoom_spin_notify_value_handler = self._zoom_spin.connect(
            'notify::value', self._zoom_spin_notify_value_cb)
        tool_item.add(self._zoom_spin)
        self._zoom_spin.show()

        zoom_perc_label = Gtk.Label(_("%"))
        zoom_perc_label.show()
        tool_item_zoom_perc_label = Gtk.ToolItem()
        tool_item_zoom_perc_label.add(zoom_perc_label)
        self.insert(tool_item_zoom_perc_label, -1)
        tool_item_zoom_perc_label.show()

        spacer = Gtk.SeparatorToolItem()
        spacer.props.draw = False
        self.insert(spacer, -1)
        spacer.show()

        self._fullscreen = ToolButton('view-fullscreen')
        self._fullscreen.set_tooltip(_('Fullscreen'))
        self._fullscreen.connect('clicked', self._fullscreen_cb)
        self.insert(self._fullscreen, -1)
        self._fullscreen.show()

        self._view_notify_zoom_handler = None

    def set_view(self, view):

        self._view = view

        self._zoom_spin.props.value = self._view.get_zoom()
        self._view_notify_zoom_handler = \
                self._view.connect_zoom_handler(self._view_notify_zoom_cb)

        self._update_zoom_buttons()

    def _zoom_spin_notify_value_cb(self, zoom_spin, pspec):
        self._view.set_zoom(zoom_spin.props.value)

    def _view_notify_zoom_cb(self, model, pspec):
        self._zoom_spin.disconnect(self._zoom_spin_notify_value_handler)
        try:
            self._zoom_spin.props.value = round(self._view.get_zoom())
        finally:
            self._zoom_spin_notify_value_handler = self._zoom_spin.connect(
                'notify::value', self._zoom_spin_notify_value_cb)

    def zoom_in(self):
        self._view.zoom_in()
        self._update_zoom_buttons()

    def _zoom_in_cb(self, button):
        self.zoom_in()

    def zoom_out(self):
        self._view.zoom_out()
        self._update_zoom_buttons()

    def _zoom_out_cb(self, button):
        self.zoom_out()

    def zoom_to_width(self):
        self._view.zoom_to_width()
        self._update_zoom_buttons()

    def _zoom_to_width_cb(self, button):
        self.zoom_to_width()

    def _update_zoom_buttons(self):
        self._zoom_in.props.sensitive = self._view.can_zoom_in()
        self._zoom_out.props.sensitive = self._view.can_zoom_out()
        self._zoom_to_width.props.sensitive = self._view.can_zoom_to_width()

    def _zoom_to_fit_menu_item_activate_cb(self, menu_item):
        self._view.zoom_to_best_fit()
        self._update_zoom_buttons()

    def _actual_size_menu_item_activate_cb(self, menu_item):
        self._view.zoom_to_actual_size()
        self._update_zoom_buttons()

    def _fullscreen_cb(self, button):
        self.emit('go-fullscreen')
class PrimaryToolbar(ToolbarBase):
    __gtype_name__ = 'PrimaryToolbar'

    __gsignals__ = {
        'add-link': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
    }

    def __init__(self, tabbed_view, act):
        ToolbarBase.__init__(self)

        self._activity = act

        self._tabbed_view = tabbed_view

        self._loading = False
        self._title = _('Untitled')

        toolbar = self.toolbar
        activity_button = ActivityToolbarButton(self._activity)
        toolbar.insert(activity_button, 0)

        self._go_home = ToolButton('go-home')
        self._go_home.set_tooltip(_('Home page'))
        self._go_home.connect('clicked', self._go_home_cb)
        toolbar.insert(self._go_home, -1)
        self._go_home.show()

        self.entry = WebEntry()
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'browse-dialog-cancel')
        self.entry.connect('icon-press', self._stop_and_reload_cb)
        self.entry.connect('activate', self._entry_activate_cb)

        entry_item = Gtk.ToolItem()
        entry_item.set_expand(True)
        entry_item.add(self.entry)
        self.entry.show()

        toolbar.insert(entry_item, -1)
        entry_item.show()

        self._back = ToolButton('go-previous-paired')
        self._back.set_tooltip(_('Back'))
        self._back.props.sensitive = False
        self._back.connect('clicked', self._go_back_cb)
        toolbar.insert(self._back, -1)
        self._back.show()

        palette = self._back.get_palette()
        self._back_box_menu = Gtk.VBox()
        self._back_box_menu.show()
        palette.set_content(self._back_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._forward = ToolButton('go-next-paired')
        self._forward.set_tooltip(_('Forward'))
        self._forward.props.sensitive = False
        self._forward.connect('clicked', self._go_forward_cb)
        toolbar.insert(self._forward, -1)
        self._forward.show()

        palette = self._forward.get_palette()
        self._forward_box_menu = Gtk.VBox()
        self._forward_box_menu.show()
        palette.set_content(self._forward_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._link_add = ToolButton('emblem-favorite')
        self._link_add.set_tooltip(_('Bookmark'))
        self._link_add.connect('clicked', self._link_add_clicked_cb)
        toolbar.insert(self._link_add, -1)
        self._link_add.show()

        stop_button = StopButton(self._activity)
        toolbar.insert(stop_button, -1)

        self._progress_listener = None
        self._browser = None

        self._loading_changed_hid = None
        self._progress_changed_hid = None
        self._session_history_changed_hid = None
        self._title_changed_hid = None
        self._uri_changed_hid = None

        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

        tabbed_view.connect_after('switch-page', self.__switch_page_cb)

    def __switch_page_cb(self, tabbed_view, page, page_num):
        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

    def _connect_to_browser(self, browser):
        if self._browser is not None:
            self._browser.disconnect(self._title_changed_hid)
            self._browser.disconnect(self._uri_changed_hid)
            self._browser.disconnect(self._progress_changed_hid)
            self._browser.disconnect(self._loading_changed_hid)

        self._browser = browser
        if self._browser.props.title:
            self._set_title(self._browser.props.title)
        else:
            self._set_title(_('Untitled'))
        self._set_address(self._browser.props.uri)
        self._set_progress(self._browser.props.progress)
        self._set_status(self._browser.props.load_status)

        is_webkit_browser = isinstance(self._browser, Browser)
        self.entry.props.editable = is_webkit_browser

        self._title_changed_hid = self._browser.connect(
            'notify::title', self._title_changed_cb)
        self._uri_changed_hid = self._browser.connect('notify::uri',
                                                      self.__uri_changed_cb)
        self._progress_changed_hid = self._browser.connect(
            'notify::progress', self.__progress_changed_cb)
        self._loading_changed_hid = self._browser.connect(
            'notify::load-status', self.__loading_changed_cb)

        self._update_navigation_buttons()

    def __loading_changed_cb(self, widget, param):
        status = widget.get_load_status()
        if status == WebKit.LoadStatus.FAILED:
            self.entry._set_title(self._title)
        elif WebKit.LoadStatus.PROVISIONAL <= status \
                < WebKit.LoadStatus.FINISHED:
            self.entry._set_title(_('Loading...'))
        elif status == WebKit.LoadStatus.FINISHED:
            if widget.props.title == None:
                self.entry._set_title(_('Untitled'))
                self._title = _('Untitled')
        self._set_status(widget.get_load_status())

    def __progress_changed_cb(self, widget, param):
        self._set_progress(widget.get_progress())

    def _set_status(self, status):
        self._set_loading(status < WebKit.LoadStatus.FINISHED)

    def _set_progress(self, progress):
        if progress == 1.0:
            self.entry.set_progress_fraction(0.0)
        else:
            self.entry.set_progress_fraction(progress)

    def _set_address(self, uri):
        if uri is None:
            self.entry.props.address = ''
        else:
            self.entry.props.address = uri

    def _set_title(self, title):
        self.entry.props.title = title
        self._title = title

    def _show_stop_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'browse-dialog-cancel')

    def _show_reload_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'browse-view-refresh')

    def _update_navigation_buttons(self):
        can_go_back = self._browser.can_go_back()
        self._back.props.sensitive = can_go_back

        can_go_forward = self._browser.can_go_forward()
        self._forward.props.sensitive = can_go_forward

        is_webkit_browser = isinstance(self._browser, Browser)
        self._link_add.props.sensitive = is_webkit_browser
        self._go_home.props.sensitive = is_webkit_browser
        if is_webkit_browser:
            self._reload_session_history()

    def _entry_activate_cb(self, entry):
        url = entry.props.text
        effective_url = self._tabbed_view.normalize_or_autosearch_url(url)
        self._browser.load_uri(effective_url)
        self._browser.grab_focus()

    def _go_home_cb(self, button):
        self.emit('go-home')

    def _go_back_cb(self, button):
        self._browser.go_back()

    def _go_forward_cb(self, button):
        self._browser.go_forward()

    def _title_changed_cb(self, widget, param):
        self._set_title(widget.get_title())

    def __uri_changed_cb(self, widget, param):
        self._set_address(widget.get_uri())
        self._update_navigation_buttons()
        filepicker.cleanup_temp_files()

    def _stop_and_reload_cb(self, entry, icon_pos, button):
        if self._loading:
            self._browser.stop_loading()
        else:
            self._browser.reload()

    def _set_loading(self, loading):
        self._loading = loading

        if self._loading:
            self._show_stop_icon()
        else:
            self._show_reload_icon()

    def _reload_session_history(self):
        back_forward_list = self._browser.get_back_forward_list()
        item_index = 0  # The index of the history item

        # Clear menus in palettes:
        for box_menu in (self._back_box_menu, self._forward_box_menu):
            for menu_item in box_menu.get_children():
                box_menu.remove(menu_item)

        def create_menu_item(history_item, item_index):
            """Create a MenuItem for the back or forward palettes."""
            title = history_item.get_title()
            if not isinstance(title, unicode):
                title = unicode(title, 'utf-8')
            # This is a fix until the Sugar MenuItem is fixed:
            menu_item = SugarMenuItem(text_label=title)
            menu_item.connect('clicked', self._history_item_activated_cb,
                              item_index)
            return menu_item

        back_list = back_forward_list.get_back_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        back_list.reverse()
        for item in back_list:
            menu_item = create_menu_item(item, item_index)
            self._back_box_menu.pack_end(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

        # Increment the item index to count the current page:
        item_index += 1

        forward_list = back_forward_list.get_forward_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        forward_list.reverse()
        for item in forward_list:
            menu_item = create_menu_item(item, item_index)
            self._forward_box_menu.pack_start(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

    def _history_item_activated_cb(self, menu_item, index):
        self._browser.set_history_index(index)

    def _link_add_clicked_cb(self, button):
        self.emit('add-link')
Beispiel #45
0
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)
        self.set_title('FotoToon')

        self._max_participants = 1
        self.page = None

        toolbar_box = ToolbarBox()
        activity_button = ActivityToolbarButton(self)
        activity_toolbar = activity_button.page
        toolbar_box.toolbar.insert(activity_button, 0)

        edit_toolbar_btn = ToolbarButton()
        edit_toolbar = Gtk.Toolbar()
        edit_toolbar_btn.props.page = edit_toolbar
        edit_toolbar_btn.props.icon_name = 'toolbar-edit'
        edit_toolbar_btn.label = _('Edit')
        toolbar_box.toolbar.insert(edit_toolbar_btn, -1)

        view_toolbar_btn = ToolbarButton()
        view_toolbar = Gtk.Toolbar()
        view_toolbar_btn.props.page = view_toolbar
        view_toolbar_btn.props.icon_name = 'toolbar-view'
        view_toolbar_btn.label = _('View')
        toolbar_box.toolbar.insert(view_toolbar_btn, -1)

        slideview_btn = ToggleToolButton('slideshow')
        slideview_btn.set_tooltip(_('Slideshow'))
        slideview_btn.set_active(False)
        slideview_btn.connect('clicked', self._switch_view_mode, False)
        view_toolbar.insert(slideview_btn, -1)
        slideview_btn.show()

        slideview_timings_btn = ToggleToolButton('slideshow-stopwatch')
        slideview_timings_btn.set_tooltip(_('Slideshow with Timings'))
        slideview_timings_btn.set_active(False)
        slideview_timings_btn.connect('clicked', self._switch_view_mode, True)
        view_toolbar.insert(slideview_timings_btn, -1)
        slideview_timings_btn.show()

        time_button = ToolButton('stopwatch')
        time_button.set_tooltip(_('Set Image Duration in Slideshow (Seconds)'))
        view_toolbar.insert(time_button, -1)
        time_button.show()

        self._time_spin = Gtk.SpinButton.new_with_range(MIN_TIME, MAX_TIME, 1)
        self._time_spin.connect('value-changed', self.__time_spin_changed_cb)
        self._time_spin.props.value = DEFAULT_TIME
        self._time_spin.props.update_policy = \
            Gtk.SpinButtonUpdatePolicy.IF_VALID

        palette = time_button.get_palette()
        palette.connect('popup', self.__time_button_popup_cb)
        time_button.connect(
            'clicked', lambda *args: palette.popup(immediate=True,
                                                   state=Palette.SECONDARY))

        alignment = Gtk.Alignment()
        alignment.set_padding(style.DEFAULT_PADDING, style.DEFAULT_PADDING,
                              style.DEFAULT_PADDING, style.DEFAULT_PADDING)
        alignment.add(self._time_spin)
        self._time_spin.show()
        palette.set_content(alignment)
        alignment.show()

        fullscreen_btn = ToolButton('view-fullscreen')
        fullscreen_btn.set_tooltip(_('Fullscreen'))
        fullscreen_btn.props.accelerator = '<Alt>Return'
        fullscreen_btn.connect('clicked', lambda w: self.fullscreen())
        view_toolbar.insert(fullscreen_btn, -1)
        fullscreen_btn.show()

        self.set_toolbar_box(toolbar_box)

        toolbar = toolbar_box.toolbar

        self.page = Page()

        self.globes_manager = GlobesManager(toolbar, edit_toolbar, self)

        # fonts
        self._text_button = ToolbarButton()
        self._text_button.props.page = TextToolbar(self.page)
        self._text_button.props.icon_name = 'format-text-size'
        self._text_button.props.label = _('Text')
        self._toolbar_box.toolbar.insert(self._text_button, -1)

        reorder_img_btn = ToolButton('thumbs-view')
        reorder_img_btn.set_icon_name('thumbs-view')
        reorder_img_btn.set_tooltip(_('Change image order'))
        reorder_img_btn.connect('clicked', self.__image_order_cb)
        edit_toolbar.insert(reorder_img_btn, -1)
        reorder_img_btn.show()

        bgchange = ToolButton(icon_name='contract-coordinates')
        bgchange.set_tooltip(_('Edit background image'))
        bgchange.connect('clicked', self.__bgchange_clicked_cb)
        edit_toolbar.insert(bgchange, -1)
        bgchange.show()

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)

        toolbar_box.toolbar.insert(separator, -1)

        stop = StopButton(self)
        toolbar_box.toolbar.insert(stop, -1)

        toolbar_box.show_all()

        # add export button

        separator_2 = Gtk.SeparatorToolItem()
        separator_2.show()
        activity_toolbar.insert(separator_2, -1)

        self.bt_save_as_image = ToolButton()
        self.bt_save_as_image.props.icon_name = 'save-as-image'
        self.bt_save_as_image.connect('clicked', self.write_image)
        self.bt_save_as_image.set_tooltip(_('Save as Image'))
        activity_toolbar.insert(self.bt_save_as_image, -1)
        self.bt_save_as_image.show()

        save_as_pdf = ToolButton()
        save_as_pdf.props.icon_name = 'save-as-pdf'
        save_as_pdf.connect('clicked', self._save_as_pdf)
        save_as_pdf.set_tooltip(_('Save as a Book (PDF)'))
        activity_toolbar.insert(save_as_pdf, -1)
        save_as_pdf.show()

        save_as_ogg = ToolButton()
        save_as_ogg.props.icon_name = 'save-as-ogg'
        save_as_ogg.connect('clicked', self.__save_as_ogg_cb)
        save_as_ogg.set_tooltip(_('Save as a Movie (OGG)'))
        activity_toolbar.insert(save_as_ogg, -1)
        Gst.init(None)
        if Gst.version_string() != 'GStreamer 1.0.10':
            save_as_ogg.show()

        activity_button.page.title.connect("focus-in-event", self.on_title)

        scrolled = Gtk.ScrolledWindow()
        # scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS)
        scrolled.add_with_viewport(self.page)
        scrolled.set_kinetic_scrolling(False)
        scrolled.show_all()

        self._slideview = SlideView(self)
        self._slideview.show_all()

        self._notebook = Gtk.Notebook()
        self._notebook.set_show_tabs(False)
        self._notebook.append_page(scrolled, None)
        self._notebook.append_page(self._slideview, None)
        self._notebook.show_all()

        if self._jobject.file_path is None or self._jobject.file_path == '':
            empty_widget = EmptyWidget()
            empty_widget.connect('choose-image', self.__add_image)
            self.set_canvas(empty_widget)
        else:
            self.set_canvas(self._notebook)

        self.show()
        self.metadata['mime_type'] = 'application/x-fototoon-activity'

        self.page.empty_page = handle.object_id is None
        self._key_press_signal_id = None
Beispiel #46
0
    def make_toolbar(self):
        def make_separator(expand=True):
            separator = Gtk.SeparatorToolItem()
            separator.props.draw = not expand
            separator.set_expand(expand)
            return separator

        toolbarbox = ToolbarBox()
        self.set_toolbar_box(toolbarbox)

        toolbar = toolbarbox.toolbar
        toolbar.insert(ActivityToolbarButton(self), -1)
        toolbar.insert(make_separator(False), -1)

        self.restart_button = ToolButton(icon_name="system-restart")
        self.restart_button.set_tooltip(_("Restart"))
        self.restart_button.props.accelerator = '<Ctrl>N'
        self.restart_button.connect("clicked", self._restart_cb)
        toolbar.insert(self.restart_button, -1)

        self.ok_button = ToolButton(icon_name="dialog-ok")
        self.ok_button.set_tooltip(_("Ok"))
        self.ok_button.set_sensitive(False)
        self.ok_button.props.accelerator = "Return"
        self.ok_button.connect("clicked", self._ok_cb)
        toolbar.insert(self.ok_button, -1)

        toolbar.insert(make_separator(False), -1)

        button = ToolButton(icon_name="emblem-favorite")
        button.set_tooltip(_("Difficulty"))
        toolbar.insert(button, -1)

        palette = button.get_palette()
        palette_box = Gtk.VBox()
        palette.set_content(palette_box)

        self.easy_button = Gtk.RadioButton(_("Easy"))
        palette_box.pack_start(self.easy_button, False, False, 0)

        self.medium_button = Gtk.RadioButton(_("Medium"),
                                             group=self.easy_button)
        palette_box.pack_start(self.medium_button, False, False, 0)

        self.advanced_button = Gtk.RadioButton(_("Advanced"),
                                               group=self.easy_button)
        palette_box.pack_start(self.advanced_button, False, False, 0)

        self.expert_button = Gtk.RadioButton(_("Expert"),
                                             group=self.easy_button)
        palette_box.pack_start(self.expert_button, False, False, 0)

        palette_box.show_all()

        item = Gtk.ToolItem()
        toolbar.insert(item, -1)

        self.label = Gtk.Label()
        self.label.modify_font(Pango.FontDescription("Bold"))
        item.add(self.label)

        toolbar.insert(make_separator(True), -1)

        helpbutton = HelpButton()
        helpbutton.add_section(_("Instructions:"))
        helpbutton.add_paragraph(_("Place colors to the last played row."),
                                 image="instructions1.png")
        helpbutton.add_paragraph(
            _("When you complete a row, click on 'Ok button'."),
            image="instructions2.png")
        helpbutton.add_paragraph(
            _("Next to the row will appear black and white circles."),
            image="instructions3.png")
        helpbutton.add_paragraph(
            _("A black circle means you matched a peg and you placed it correctly."
              ))
        helpbutton.add_paragraph(
            _("A white circle means you matched a peg and you wrong placed it."
              ))
        helpbutton.add_paragraph(
            _("The goal is match all pegs in the correct place."))
        toolbar.insert(helpbutton, -1)

        stop_button = StopButton(self)
        toolbar.insert(stop_button, -1)

        toolbar.show_all()
Beispiel #47
0
class InsertToolbar(Gtk.Toolbar):

    def __init__(self, abiword_canvas):
        GObject.GObject.__init__(self)

        self._abiword_canvas = abiword_canvas

        self._table_btn = ToolButton('create-table')
        self._table_btn.set_tooltip(_('Create table'))
        self.insert(self._table_btn, -1)
        self._grid_create = GridCreateWidget()
        self._grid_create.show()
        self._grid_create.connect('create-table', self._create_table_cb)
        palette = self._table_btn.get_palette()
        palette.set_content(self._grid_create)
        self._table_btn.connect('clicked', self._table_btn_clicked_cb)

        self._table_rows_after = ToolButton('row-insert')
        self._table_rows_after.set_tooltip(_('Insert Row'))
        self._table_rows_after_id = self._table_rows_after.connect(
            'clicked', self._table_rows_after_cb)
        self.insert(self._table_rows_after, -1)

        self._table_delete_rows = ToolButton('row-remove')
        self._table_delete_rows.set_tooltip(_('Delete Row'))
        self._table_delete_rows_id = self._table_delete_rows.connect(
            'clicked', self._table_delete_rows_cb)
        self.insert(self._table_delete_rows, -1)

        self._table_cols_after = ToolButton('column-insert')
        self._table_cols_after.set_tooltip(_('Insert Column'))
        self._table_cols_after_id = self._table_cols_after.connect(
            'clicked', self._table_cols_after_cb)
        self.insert(self._table_cols_after, -1)

        self._table_delete_cols = ToolButton('column-remove')
        self._table_delete_cols.set_tooltip(_('Delete Column'))
        self._table_delete_cols_id = self._table_delete_cols.connect(
            'clicked', self._table_delete_cols_cb)
        self.insert(self._table_delete_cols, -1)

        self.show_all()

        self._abiword_canvas.connect('table-state', self._isTable_cb)
        #self._abiword_canvas.connect('image-selected',
        #       self._image_selected_cb)

    def _table_btn_clicked_cb(self, button):
        button.get_palette().popup(True, button.get_palette().SECONDARY)

    def _create_table_cb(self, abi, rows, cols):
        self._abiword_canvas.insert_table(rows, cols)

    def _table_rows_after_cb(self, button):
        self._abiword_canvas.invoke_ex('insertRowsAfter', '', 0, 0)

    def _table_delete_rows_cb(self, button):
        self._abiword_canvas.invoke_ex('deleteRows', '', 0, 0)

    def _table_cols_after_cb(self, button):
        self._abiword_canvas.invoke_ex('insertColsAfter', '', 0, 0)

    def _table_delete_cols_cb(self, button):
        self._abiword_canvas.invoke_ex('deleteColumns', '', 0, 0)

    def _isTable_cb(self, abi, b):
        self._table_rows_after.set_sensitive(b)
        self._table_delete_rows.set_sensitive(b)
        self._table_cols_after.set_sensitive(b)
        self._table_delete_cols.set_sensitive(b)
    def __init__(self, handle):
        ''' Initiate activity. '''
        super(AbacusActivity, self).__init__(handle)

        self._setting_up = True
        self.bead_colors = profile.get_color().to_string().split(',')

        # no sharing
        self.max_participants = 1

        self.sep = []
        self.abacus_toolbar = Gtk.Toolbar()
        custom_toolbar = Gtk.Toolbar()
        edit_toolbar = Gtk.Toolbar()

        toolbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        toolbox.toolbar.insert(activity_button, 0)
        activity_button.show()

        edit_toolbar_button = ToolbarButton(label=_('Edit'),
                                            page=edit_toolbar,
                                            icon_name='toolbar-edit')
        edit_toolbar_button.show()
        toolbox.toolbar.insert(edit_toolbar_button, -1)
        edit_toolbar_button.show()

        self.abacus_toolbar_button = ToolbarButton(
            page=self.abacus_toolbar,
            icon_name='abacus-list')
        self.abacus_toolbar.show()
        toolbox.toolbar.insert(self.abacus_toolbar_button, -1)
        self.abacus_toolbar_button.show()

        self.custom_toolbar_button = ToolbarButton(
            page=custom_toolbar,
            icon_name='view-source')
        custom_toolbar.show()
        toolbox.toolbar.insert(self.custom_toolbar_button, -1)
        self.custom_toolbar_button.show()

        separator_factory(toolbox.toolbar, False, True)

        button_factory('edit-delete', toolbox.toolbar,
                       self._reset_cb, tooltip=_('Reset'))

        separator_factory(toolbox.toolbar, False, True)

        self._label = label_factory(NAMES['suanpan'], toolbox.toolbar)

        separator_factory(toolbox.toolbar, True, False)

        stop_button = StopButton(self)
        stop_button.props.accelerator = _('<Ctrl>Q')
        toolbox.toolbar.insert(stop_button, -1)
        stop_button.show()

        self.set_toolbar_box(toolbox)
        toolbox.show()

        self.abacus_buttons = {}

        # Traditional
        self._add_abacus_button('decimal', None)
        self._add_abacus_button('soroban', self.abacus_buttons['decimal'])
        self._add_abacus_button('suanpan', self.abacus_buttons['decimal'])

        self.sep.append(separator_factory(self.abacus_toolbar))

        # Bases other than 10
        self._add_abacus_button('nepohualtzintzin',
                                self.abacus_buttons['decimal'])
        self._add_abacus_button('hexadecimal', self.abacus_buttons['decimal'])
        self._add_abacus_button('binary', self.abacus_buttons['decimal'])

        self.sep.append(separator_factory(self.abacus_toolbar))

        # Fractions
        self._add_abacus_button('schety', self.abacus_buttons['decimal'])
        # self._add_abacus_button('fraction', self.abacus_buttons['decimal'])
        self._add_abacus_button('caacupe', self.abacus_buttons['decimal'])

        self.sep.append(separator_factory(self.abacus_toolbar))

        # Non-traditional
        self._add_abacus_button('cuisenaire', self.abacus_buttons['decimal'])

        self.sep.append(separator_factory(self.abacus_toolbar))

        # Custom
        self._add_abacus_button('custom', self.abacus_buttons['decimal'])

        preferences_button = ToolButton('preferences-system')
        preferences_button.set_tooltip(_('Custom'))
        custom_toolbar.insert(preferences_button, -1)
        preferences_button.palette_invoker.props.toggle_palette = True
        preferences_button.palette_invoker.props.lock_palette = True
        preferences_button.props.hide_tooltip_on_click = False
        preferences_button.show()

        self._palette = preferences_button.get_palette()
        button_box = Gtk.VBox()
        # TRANS: Number of rods on the abacus
        self._rods_spin = add_spinner_and_label(
            15, 1, MAX_RODS, _('Rods:'), self._rods_spin_cb, button_box)
        # TRANS: Number of beads in the top section of the abacus
        self._top_spin = add_spinner_and_label(
            2, 0, MAX_TOP, _('Top:'), self._top_spin_cb, button_box)
        # TRANS: Number of beads in the bottom section of the abacus
        self._bottom_spin = add_spinner_and_label(
            5, 0, MAX_BOT, _('Bottom:'), self._bottom_spin_cb, button_box)
        # TRANS: Scale factor between bottom and top beads
        self._value_spin = add_spinner_and_label(
            5, 1, MAX_BOT + 1, _('Factor:'), self._value_spin_cb, button_box)
        # TRANS: Scale factor between rods
        self._base_spin = add_spinner_and_label(
            10, 1, (MAX_TOP + 1) * MAX_BOT, _('Base:'), self._base_spin_cb,
            button_box)
        hbox = Gtk.HBox()
        hbox.pack_start(button_box, True, True, style.DEFAULT_SPACING)
        hbox.show_all()
        self._palette.set_content(hbox)

        separator_factory(custom_toolbar, False, False)

        self.custom_maker = button_factory('new-abacus', custom_toolbar,
                                           self._custom_cb,
                                           tooltip=_('Custom'))

        button_factory('edit-copy', edit_toolbar, self._copy_cb,
                       tooltip=_('Copy'), accelerator='<Ctrl>c')
        button_factory('edit-paste', edit_toolbar, self._paste_cb,
                       tooltip=_('Paste'), accelerator='<Ctrl>v')

        # Create a canvas
        canvas = Gtk.DrawingArea()
        canvas.set_size_request(Gdk.Screen.width(),
                                Gdk.Screen.height())
        self.set_canvas(canvas)
        canvas.show()
        self.show_all()

        # Initialize the canvas
        self.abacus = Abacus(canvas, self)

        self._setting_up = False

        # Read the current mode from the Journal
        if 'rods' in self.metadata:
            self._rods_spin.set_value(int(self.metadata['rods']))
        if 'top' in self.metadata:
            self._top_spin.set_value(int(self.metadata['top']))
        if 'bottom' in self.metadata:
            self._bottom_spin.set_value(int(self.metadata['bottom']))
        if 'factor' in self.metadata:
            self._value_spin.set_value(int(self.metadata['factor']))
        if 'base' in self.metadata:
            self._base_spin.set_value(int(self.metadata['base']))
        if 'abacus' in self.metadata:
            if self.metadata['abacus'] in self.abacus_buttons:
                _logger.debug('restoring %s', self.metadata['abacus'])
                if self.metadata['abacus'] == 'custom':
                    self._custom_cb()
                self.abacus_buttons[self.metadata['abacus']].set_active(True)
            else:  # Default is Chinese
                self.abacus_buttons['suanpan'].set_active(True)

            if 'value' in self.metadata:
                _logger.debug('restoring value %s', self.metadata['value'])
                self.abacus.mode.set_value(self.metadata['value'])
                self.abacus.mode.label(self.abacus.generate_label())

        self.abacus.init()

        # Start with abacus toolbar expanded and suanpan as default
        self.abacus_toolbar_button.set_expanded(True)
    def _load_custom_buttons(self, toolbar):
        self.numerator = Gtk.Entry()
        self.numerator.set_text('')
        self.numerator.set_tooltip_text(_('numerator'))
        self.numerator.set_width_chars(3)
        toolitem = Gtk.ToolItem()
        toolitem.add(self.numerator)
        self.numerator.show()
        toolbar.insert(toolitem, -1)
        toolitem.show()

        label = Gtk.Label('   /   ')
        toolitem = Gtk.ToolItem()
        toolitem.add(label)
        label.show()
        toolbar.insert(toolitem, -1)
        toolitem.show()

        self.denominator = Gtk.Entry()
        self.denominator.set_text('')
        self.denominator.set_tooltip_text(_('denominator'))
        self.denominator.set_width_chars(3)
        toolitem = Gtk.ToolItem()
        toolitem.add(self.denominator)
        self.denominator.show()
        toolbar.insert(toolitem, -1)
        toolitem.show()

        button = ToolButton('list-add')
        button.set_tooltip(_('add new fraction'))
        button.props.sensitive = True
        button.props.accelerator = 'Return'
        button.connect('clicked', self._add_fraction_cb)
        toolbar.insert(button, -1)
        button.show()

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(False)
        toolbar.insert(separator, -1)
        separator.show()

        button = ToolButton('soccerball')
        button.set_tooltip(_('choose a ball'))
        button.props.sensitive = True
        button.connect('clicked', self._button_palette_cb)
        toolbar.insert(button, -1)
        button.show()
        self._ball_palette = button.get_palette()
        button_grid = Gtk.Grid()
        row = 0
        for ball in BALLDICT.keys():
            if ball == 'custom':
                button = ToolButton('view-source')
            else:
                button = ToolButton(ball)
            button.connect('clicked', self._load_ball_cb, None, ball)
            eventbox = Gtk.EventBox()
            eventbox.connect('button_press_event', self._load_ball_cb, ball)
            label = Gtk.Label(BALLDICT[ball][0])
            eventbox.add(label)
            label.show()
            button_grid.attach(button, 0, row, 1, 1)
            button.show()
            button_grid.attach(eventbox, 1, row, 1, 1)
            eventbox.show()
            row += 1
        self._ball_palette.set_content(button_grid)
        button_grid.show()

        button = ToolButton('insert-picture')
        button.set_tooltip(_('choose a background'))
        button.props.sensitive = True
        button.connect('clicked', self._button_palette_cb)
        toolbar.insert(button, -1)
        button.show()
        self._bg_palette = button.get_palette()
        button_grid = Gtk.Grid()
        row = 0
        for bg in BGDICT.keys():
            if bg == 'custom':
                button = ToolButton('view-source')
            else:
                button = ToolButton(bg)
            button.connect('clicked', self._load_bg_cb, None, bg)
            eventbox = Gtk.EventBox()
            eventbox.connect('button_press_event', self._load_bg_cb, bg)
            label = Gtk.Label(BGDICT[bg][0])
            eventbox.add(label)
            label.show()
            button_grid.attach(button, 0, row, 1, 1)
            button.show()
            button_grid.attach(eventbox, 1, row, 1, 1)
            eventbox.show()
            row += 1
        self._bg_palette.set_content(button_grid)
        button_grid.show()
Beispiel #50
0
class Toolbar(ToolbarBox):

    def __init__(self, activity):

        ToolbarBox.__init__(self)

        activity_button = ActivityToolbarButton(activity)
        self.toolbar.insert(activity_button, 0)
        activity_button.show()

        separator = Gtk.SeparatorToolItem()
        self.toolbar.insert(separator, -1)

        self.choose_button = RadioToolButton('view-list')
        self.choose_button.set_tooltip(_('Choose a Poll'))
        self.toolbar.insert(self.choose_button, -1)
        modes_group = self.choose_button

        self.create_button = RadioToolButton('new-poll')
        self.create_button.set_tooltip(_('Build a Poll'))
        self.toolbar.insert(self.create_button, -1)
        self.create_button.props.group = modes_group

        self.settings_button = ToolButton('preferences-system')
        self.settings_button.set_tooltip(_('Settings'))
        self.settings_button.palette_invoker.props.toggle_palette = True
        self.settings_button.palette_invoker.props.lock_palette = True
        self.settings_button.props.hide_tooltip_on_click = False

        palette = self.settings_button.get_palette()
        hbox = Gtk.HBox()
        self._options_palette = OptionsPalette(activity)
        hbox.pack_start(self._options_palette, True, True,
                        style.DEFAULT_SPACING)
        hbox.show_all()
        palette.set_content(hbox)
        self.toolbar.insert(self.settings_button, -1)

        self.toolbar.insert(Gtk.SeparatorToolItem(), -1)

        self.pie_chart_button = RadioToolButton('pie-chart')
        self.pie_chart_button.set_tooltip(_('Pie chart'))
        self.toolbar.insert(self.pie_chart_button, -1)
        charts_group = self.pie_chart_button

        self.vbar_chart_button = RadioToolButton('vbar-chart')
        self.vbar_chart_button.set_tooltip(_('Vertical bar chart'))
        self.toolbar.insert(self.vbar_chart_button, -1)
        self.vbar_chart_button.props.group = charts_group

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)
        self.toolbar.insert(separator, -1)
        separator.show()

        self.toolbar.insert(StopButton(activity), -1)

        # add the export buttons
        activity_button.page.insert(Gtk.SeparatorToolItem(), -1)

        self.export_data_bt = ToolButton('save-as-data')
        self.export_data_bt.props.tooltip = _('Export data')
        activity_button.page.insert(self.export_data_bt, -1)

        self.export_image_bt = ToolButton('save-as-image')
        self.export_image_bt.set_tooltip(_("Save as Image"))
        activity_button.page.insert(self.export_image_bt, -1)
        activity_button.page.show_all()

        self.show_all()

    def update_configs(self):
        self._options_palette.update_configs()
Beispiel #51
0
class PrimaryToolbar(ToolbarBase):
    __gtype_name__ = 'PrimaryToolbar'

    __gsignals__ = {
        'add-link': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'go-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'set-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'reset-home': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'go-library': (GObject.SignalFlags.RUN_FIRST, None, ([])),
    }

    def __init__(self, tabbed_view, act):
        ToolbarBase.__init__(self)

        self._url_toolbar = UrlToolbar()

        self._activity = act

        self._tabbed_view = self._canvas = tabbed_view

        self._loading = False

        toolbar = self.toolbar
        activity_button = ActivityToolbarButton(self._activity)
        toolbar.insert(activity_button, 0)

        separator = Gtk.SeparatorToolItem()

        save_as_pdf = ToolButton('save-as-pdf')
        save_as_pdf.set_tooltip(_('Save page as pdf'))
        save_as_pdf.connect('clicked', self.save_as_pdf)

        activity_button.props.page.insert(separator, -1)
        activity_button.props.page.insert(save_as_pdf, -1)
        separator.show()
        save_as_pdf.show()

        self._go_home = ToolButton('go-home')
        self._go_home.set_tooltip(_('Home page'))
        self._go_home.connect('clicked', self._go_home_cb)
        # add a menu to save the home page
        menu_box = PaletteMenuBox()
        self._go_home.props.palette.set_content(menu_box)
        menu_item = PaletteMenuItem()
        menu_item.set_label(_('Select as initial page'))
        menu_item.connect('activate', self._set_home_cb)
        menu_box.append_item(menu_item)

        self._reset_home_menu = PaletteMenuItem()
        self._reset_home_menu.set_label(_('Reset initial page'))
        self._reset_home_menu.connect('activate', self._reset_home_cb)
        menu_box.append_item(self._reset_home_menu)

        if os.path.isfile(LIBRARY_PATH):
            library_menu = PaletteMenuItem()
            library_menu.set_label(_('Library'))
            library_menu.connect('activate', self._go_library_cb)
            menu_box.append_item(library_menu)

        menu_box.show_all()

        # verify if the home page is configured
        client = GConf.Client.get_default()
        self._reset_home_menu.set_visible(
            client.get_string(HOME_PAGE_GCONF_KEY) is not None)

        toolbar.insert(self._go_home, -1)
        self._go_home.show()

        self.entry = WebEntry()
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-stop')
        self.entry.connect('icon-press', self._stop_and_reload_cb)
        self.entry.connect('activate', self._entry_activate_cb)
        self.entry.connect('focus-in-event', self.__focus_in_event_cb)
        self.entry.connect('focus-out-event', self.__focus_out_event_cb)
        self.entry.connect('key-press-event', self.__key_press_event_cb)
        self.entry.connect('changed', self.__changed_cb)

        self._entry_item = Gtk.ToolItem()
        self._entry_item.set_expand(True)
        self._entry_item.add(self.entry)
        self.entry.show()

        toolbar.insert(self._entry_item, -1)

        self._entry_item.show()

        self._back = ToolButton('go-previous-paired')
        self._back.set_tooltip(_('Back'))
        self._back.props.sensitive = False
        self._back.connect('clicked', self._go_back_cb)
        toolbar.insert(self._back, -1)
        self._back.show()

        palette = self._back.get_palette()
        self._back_box_menu = Gtk.VBox()
        self._back_box_menu.show()
        palette.set_content(self._back_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        self._forward = ToolButton('go-next-paired')
        self._forward.set_tooltip(_('Forward'))
        self._forward.props.sensitive = False
        self._forward.connect('clicked', self._go_forward_cb)
        toolbar.insert(self._forward, -1)
        self._forward.show()

        palette = self._forward.get_palette()
        self._forward_box_menu = Gtk.VBox()
        self._forward_box_menu.show()
        palette.set_content(self._forward_box_menu)
        # FIXME, this is a hack, should be done in the theme:
        palette._content.set_border_width(1)

        # Downloads ProgressIcon
        self._download_icon = ProgressToolButton('emblem-downloads',
                                                 style.STANDARD_ICON_SIZE,
                                                 'vertical')
        self._download_icon.set_tooltip(_('Downloads'))
        self._download_icon.props.sensitive = False
        down_id = GObject.timeout_add(500, self.__download_running_cb)
        toolbar.insert(self._download_icon, -1)
        self._download_icon.show()

        self._link_add = ToolButton('emblem-favorite')
        self._link_add.set_tooltip(_('Bookmark'))
        self._link_add.connect('clicked', self._link_add_clicked_cb)
        toolbar.insert(self._link_add, -1)
        self._link_add.show()

        self._toolbar_separator = Gtk.SeparatorToolItem()
        self._toolbar_separator.props.draw = False
        self._toolbar_separator.set_expand(True)

        # Adds an options-toolbar button to the main-toolbar
        self._options_toolbar = OptionsToolbar(self._activity)
        self._options_toolbar_button = ToolbarButton(
            page=self._options_toolbar, icon_name='options')
        toolbar.insert(self._options_toolbar_button, -1)

        stop_button = StopButton(self._activity)
        toolbar.insert(stop_button, -1)

        self._progress_listener = None
        self._browser = None

        self._loading_changed_hid = None
        self._progress_changed_hid = None
        self._session_history_changed_hid = None
        self._uri_changed_hid = None
        self._security_status_changed_hid = None

        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

        tabbed_view.connect_after('switch-page', self.__switch_page_cb)
        tabbed_view.connect_after('page-added', self.__page_added_cb)

        Gdk.Screen.get_default().connect('size-changed',
                                         self.__screen_size_changed_cb)

        self._configure_toolbar()

    def __download_running_cb(self):
        '''
        Updates the downloadIcon tooltip message and progress value.
        '''
        progress = downloadmanager.overall_downloads_progress()
        self._download_icon.update(progress)
        if progress > 0.0:
            self._download_icon.set_tooltip(
                _("Downloading.. {}%".format(int(progress * 100))))
        else:
            self._download_icon.set_tooltip(_("No active downloads"))
        return True

    def __key_press_event_cb(self, entry, event):
        self._tabbed_view.current_browser.loading_uri = entry.props.text

    def __switch_page_cb(self, tabbed_view, page, page_num):
        if tabbed_view.get_n_pages():
            self._connect_to_browser(tabbed_view.props.current_browser)

    def __page_added_cb(self, notebook, child, pagenum):
        self.entry._search_popdown()

    def _configure_toolbar(self, screen=None):
        # Adapt the toolbars for portrait or landscape mode.

        if screen is None:
            screen = Gdk.Screen.get_default()

        if screen.get_width() < screen.get_height():
            if self._entry_item in self._url_toolbar.toolbar.get_children():
                return

            self.toolbar.remove(self._entry_item)
            self._url_toolbar.toolbar.insert(self._entry_item, -1)

            separator_pos = len(self.toolbar.get_children()) - 1
            self.toolbar.insert(self._toolbar_separator, separator_pos)
            self._toolbar_separator.show()

            self.pack_end(self._url_toolbar, True, True, 0)
            self._url_toolbar.show()

        else:
            if self._entry_item in self.toolbar.get_children():
                return

            self.toolbar.remove(self._toolbar_separator)

            position = len(self.toolbar.get_children()) - 4
            self._url_toolbar.toolbar.remove(self._entry_item)
            self.toolbar.insert(self._entry_item, position)

            self._toolbar_separator.hide()
            self.remove(self._url_toolbar)

    def __screen_size_changed_cb(self, screen):
        self._configure_toolbar(screen)

    def _connect_to_browser(self, browser):
        if self._browser is not None:
            self._browser.disconnect(self._uri_changed_hid)
            self._browser.disconnect(self._progress_changed_hid)
            self._browser.disconnect(self._loading_changed_hid)
            self._browser.disconnect(self._security_status_changed_hid)

        self._browser = browser
        if not isinstance(self._browser, DummyBrowser):
            address = self._browser.props.uri or self._browser.loading_uri
        else:
            address = self._browser.props.uri
        self._set_address(address)
        self._set_progress(self._browser.props.progress)
        self._set_status(self._browser.props.load_status)
        self._set_security_status(self._browser.security_status)

        is_webkit_browser = isinstance(self._browser, Browser)
        self.entry.props.editable = is_webkit_browser

        self._uri_changed_hid = self._browser.connect('notify::uri',
                                                      self.__uri_changed_cb)
        self._progress_changed_hid = self._browser.connect(
            'notify::progress', self.__progress_changed_cb)
        self._loading_changed_hid = self._browser.connect(
            'notify::load-status', self.__loading_changed_cb)
        self._security_status_changed_hid = self._browser.connect(
            'security-status-changed', self.__security_status_changed_cb)

        self._update_navigation_buttons()

    def __loading_changed_cb(self, widget, param):
        self._set_status(widget.get_load_status())

    def __security_status_changed_cb(self, widget):
        self._set_security_status(widget.security_status)

    def __progress_changed_cb(self, widget, param):
        self._set_progress(widget.get_progress())

    def _set_status(self, status):
        self._set_loading(status < WebKit.LoadStatus.FINISHED)

    def _set_security_status(self, security_status):
        # Display security status as a lock icon in the left side of
        # the URL entry.
        if security_status is None:
            self.entry.set_icon_from_pixbuf(iconentry.ICON_ENTRY_PRIMARY, None)
        elif security_status == Browser.SECURITY_STATUS_SECURE:
            self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                          'channel-secure-symbolic')
        elif security_status == Browser.SECURITY_STATUS_INSECURE:
            self.entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                          'channel-insecure-symbolic')

    def _set_progress(self, progress):
        if progress == 1.0:
            self.entry.set_progress_fraction(0.0)
        else:
            self.entry.set_progress_fraction(progress)

    def _set_address(self, uri):
        if uri is None:
            self.entry.props.address = ''
        else:
            self.entry.props.address = uri

    def __changed_cb(self, iconentry):
        # The WebEntry can be changed when we click on a link, then we
        # have to show the clear icon only if is the user who has
        # changed the entry
        if self.entry.has_focus():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_in_event_cb(self, entry, event):
        if not self._tabbed_view.is_current_page_pdf():
            if not self.entry.props.text:
                self._show_no_icon()
            else:
                self._show_clear_icon()

    def __focus_out_event_cb(self, entry, event):
        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self._show_reload_icon()

    def _show_no_icon(self):
        self.entry.remove_icon(iconentry.ICON_ENTRY_SECONDARY)

    def _show_stop_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-stop')

    def _show_reload_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-refresh')

    def _show_clear_icon(self):
        self.entry.set_icon_from_name(iconentry.ICON_ENTRY_SECONDARY,
                                      'entry-cancel')

    def _update_navigation_buttons(self):
        can_go_back = self._browser.can_go_back()
        self._back.props.sensitive = can_go_back

        can_go_forward = self._browser.can_go_forward()
        self._forward.props.sensitive = can_go_forward

        is_webkit_browser = isinstance(self._browser, Browser)
        self._link_add.props.sensitive = is_webkit_browser
        self._go_home.props.sensitive = is_webkit_browser
        if is_webkit_browser:
            self._reload_session_history()

    def _entry_activate_cb(self, entry):
        url = entry.props.text
        effective_url = self._tabbed_view.normalize_or_autosearch_url(url)
        self._browser.load_uri(effective_url)
        self._browser.loading_uri = effective_url
        self.entry.props.address = effective_url
        self._browser.grab_focus()

    def _go_home_cb(self, button):
        self.emit('go-home')

    def _go_library_cb(self, button):
        self.emit('go-library')

    def _set_home_cb(self, button):
        self._reset_home_menu.set_visible(True)
        self.emit('set-home')

    def _reset_home_cb(self, button):
        self._reset_home_menu.set_visible(False)
        self.emit('reset-home')

    def _go_back_cb(self, button):
        self._browser.go_back()

    def _go_forward_cb(self, button):
        self._browser.go_forward()

    def __uri_changed_cb(self, widget, param):
        self._set_address(widget.get_uri())
        self._update_navigation_buttons()
        filepicker.cleanup_temp_files()

    def _stop_and_reload_cb(self, entry, icon_pos, button):
        if entry.has_focus() and \
                not self._tabbed_view.is_current_page_pdf():
            entry.set_text('')
        else:
            if self._loading:
                self._browser.stop_loading()
            else:
                self._browser.reload()

    def _set_loading(self, loading):
        self._loading = loading

        if self._loading:
            self._show_stop_icon()
        else:
            if not self._tabbed_view.is_current_page_pdf():
                self.set_sensitive(True)
                self._show_reload_icon()
            else:
                self.set_sensitive(False)
                self._show_no_icon()

    def _reload_session_history(self):
        back_forward_list = self._browser.get_back_forward_list()
        item_index = 0  # The index of the history item

        # Clear menus in palettes:
        for box_menu in (self._back_box_menu, self._forward_box_menu):
            for menu_item in box_menu.get_children():
                box_menu.remove(menu_item)

        def create_menu_item(history_item, item_index):
            """Create a MenuItem for the back or forward palettes."""
            title = history_item.get_title()
            if not isinstance(title, unicode):
                title = unicode(title, 'utf-8')
            # This is a fix until the Sugar MenuItem is fixed:
            menu_item = PaletteMenuItem(text_label=title)
            menu_item.connect('activate', self._history_item_activated_cb,
                              item_index)
            return menu_item

        back_list = back_forward_list.get_back_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        back_list.reverse()
        for item in back_list:
            menu_item = create_menu_item(item, item_index)
            self._back_box_menu.pack_end(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

        # Increment the item index to count the current page:
        item_index += 1

        forward_list = back_forward_list.get_forward_list_with_limit(
            _MAX_HISTORY_ENTRIES)
        forward_list.reverse()
        for item in forward_list:
            menu_item = create_menu_item(item, item_index)
            self._forward_box_menu.pack_start(menu_item, False, False, 0)
            menu_item.show()
            item_index += 1

    def _history_item_activated_cb(self, menu_item, index):
        self._back.get_palette().popdown(immediate=True)
        self._forward.get_palette().popdown(immediate=True)
        self._browser.set_history_index(index)

    def _link_add_clicked_cb(self, button):
        self.emit('add-link')

    def save_as_pdf(self, widget):
        tmp_dir = os.path.join(self._activity.get_activity_root(), 'tmp')
        fd, file_path = tempfile.mkstemp(dir=tmp_dir)
        os.close(fd)

        page = self._canvas.get_current_page()
        webview = self._canvas.get_children()[page].get_children()[0]

        operation = Gtk.PrintOperation.new()
        operation.set_export_filename(file_path)

        webview.get_main_frame().print_full(operation,
                                            Gtk.PrintOperationAction.EXPORT)

        client = GConf.Client.get_default()
        jobject = datastore.create()
        color = client.get_string('/desktop/sugar/user/color')
        try:
            jobject.metadata['title'] = _('Browse activity as PDF')
            jobject.metadata['icon-color'] = color
            jobject.metadata['mime_type'] = 'application/pdf'
            jobject.file_path = file_path
            datastore.write(jobject)
        finally:
            self.__pdf_alert(jobject.object_id)
            jobject.destroy()
            del jobject

    def __pdf_alert(self, object_id):
        alert = Alert()
        alert.props.title = _('Page saved')
        alert.props.msg = _('The page has been saved as PDF to journal')

        alert.add_button(Gtk.ResponseType.APPLY, _('Show in Journal'),
                         Icon(icon_name='zoom-activity'))
        alert.add_button(Gtk.ResponseType.OK, _('Ok'),
                         Icon(icon_name='dialog-ok'))

        # Remove other alerts
        for alert in self._activity._alerts:
            self._activity.remove_alert(alert)

        self._activity.add_alert(alert)
        alert.connect('response', self.__pdf_response_alert, object_id)
        alert.show_all()

    def __pdf_response_alert(self, alert, response_id, object_id):

        if response_id is Gtk.ResponseType.APPLY:
            activity.show_object_in_journal(object_id)

        self._activity.remove_alert(alert)
Beispiel #52
0
class ReadToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ReadToolbar'

    def __init__(self):
        GObject.GObject.__init__(self)
        self.back = ToolButton('go-previous')
        self.back.set_tooltip(_('Back'))
        self.back.props.sensitive = False
        palette = self.back.get_palette()
        self.prev_page = MenuItem(text_label=_("Previous page"))
        palette.menu.append(self.prev_page)
        self.prev_page.show_all()
        self.back.connect('clicked', self.go_back_cb)
        self.prev_page.connect('activate', self.go_back_cb)
        self.insert(self.back, -1)
        self.back.show()

        self.forward = ToolButton('go-next')
        self.forward.set_tooltip(_('Forward'))
        self.forward.props.sensitive = False
        palette = self.forward.get_palette()
        self.next_page = MenuItem(text_label=_("Next page"))
        palette.menu.append(self.next_page)
        self.next_page.show_all()
        self.forward.connect('clicked', self.go_forward_cb)
        self.next_page.connect('activate', self.go_forward_cb)
        self.insert(self.forward, -1)
        self.forward.show()

        num_page_item = Gtk.ToolItem()

        self._num_page_entry = Gtk.Entry()
        self._num_page_entry.set_text('0')
        self._num_page_entry.set_alignment(1)
        self._num_page_entry.connect('insert-text',
                                     self._num_page_entry_insert_text_cb)
        self._num_page_entry.connect('activate',
                                     self._num_page_entry_activate_cb)

        self._num_page_entry.set_width_chars(4)

        num_page_item.add(self._num_page_entry)
        self._num_page_entry.show()

        self.insert(num_page_item, -1)
        num_page_item.show()

        total_page_item = Gtk.ToolItem()

        self._total_page_label = Gtk.Label()

        self._total_page_label.set_text(' / 0')
        total_page_item.add(self._total_page_label)
        self._total_page_label.show()

        self.insert(total_page_item, -1)
        total_page_item.show()

    def _num_page_entry_insert_text_cb(self, entry, text, length, position):
        if not re.match('[0-9]', text):
            entry.emit_stop_by_name('insert-text')
            return True
        return False

    def _num_page_entry_activate_cb(self, entry):
        if entry.props.text:
            page = int(entry.props.text) - 1
        else:
            page = 0

        if page >= self.total_pages:
            page = self.total_pages - 1
        elif page < 0:
            page = 0

        self.current_page = page
        self.activity.set_current_page(page)
        self.activity.show_page(page)
        entry.props.text = str(page + 1)
        self._update_nav_buttons()

    def go_back_cb(self, button):
        self.activity.previous_page()

    def go_forward_cb(self, button):
        self.activity.next_page()

    def _update_nav_buttons(self):
        current_page = self.current_page
        self.back.props.sensitive = current_page > 0
        self.forward.props.sensitive = \
            current_page < self.total_pages - 1

        self._num_page_entry.props.text = str(current_page + 1)
        self._total_page_label.props.label = \
            ' / ' + str(self.total_pages)

    def set_total_pages(self, pages):
        self.total_pages = pages

    def set_current_page(self, page):
        self.current_page = page
        self._update_nav_buttons()

    def set_activity(self, activity):
        self.activity = activity

    def setToggleButtonState(self, button, b, id):
        button.handler_block(id)
        button.set_active(b)
        button.handler_unblock(id)