Ejemplo n.º 1
0
    def __init__(self):
        Gtk.Toolbar.__init__(self)

        self.button = ToolbarButton(page=self, icon_name="toolbar-view")

        self.buttons = {
            CelestialBodyType.MERCURY: None,
            CelestialBodyType.VENUS: None,
            CelestialBodyType.EARTH: None,
            CelestialBodyType.MARS: None,
            CelestialBodyType.JUPITER: None,
            CelestialBodyType.SATURN: None,
            CelestialBodyType.URANUS: None,
            CelestialBodyType.NEPTUNE: None
        }

        self.orbits_button = ToggleToolButton("show-orbits")
        self.orbits_button.set_tooltip(_("Show planets orbits"))
        self.orbits_button.set_active(True)
        self.orbits_button.connect("toggled", self._show_orbits_cb)
        self.insert(self.orbits_button, -1)

        self.insert(make_separator(False), -1)

        for planet in self.buttons:
            button = ToggleToolButton(get_icon_name(planet))
            button.set_tooltip(get_body_name(planet))
            button.set_active(True)
            button.connect("toggled", self._show_planet_cb, planet)
            self.insert(button, -1)

            self.buttons[planet] = button

        self.show_all()
Ejemplo n.º 2
0
class ViewToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ViewToolbar'

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

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

        self._show_playlist = ToggleToolButton('view-list')
        self._show_playlist.set_active(False)
        self._show_playlist.set_tooltip(_('Show Playlist'))
        self._show_playlist.connect('toggled', self._playlist_toggled_cb)
        self.insert(self._show_playlist, -1)
        self._show_playlist.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()

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

    def _playlist_toggled_cb(self, button):
        self.emit('toggle-playlist')
Ejemplo n.º 3
0
class ViewToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ViewToolbar'

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

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

        self._show_playlist = ToggleToolButton('view-list')
        self._show_playlist.set_active(True)  # due to Activity.show_all()
        self._show_playlist.set_tooltip(_('Playlist'))
        self._show_playlist.set_accelerator('<ctrl>l')
        self._show_playlist.connect('toggled', self._playlist_toggled_cb)
        self.insert(self._show_playlist, -1)
        self._show_playlist.show()

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

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

    def _playlist_toggled_cb(self, button):
        self.emit('toggle-playlist')
Ejemplo n.º 4
0
    def __init__(self, conf):
        Gtk.Toolbar.__init__(self)

        self.button = ToolbarButton(page=self, icon_name="toolbar-view")

        combo_font = FontComboBox(conf["font"])
        combo_font.connect("changed", self.__font_changed_cb)
        self.insert(combo_font, -1)

        item_font_size = FontSize()
        item_font_size.set_font_size(conf["font-size"])
        item_font_size.connect("changed", self.__font_size_changed_cb)
        self.insert(item_font_size, -1)

        self.insert(utils.make_separator(False), -1)

        button_numbers = ToggleToolButton("show-numbers")
        button_numbers.props.accelerator = "<Ctrl><Mayus>N"
        button_numbers.set_tooltip(_("Show line numbers"))
        button_numbers.set_active(conf["show-line-numbers"])
        button_numbers.connect("toggled", self.__show_line_numbers_changed_cb)
        self.insert(button_numbers, -1)

        button_right_line = ToggleToolButton("show-right-line")
        button_right_line.props.accelerator = "<Ctrl>L"
        button_right_line.set_tooltip(_("Show a line in a specific position"))
        button_right_line.set_active(conf["show-right-line"])
        button_right_line.connect("toggled", self.__show_right_line_changed_cb)
        self.insert(button_right_line, -1)

        adjustement = Gtk.Adjustment(
            value=conf["right-line-pos"],
            lower=1,
            upper=150,
            step_increment=1,
            page_increment=5,
            page_size=0,
        )

        toolItem1 = Gtk.ToolItem()
        self.spinner_right_line = Gtk.SpinButton()
        self.spinner_right_line.set_margin_left(5)
        self.spinner_right_line.set_adjustment(adjustement)

        # Ensuring that the value is displayed when starting:
        self.spinner_right_line.set_value(conf["right-line-pos"])
        self.spinner_right_line.connect('notify::value',
            self.__right_line_pos_changed_cb)

        toolItem1.add(self.spinner_right_line)
        self.insert(toolItem1, -1)

        self.insert(utils.make_separator(False), -1)

        combo_styles = ComboStyles(conf["theme"])
        combo_styles.connect("theme-changed", self.__theme_changed_cb)
        self.insert(combo_styles, -1)

        self.show_all()
Ejemplo n.º 5
0
class ToolbarView(Gtk.Toolbar):

    __gsignals__ = {
        "show-orbits": (GObject.SIGNAL_RUN_FIRST, None, [bool]),
        "show-body": (GObject.SIGNAL_RUN_FIRST, None, [int, bool]),
    }

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

        self.button = ToolbarButton(page=self, icon_name="toolbar-view")

        self.buttons = {
            CelestialBodyType.MERCURY: None,
            CelestialBodyType.VENUS: None,
            CelestialBodyType.EARTH: None,
            CelestialBodyType.MARS: None,
            CelestialBodyType.JUPITER: None,
            CelestialBodyType.SATURN: None,
            CelestialBodyType.URANUS: None,
            CelestialBodyType.NEPTUNE: None
        }

        self.orbits_button = ToggleToolButton("show-orbits")
        self.orbits_button.set_tooltip(_("Show planets orbits"))
        self.orbits_button.set_active(True)
        self.orbits_button.connect("toggled", self._show_orbits_cb)
        self.insert(self.orbits_button, -1)

        self.insert(make_separator(False), -1)

        for planet in self.buttons:
            button = ToggleToolButton(get_icon_name(planet))
            button.set_tooltip(get_body_name(planet))
            button.set_active(True)
            button.connect("toggled", self._show_planet_cb, planet)
            self.insert(button, -1)

            self.buttons[planet] = button

        self.show_all()

    def disable_simulation_widgets(self):
        self.orbits_button.set_sensitive(False)
        for planet in self.buttons:
            self.buttons[planet].set_sensitive(False)

    def enable_simulation_widgets(self):
        self.orbits_button.set_sensitive(True)
        for planet in self.buttons:
            self.buttons[planet].set_sensitive(True)

    def _show_orbits_cb(self, button):
        self.emit("show-orbits", button.get_active())

    def _show_planet_cb(self, button, planet):
        self.emit("show-body", planet, button.get_active())
Ejemplo n.º 6
0
def toggle_factory(icon_name, callback, toolbar, tooltip=None):
    ''' add a toggle button to a toolbar'''
    
    t_button = ToggleToolButton(icon_name)
    t_button.connect('toggled', callback)
    if tooltip:
        t_button.set_tooltip(tooltip)
    if hasattr(toolbar, 'insert'):  # the main toolbar
        toolbar.insert(t_button, -1)
    else:  # or a secondary toolbar
        toolbar.props.page.insert(t_button, -1)
    t_button.show()
Ejemplo n.º 7
0
def toggle_factory(icon_name, callback, toolbar, tooltip=None):
    ''' add a toggle button to a toolbar'''

    t_button = ToggleToolButton(icon_name)
    t_button.connect('toggled', callback)
    if tooltip:
        t_button.set_tooltip(tooltip)
    if hasattr(toolbar, 'insert'):  # the main toolbar
        toolbar.insert(t_button, -1)
    else:  # or a secondary toolbar
        toolbar.props.page.insert(t_button, -1)
    t_button.show()
Ejemplo n.º 8
0
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        logging.debug('Starting the IRC Activity')
        self.set_title(_('IRC Activity'))

        self.add_events(Gdk.EventMask.VISIBILITY_NOTIFY_MASK)
        self.connect('visibility-notify-event',
                     self.__visibility_notify_event_cb)

        self.is_visible = False

        self.client = purk.Client(self)
        if handle.object_id is None:
            self.default_config()
        self.client.show()
        widget = self.client.get_widget()

        # CANVAS
        self.set_canvas(widget)

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

        title_entry = TitleEntry(self)
        toolbar_box.toolbar.insert(title_entry, -1)
        title_entry.show()

        connectionbtn = ToggleToolButton('connect')
        connectionbtn.set_active(True)
        connectionbtn.set_tooltip(_('Disconnect'))
        connectionbtn.connect('toggled', self._connection_cb)
        toolbar_box.toolbar.insert(connectionbtn, -1)
        connectionbtn.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()
Ejemplo n.º 9
0
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        logging.debug('Starting the IRC Activity')
        self.set_title(_('IRC Activity'))

        self.add_events(Gdk.EventMask.VISIBILITY_NOTIFY_MASK)
        self.connect('visibility-notify-event',
                     self.__visibility_notify_event_cb)

        self.is_visible = False

        self.client = purk.Client(self)
        if handle.object_id is None:
            self.default_config()
        self.client.show()
        widget = self.client.get_widget()

        # CANVAS
        self.set_canvas(widget)

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

        title_entry = TitleEntry(self)
        toolbar_box.toolbar.insert(title_entry, -1)
        title_entry.show()

        connectionbtn = ToggleToolButton('connect')
        connectionbtn.set_active(True)
        connectionbtn.set_tooltip(_('Disconnect'))
        connectionbtn.connect('toggled', self._connection_cb)
        toolbar_box.toolbar.insert(connectionbtn, -1)
        connectionbtn.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()
Ejemplo n.º 10
0
class CollabEditActivity(activity.Activity):
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        self.toolbarbox = ToolbarBox()
        self.toolbar = self.toolbarbox.toolbar
        self.set_toolbar_box(self.toolbarbox)

        self.edit = collabedit.CollabEdit(self)
        self.edit.connect("cursor-position-changed", self._cursor_positon_changed_cb)
        self.set_canvas(self.edit)

        self.setup_toolbar()

        self.show_all()

    def _cursor_positon_changed_cb(self, edit, pos):
        self.button_bold.props.active = self.edit.check_tag_at_offset("bold", pos)
        self.button_italic.props.active = self.edit.check_tag_at_offset("italic", pos)
        self.button_underline.props.active = self.edit.check_tag_at_offset("underline", pos)

    def setup_toolbar(self):
        activity_button = ActivityToolbarButton(self)
        self.toolbar.insert(activity_button, -1)

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

        edit_toolbar = EditToolbar()
        self.toolbar.insert(ToolbarButton(page=edit_toolbar, icon_name="toolbar-edit"), -1)

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

        self.button_bold = ToggleToolButton("format-text-bold")
        self.button_bold.set_tooltip(_("Bold"))
        self.button_bold.props.accelerator = "<Ctrl>B"
        self.button_bold.connect("toggled", lambda button: self.edit.toggle_bold())
        edit_toolbar.insert(self.button_bold, -1)

        self.button_italic = ToggleToolButton("format-text-italic")
        self.button_italic.set_tooltip(_("Italic"))
        self.button_italic.props.accelerator = "<Ctrl>I"
        self.button_italic.connect("toggled", lambda button: self.edit.toggle_italic())
        edit_toolbar.insert(self.button_italic, -1)

        self.button_underline = ToggleToolButton("format-text-underline")
        self.button_underline.set_tooltip(_("Underline"))
        self.button_underline.props.accelerator = "<Ctrl>B"
        self.button_underline.connect("toggled", lambda button: self.edit.toggle_underline())
        edit_toolbar.insert(self.button_underline, -1)

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

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

        self.toolbarbox.show_all()
        edit_toolbar.show_all()
Ejemplo n.º 11
0
    def _add_clock_controls(self, display_toolbar):

        # First group of radio button to select the type of clock to display
        button1 = RadioToolButton(icon_name="simple-clock")
        button1.set_tooltip(_('Simple Clock'))
        button1.connect("toggled", self._display_mode_changed_cb,
                        _MODE_SIMPLE_CLOCK)
        display_toolbar.insert(button1, -1)
        button2 = RadioToolButton(icon_name="nice-clock",
                                  group=button1)
        button2.set_tooltip(_('Nice Clock'))
        button2.connect("toggled", self._display_mode_changed_cb,
                        _MODE_NICE_CLOCK)
        display_toolbar.insert(button2, -1)
        button3 = RadioToolButton(icon_name="digital-clock",
                                  group=button1)
        button3.set_tooltip(_('Digital Clock'))
        button3.connect("toggled", self._display_mode_changed_cb,
                        _MODE_DIGITAL_CLOCK)
        display_toolbar.insert(button3, -1)

        # A separator between the two groups of buttons
        separator = Gtk.SeparatorToolItem()
        separator.set_draw(True)
        display_toolbar.insert(separator, -1)

        # Now the options buttons to display other elements: date, day
        # of week...  A button in the toolbar to write the time in
        # full letters
        button = ToggleToolButton("write-time")
        button.set_tooltip(_('Display time in full letters'))
        button.connect("toggled", self._write_time_clicked_cb)
        display_toolbar.insert(button, -1)

        # The button to display the weekday and date
        button = ToggleToolButton("write-date")
        button.set_tooltip(_('Display weekday and date'))
        button.connect("toggled", self._write_date_clicked_cb)
        display_toolbar.insert(button, -1)

        # Another button to speak aloud the time
        button = ToggleToolButton("microphone")
        button.set_tooltip(_('Talking clock'))
        button.connect("toggled", self._speak_time_clicked_cb)
        display_toolbar.insert(button, -1)

        # A separator between the two groups of buttons
        separator = Gtk.SeparatorToolItem()
        separator.set_draw(True)
        display_toolbar.insert(separator, -1)

        # And another button to toggle grabbing the hands
        self._grab_button = ToggleToolButton("grab")
        self._grab_button.set_tooltip(_('Grab the hands'))
        self._grab_button.connect("toggled", self._grab_clicked_cb)
        display_toolbar.insert(self._grab_button, -1)
Ejemplo n.º 12
0
    def _build_toolbox(self):
        toolbar_box = ToolbarBox()

        self.max_participants = 1

        activity_button = ActivityToolbarButton(self)
        activity_toolbar = activity_button.page

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

        self._secondary_toolbar = Gtk.Toolbar()
        self._secondary_toolbar_button = ToolbarButton(
            page=self._secondary_toolbar,
            icon_name='system-search')
        self._secondary_toolbar.show()
        self._toolbar.insert(self._secondary_toolbar_button, -1)
        self._secondary_toolbar_button.hide()

        show_list = ToggleToolButton('view-list')
        show_list.set_active(True)
        show_list.set_tooltip(_('Show list of files'))
        show_list.connect('toggled', self._list_toggled_cb)
        self._toolbar.insert(show_list, -1)
        show_list.show()

        copy = CopyButton()
        copy.connect('clicked', self.__copy_clicked_cb)
        self._toolbar.insert(copy, -1)

        wrap_btn = ToggleToolButton("format-wrap")
        wrap_btn.set_tooltip(_('Word Wrap'))
        wrap_btn.connect('clicked', self._wrap_cb)
        self._toolbar.insert(wrap_btn, -1)

        self.search_entry = iconentry.IconEntry()
        self.search_entry.set_size_request(Gdk.Screen.width() / 3, -1)
        self.search_entry.set_icon_from_name(
            iconentry.ICON_ENTRY_PRIMARY, 'entry-search')
        self.search_entry.add_clear_button()
        self.search_entry.connect('activate', self._search_entry_activate_cb)
        self.search_entry.connect('changed', self._search_entry_changed_cb)
        self._search_item = Gtk.ToolItem()
        self._search_item.add(self.search_entry)
        self._toolbar.insert(self._search_item, -1)

        self._search_prev = ToolButton('go-previous-paired')
        self._search_prev.set_tooltip(_('Previous'))
        self._search_prev.connect('clicked', self._search_prev_cb)
        self._toolbar.insert(self._search_prev, -1)

        self._search_next = ToolButton('go-next-paired')
        self._search_next.set_tooltip(_('Next'))
        self._search_next.connect('clicked', self._search_next_cb)
        self._toolbar.insert(self._search_next, -1)

        self._update_search_buttons()

        self.collector_palette = CollectorPalette(self)
        collector_btn = ToolButton('log-export')
        collector_btn.set_palette(self.collector_palette)
        collector_btn.connect('clicked', self._logviewer_cb)
        collector_btn.show()
        activity_toolbar.insert(collector_btn, -1)

        self._delete_btn = ToolButton('list-remove')
        self._delete_btn = ToolButton('list-remove', accelerator='<ctrl>d')
        self._delete_btn.set_tooltip(_('Delete Log File'))
        self._delete_btn.connect('clicked', self._delete_log_cb)
        self._toolbar.insert(self._delete_btn, -1)

        self._separator = Gtk.SeparatorToolItem()
        self._separator.set_expand(True)
        self._separator.set_draw(False)
        self._toolbar.insert(self._separator, -1)

        self._stop_btn = StopButton(self)
        self._toolbar.insert(self._stop_btn, -1)

        toolbar_box.show_all()
        self.set_toolbar_box(toolbar_box)
Ejemplo n.º 13
0
class CartoonBuilderActivity(SharedActivity):
    def __init__(self, handle):
        self.notebook = Gtk.Notebook()
        SharedActivity.__init__(self, self.notebook, SERVICE, handle)

        self.notebook.show()
        self.notebook.props.show_border = False
        self.notebook.props.show_tabs = False

        self.montage = montage.View()
        self.notebook.append_page(self.montage, Gtk.Label(''))

        toolbox = ToolbarBox()
        toolbox.show()

        toolbox.toolbar.insert(ActivityToolbarButton(self), -1)

        separator = Gtk.SeparatorToolItem()
        separator.set_draw(False)
        toolbox.toolbar.insert(separator, -1)

        self.notebook_toolbar = Gtk.Notebook()
        self.notebook_toolbar.props.show_border = False
        self.notebook_toolbar.props.show_tabs = False
        self.notebook_toolbar.append_page(self._create_montage_toolbar(),
                                          Gtk.Label(''))
        self.notebook_toolbar.show()

        notebook_item = Gtk.ToolItem()
        notebook_item.set_expand(True)
        notebook_item.add(self.notebook_toolbar)
        notebook_item.show()
        toolbox.toolbar.insert(notebook_item, -1)

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

        toolbox.show_all()
        self.toolbar_box = toolbox

    def new_instance(self):
        logger.debug('new_instance')
        self.montage.restore()

    def resume_instance(self, filepath):
        logger.debug('resume_instance from %s' % filepath)
        document.load(filepath)
        char.load()
        ground.load()
        sound.load()
        self.montage.restore()

    def save_instance(self, filepath):
        logger.debug('save_instance to %s' % filepath)
        document.save(filepath)

    def share_instance(self, tube_conn, initiating):
        logger.debug('share_instance')
        self.messenger = Messenger(tube_conn, initiating, self.montage)

    def _create_montage_toolbar(self):
        toolbar = Gtk.Toolbar()

        playButtonImg = Gtk.Image()
        playButtonImg.show()
        playButtonImg.set_from_icon_name('media-playback-start',
                                         Gtk.IconSize.LARGE_TOOLBAR)

        pauseButtonImg = Gtk.Image()
        pauseButtonImg.show()
        pauseButtonImg.set_from_icon_name('media-playback-pause',
                                          Gtk.IconSize.LARGE_TOOLBAR)

        self.playButton = ToggleToolButton('media-playback-start')
        self.playButton.connect('toggled', self.__play_cb, playButtonImg,
                                pauseButtonImg)
        toolbar.insert(self.playButton, -1)
        self.playButton.set_tooltip(_('Play / Pause'))

        tempo = TempoSlider(0, 10)
        tempo.adjustment.connect("value-changed", self.__tempo_cb)
        tempo.set_size_request(250, -1)
        tempo.set_value(5)
        tempo_item = Gtk.ToolItem()
        tempo_item.add(tempo)
        toolbar.insert(tempo_item, -1)

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

        clear_tape = ToolButton('sl-reset')
        clear_tape.connect('clicked', self.__clear_tape_cb)
        clear_tape.set_tooltip(_('Reset'))
        toolbar.insert(clear_tape, -1)

        toolbar.show_all()

        return toolbar

    def __clear_tape_cb(self, widget):
        for i in range(TAPE_COUNT):
            self.montage.props.frame = (i, None)

    def __tempo_cb(self, widget):
        self.montage.set_tempo(widget.get_value())

    def __play_cb(self, widget, playButtonImg, pauseButtonImg):
        if widget.get_active():
            widget.set_icon_widget(pauseButtonImg)
            sound.play()
            self.montage.play()
        else:
            widget.set_icon_widget(playButtonImg)
            sound.stop()
            self.montage.stop()
Ejemplo n.º 14
0
class SpeechToolbar(Gtk.Toolbar):

    def __init__(self, activity):
        Gtk.Toolbar.__init__(self)
        self._activity = activity
        if not speech.supported:
            return

        self._cnf_client = GConf.Client.get_default()
        self.load_speech_parameters()

        self.sorted_voices = [i for i in speech.voices()]
        self.sorted_voices.sort(self.compare_voices)
        default = 0
        for voice in self.sorted_voices:
            if voice[0] == speech.voice[0]:
                break
            default = default + 1

        # Play button
        self.play_btn = ToggleToolButton('media-playback-start')
        self.play_btn.show()
        self.play_btn.connect('toggled', self.play_cb)
        self.insert(self.play_btn, -1)
        self.play_btn.set_tooltip(_('Play / Pause'))

        # Stop button
        self.stop_btn = ToolButton('media-playback-stop')
        self.stop_btn.show()
        self.stop_btn.connect('clicked', self.stop_cb)
        self.stop_btn.set_sensitive(False)
        self.insert(self.stop_btn, -1)
        self.stop_btn.set_tooltip(_('Stop'))

        self.voice_combo = ComboBox()
        for voice in self.sorted_voices:
            self.voice_combo.append_item(voice, voice[0])
        self.voice_combo.set_active(default)

        self.voice_combo.connect('changed', self.voice_changed_cb)
        combotool = ToolComboBox(self.voice_combo)
        self.insert(combotool, -1)
        combotool.show()
        speech.reset_buttons_cb = self.reset_buttons_cb

    def compare_voices(self,  a,  b):
        if a[0].lower() == b[0].lower():
            return 0
        if a[0] .lower() < b[0].lower():
            return -1
        if a[0] .lower() > b[0].lower():
            return 1

    def voice_changed_cb(self, combo):
        speech.voice = combo.props.value
        speech.say(speech.voice[0])
        self.save_speech_parameters()

    def load_speech_parameters(self):
        speech_parameters = {}
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        if os.path.exists(data_file_name):
            f = open(data_file_name, 'r')
            try:
                speech_parameters = simplejson.load(f)
                speech.voice = speech_parameters['voice']
            finally:
                f.close()

        self._cnf_client.add_dir('/desktop/sugar/speech',
                GConf.ClientPreloadType.PRELOAD_NONE)
        speech.pitch = self._cnf_client.get_int('/desktop/sugar/speech/pitch')
        speech.rate = self._cnf_client.get_int('/desktop/sugar/speech/rate')
        self._cnf_client.notify_add('/desktop/sugar/speech/pitch', \
                self.__conf_changed_cb, None)
        self._cnf_client.notify_add('/desktop/sugar/speech/rate', \
                self.__conf_changed_cb, None)

    def __conf_changed_cb(self, client, connection_id, entry, args):
        key = entry.get_key()
        value = client.get_int(key)
        if key == '/desktop/sugar/speech/pitch':
            speech.pitch = value
        if key == '/desktop/sugar/speech/rate':
            speech.rate = value

    def save_speech_parameters(self):
        speech_parameters = {}
        speech_parameters['voice'] = speech.voice
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        f = open(data_file_name, 'w')
        try:
            simplejson.dump(speech_parameters, f)
        finally:
            f.close()

    def reset_buttons_cb(self):
        logging.error('reset buttons')
        self.play_btn.set_named_icon('media-playback-start')
        self.stop_btn.set_sensitive(False)

    def play_cb(self, widget):
        self.stop_btn.set_sensitive(True)
        if widget.get_active():
            self.play_btn.set_named_icon('media-playback-pause')
            if speech.is_stopped():
                speech.play(self._activity._view.get_marked_words())
        else:
            self.play_btn.set_named_icon('media-playback-start')
            speech.pause()

    def stop_cb(self, widget):
        self.stop_btn.set_sensitive(False)
        self.play_btn.set_named_icon('media-playback-start')
        self.play_btn.set_active(False)
        speech.stop()
Ejemplo n.º 15
0
class MazeActivity(activity.Activity):

    def __init__(self, handle):
        """Set up the Maze activity."""
        activity.Activity.__init__(self, handle)
        self._busy_count = 0
        self._unbusy_idle_sid = None

        self.build_toolbar()

        self.pservice = PresenceService()
        self.owner = self.pservice.get_owner()

        state = None
        if 'state' in self.metadata:
            state = json.loads(self.metadata['state'])
        self.game = game.MazeGame(self, self.owner, state)
        self.set_canvas(self.game)
        self.game.show()
        self.connect("key_press_event", self.game.key_press_cb)

        self.text_channel = None
        self.my_key = profile.get_pubkey()
        self._alert = None

        if self.shared_activity:
            # we are joining the activity
            self._add_alert(_('Joining a maze'), _('Connecting...'))
            self.connect('joined', self._joined_cb)
            if self.get_shared():
                # we have already joined
                self._joined_cb()
        else:
            # we are creating the activity
            self.connect('shared', self._shared_cb)

    def busy(self):
        if self._busy_count == 0:
            if self._unbusy_idle_sid is not None:
                GLib.source_remove(self._unbusy_idle_sid)
                self._unbusy_idle_sid = None
            self._old_cursor = self.get_window().get_cursor()
            self._set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
        self._busy_count += 1

    def unbusy(self):
        self._unbusy_idle_sid = GLib.idle_add(self._unbusy_idle_cb)

    def _unbusy_idle_cb(self):
        self._unbusy_idle_sid = None
        self._busy_count -= 1
        if self._busy_count == 0:
            self._set_cursor(self._old_cursor)

    def _set_cursor(self, cursor):
        self.get_window().set_cursor(cursor)
        Gdk.flush()

    def build_toolbar(self):
        """Build our Activity toolbar for the Sugar system."""

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

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

        easier_button = ToolButton('create-easier')
        easier_button.set_tooltip(_('Easier level'))
        easier_button.connect('clicked', self._easier_button_cb)
        toolbar_box.toolbar.insert(easier_button, -1)

        harder_button = ToolButton('create-harder')
        harder_button.set_tooltip(_('Harder level'))
        harder_button.connect('clicked', self._harder_button_cb)
        toolbar_box.toolbar.insert(harder_button, -1)

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

        self.show_trail_button = ToggleToolButton('show-trail')
        self.show_trail_button.set_tooltip(_('Show trail'))
        self.show_trail_button.set_active(True)
        self.show_trail_button.connect('toggled', self._toggled_show_trail_cb)
        toolbar_box.toolbar.insert(self.show_trail_button, -1)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_size_request(0, -1)
        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_all()

        return toolbar_box

    def _easier_button_cb(self, button):
        self.game.easier()

    def _harder_button_cb(self, button):
        self.game.harder()

    def _toggled_show_trail_cb(self, button):
        if self.game.set_show_trail(button.get_active()):
            self.broadcast_msg('show_trail:%s' % str(button.get_active()))

    def _shared_cb(self, activity):
        logging.debug('Maze was shared')
        self._add_alert(_('Sharing'), _('This maze is shared.'))
        self._setup()

    def _joined_cb(self, activity):
        """Joined a shared activity."""
        if not self.shared_activity:
            return
        logging.debug('Joined a shared chat')
        for buddy in self.shared_activity.get_joined_buddies():
            self._buddy_already_exists(buddy)
        self._setup()
        # request maze data
        self.broadcast_msg('req_maze')

    def _setup(self):
        self.text_channel = TextChannelWrapper(
            self.shared_activity.telepathy_text_chan,
            self.shared_activity.telepathy_conn, self.pservice)
        self.text_channel.set_received_callback(self._received_cb)
        self.shared_activity.connect('buddy-joined', self._buddy_joined_cb)
        self.shared_activity.connect('buddy-left', self._buddy_left_cb)

    def _received_cb(self, buddy, text):
        if buddy == self.owner:
            return
        self.game.msg_received(buddy, text)

    def _add_alert(self, title, text=None):
        self.grab_focus()
        self._alert = ErrorAlert()
        self._alert.props.title = title
        self._alert.props.msg = text
        self.add_alert(self._alert)
        self._alert.connect('response', self._alert_cancel_cb)
        self._alert.show()

    def _alert_cancel_cb(self, alert, response_id):
        self.remove_alert(alert)
        self._alert = None

    def update_alert(self, title, text=None):
        if self._alert is not None:
            self._alert.props.title = title
            self._alert.props.msg = text

    def show_accelerator_alert(self):
        self.grab_focus()
        self._alert = NotifyAlert()
        self._alert.props.title = _('Tablet mode detected.')
        self._alert.props.msg = _('Hold your XO flat and tilt to play!')
        self.add_alert(self._alert)
        self._alert.connect('response', self._alert_cancel_cb)
        self._alert.show()

    def _buddy_joined_cb(self, activity, buddy):
        """Show a buddy who joined"""
        logging.debug('buddy joined')
        if buddy == self.owner:
            logging.debug('its me, exit!')
            return
        self.game.buddy_joined(buddy)

    def _buddy_left_cb(self, activity, buddy):
        self.game.buddy_left(buddy)

    def _buddy_already_exists(self, buddy):
        """Show a buddy already in the chat."""
        if buddy == self.owner:
            return
        self.game.buddy_joined(buddy)

    def broadcast_msg(self, message):
        if self.text_channel:
            # FIXME: can't identify the sender at the other end,
            # add the pubkey to the text message
            self.text_channel.send('%s|%s' % (self.my_key, message))

    def write_file(self, file_path):
        logging.debug('Saving the state of the game...')
        data = {'seed': self.game.maze.seed,
                'width': self.game.maze.width,
                'height': self.game.maze.height,
                'finish_time': self.game.finish_time}
        logging.debug('Saving data: %s', data)
        self.metadata['state'] = json.dumps(data)

    def can_close(self):
        self.game.close_finish_window()
        return True

    def read_file(self, file_path):
        pass
Ejemplo n.º 16
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
Ejemplo n.º 17
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()

    '''
Ejemplo n.º 18
0
class CollabEditActivity(activity.Activity):

    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        self.toolbarbox = ToolbarBox()
        self.toolbar = self.toolbarbox.toolbar
        self.set_toolbar_box(self.toolbarbox)

        self.edit = collabedit.CollabEdit(self)
        self.edit.connect(
            "cursor-position-changed",
            self._cursor_positon_changed_cb)
        self.set_canvas(self.edit)

        self.setup_toolbar()

        self.show_all()

    def _cursor_positon_changed_cb(self, edit, pos):
        self.button_bold.props.active = self.edit.check_tag_at_offset(
            "bold", pos)
        self.button_italic.props.active = self.edit.check_tag_at_offset(
            "italic", pos)
        self.button_underline.props.active = self.edit.check_tag_at_offset(
            "underline", pos)

    def setup_toolbar(self):
        activity_button = ActivityToolbarButton(self)
        self.toolbar.insert(activity_button, -1)

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

        edit_toolbar = EditToolbar()
        self.toolbar.insert(
            ToolbarButton(
                page=edit_toolbar, icon_name="toolbar-edit"), -1)

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

        self.button_bold = ToggleToolButton("format-text-bold")
        self.button_bold.set_tooltip(_("Bold"))
        self.button_bold.props.accelerator = "<Ctrl>B"
        self.button_bold.connect(
            "toggled", lambda button: self.edit.toggle_bold())
        edit_toolbar.insert(self.button_bold, -1)

        self.button_italic = ToggleToolButton("format-text-italic")
        self.button_italic.set_tooltip(_("Italic"))
        self.button_italic.props.accelerator = "<Ctrl>I"
        self.button_italic.connect(
            "toggled", lambda button: self.edit.toggle_italic())
        edit_toolbar.insert(self.button_italic, -1)

        self.button_underline = ToggleToolButton("format-text-underline")
        self.button_underline.set_tooltip(_("Underline"))
        self.button_underline.props.accelerator = "<Ctrl>U"
        self.button_underline.connect(
            "toggled", lambda button: self.edit.toggle_underline())
        edit_toolbar.insert(self.button_underline, -1)

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

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

        self.toolbarbox.show_all()
        edit_toolbar.show_all()
Ejemplo n.º 19
0
class TextToolbar(Gtk.Toolbar):

    def __init__(self, page):
        self._colorseldlg = None

        Gtk.Toolbar.__init__(self)

        self._page = page
        page._text_toolbar = self

        self._bold = ToggleToolButton('format-text-bold')
        self._bold.set_tooltip(_('Bold'))
        self._bold_id = self._bold.connect('clicked', self._bold_cb)
        self.insert(self._bold, -1)

        self._italic = ToggleToolButton('format-text-italic')
        self._italic.set_tooltip(_('Italic'))
        self._italic_id = self._italic.connect('clicked', self._italic_cb)
        self.insert(self._italic, -1)

        """
        self._underline = ToggleToolButton('format-text-underline')
        self._underline.set_tooltip(_('Underline'))
        self._underline_id = self._underline.connect('clicked',
                self._underline_cb)
        self.insert(self._underline, -1)
        self._underline.show()
        """

        self._text_color = TextButtonColor(page)
        self._text_color.set_title(_('Text Color'))
        item = Gtk.ToolItem()
        item.add(self._text_color)
        self.insert(item, -1)

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

        self._font_size_combo = FontSize()
        self._font_size_changed_id = self._font_size_combo.connect(
            'changed', self._font_size_changed_cb)
        self.insert(self._font_size_combo, -1)

        # font
        self._font_combo = FontComboBox()
        self._font_combo.set_font_name(globos.DEFAULT_FONT)
        self._fonts_changed_id = self._font_combo.connect(
            'changed', self._font_changed_cb)
        self.insert(ToolComboBox(self._font_combo), -1)

        self.show_all()

    def get_text_selected_handler(self):
        return self._text_selected_handler

    def _add_widget(self, widget, expand=False):
        tool_item = Gtk.ToolItem()
        tool_item.set_expand(expand)
        tool_item.add(widget)
        widget.show()
        self.insert(tool_item, -1)
        tool_item.show()

    def _bold_cb(self, button):
        globo_activo = self._page.get_globo_activo()
        if globo_activo is not None and globo_activo.texto is not None:
            globo_activo.texto.bold = not globo_activo.texto.bold
            self._page.get_active_box().redraw()

    def _italic_cb(self, button):
        globo_activo = self._page.get_globo_activo()
        if globo_activo is not None and globo_activo.texto is not None:
            globo_activo.texto.italic = not globo_activo.texto.italic
            self._page.get_active_box().redraw()

    # para la version 0.82
    def _text_color_cb(self, button):
        globo_activo = self._page.get_globo_activo()
        if globo_activo is not None and globo_activo.texto is not None:
            color = self._text_color.get_color()
            texto = globo_activo.texto
            texto.color = (color.red, color.green, color.blue)
            self._page.get_active_box().redraw()

    def _font_size_changed_cb(self, widget):
        size = widget.get_font_size()
        logger.debug('Setting font size: %d', size)
        globo_activo = self._page.get_globo_activo()
        if globo_activo is not None and globo_activo.texto is not None:
            globo_activo.texto.font_size = size
            self._page.get_active_box().redraw()

    def _font_changed_cb(self, widget):
        font_name = widget.get_font_name()
        logger.debug('Setting font name: %s', font_name)
        globo_activo = self._page.get_globo_activo()
        if globo_activo is not None and globo_activo.texto is not None:
            globo_activo.texto.font_type = font_name
            self._page.selected_font_name = font_name
            self._page.get_active_box().redraw()

    """
    Estos son los metodos para setear los contrles de la barra en base a el
    texto del globo como el globo va a tener un solo font seleccionado, voy
    a hacer un solo metodo
    """
    def setToggleButtonState(self, button, b, id):
        button.handler_block(id)
        button.set_active(b)
        button.handler_unblock(id)

    def setToolbarState(self, globeText):
        # seteo bold
        self.setToggleButtonState(self._bold, globeText.bold, self._bold_id)
        # seteo italic
        self.setToggleButtonState(self._italic, globeText.italic,
                                  self._italic_id)
        # color
        self._text_color.set_color(Gdk.Color(*globeText.color))
        # font size
        logging.error('Setting font size from globe %s %s',
                      globeText.font_size, globeText.font_size.__class__)
        self._font_size_combo.handler_block(self._font_size_changed_id)
        self._font_size_combo.set_font_size(int(globeText.font_size))
        self._font_size_combo.handler_unblock(self._font_size_changed_id)

        # font seleccionada
        self._font_combo.handler_block(self._fonts_changed_id)
        self._font_combo.set_font_name(globeText.font_type)
        self._page.selected_font_name = globeText.font_type
        self._font_combo.handler_unblock(self._fonts_changed_id)
Ejemplo n.º 20
0
class TextToolbar(Gtk.Toolbar):

    _ACTION_TEXT_NAME = 'text'

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

        self._activity = activity
        self.properties = self._activity.area.tool

        self._text = DrawToolButton('text', activity.tool_group, _('Type'))
        self.insert(self._text, -1)
        self._text.connect('clicked', self.set_tool, self._ACTION_TEXT_NAME)

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

        self._bold = ToggleToolButton('format-text-bold')
        self.insert(self._bold, -1)
        self._bold.show()
        self._bold.connect('clicked', self.__bold_bt_cb)

        self._italic = ToggleToolButton('format-text-italic')
        self.insert(self._italic, -1)
        self._italic.show()
        self._italic.connect('clicked', self.__italic_bt_cb)

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

        self._font_size = FontSize()
        self.insert(self._font_size, -1)
        self._font_size_changed_id = self._font_size.connect(
            'changed', self.__font_size_changed_cb)

        self._font_combo = FontComboBox()
        self._fonts_changed_id = self._font_combo.connect(
            'changed', self.__font_changed_cb)

        fd = activity.area.get_font_description()
        font_name = fd.get_family()
        self._font_combo.set_font_name(font_name)
        self._font_size.set_font_size(int(fd.get_size() / Pango.SCALE))
        tool_item = ToolComboBox(self._font_combo)
        self.insert(tool_item, -1)
        self.show_all()

    def __bold_bt_cb(self, button):
        fd = self._activity.area.get_font_description()
        if button.get_active():
            fd.set_weight(Pango.Weight.BOLD)
        else:
            fd.set_weight(Pango.Weight.NORMAL)
        self._activity.area.set_font_description(fd)

    def __italic_bt_cb(self, button):
        fd = self._activity.area.get_font_description()
        if button.get_active():
            fd.set_style(Pango.Style.ITALIC)
        else:
            fd.set_style(Pango.Style.NORMAL)
        self._activity.area.set_font_description(fd)

    def __font_size_changed_cb(self, widget):
        fd = self._activity.area.get_font_description()
        value = widget.get_font_size()
        fd.set_size(int(value) * Pango.SCALE)
        self._activity.area.set_font_description(fd)

    def __font_changed_cb(self, combo):
        fd = self._activity.area.get_font_description()
        font_name = combo.get_font_name()
        fd.set_family(font_name)
        self._activity.area.set_font_description(fd)

    def get_active_text(self, combobox):
        model = combobox.get_model()
        active = combobox.get_active()
        if active < 0:
            return None
        return model[active][0]

    def set_tool(self, widget, tool_name):
        self.properties['name'] = tool_name
        self._activity.area.set_tool(self.properties)
Ejemplo n.º 21
0
class ToolbarBuilder():
    def __init__(self, edit, toolbar):
        self.edit = edit
        logging.debug('init edit toolbar')
        logging.debug(self.edit)

        self.txt_toggle = ToggleToolButton('ascii')
        self.img_toggle = ToggleToolButton('image')
        self.jimg_toggle = ToggleToolButton('journal-image')
        self.jimg_chooser_toggle = ToolButton('load-image-from-journal')
        self.jtext_chooser_toggle = ToolButton('load-text-from-journal')

        self.txt_toggle.set_tooltip(_('Text'))
        self.txt_toggle.connect(
            'toggled', self._toggle_cb,
            [self.txt_toggle, self.img_toggle, self.jimg_toggle])
        toolbar.insert(self.txt_toggle, -1)

        self.img_toggle.set_tooltip(_('Images'))
        self.img_toggle.connect(
            'toggled', self._toggle_cb,
            [self.txt_toggle, self.img_toggle, self.jimg_toggle])
        toolbar.insert(self.img_toggle, -1)

        self.jimg_toggle.set_tooltip(_('Journal Images'))
        self.jimg_toggle.connect(
            'toggled', self._toggle_cb,
            [self.txt_toggle, self.img_toggle, self.jimg_toggle])
        toolbar.insert(self.jimg_toggle, -1)

        self.jimg_chooser_toggle.set_tooltip(_('Choose Journal Images'))
        self.jimg_chooser_toggle.connect('clicked', self._toggle_image_chooser)
        toolbar.insert(self.jimg_chooser_toggle, -1)

        self.jtext_chooser_toggle.set_tooltip(_('Choose Journal Text'))
        self.jtext_chooser_toggle.connect('clicked', self._toggle_text_chooser)
        toolbar.insert(self.jtext_chooser_toggle, -1)

        for tab in TABS:
            for i in tab.toolitems:
                toolbar.insert(i, -1)

        self.txt_toggle.set_active(True)

    def sensitize_all(self):
        self.txt_toggle.set_sensitive(True)
        self.img_toggle.set_sensitive(True)
        self.jimg_toggle.set_sensitive(True)

    def unsensitize_all(self):
        self.txt_toggle.set_sensitive(False)
        self.img_toggle.set_sensitive(False)
        self.jimg_toggle.set_sensitive(False)

    def _toggle_image_chooser(self, widget):
        # self._old_cursor = self.edit.get_window().get_cursor()
        # self.edit.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
        GObject.idle_add(self.__image_chooser)

    def __image_chooser(self):
        chooser = ObjectChooser(what_filter=mime.GENERIC_TYPE_IMAGE)
        result = chooser.run()
        if result == Gtk.ResponseType.ACCEPT:
            jobject = chooser.get_selected_object()
            if jobject and jobject.file_path:
                title = str(jobject.metadata['title'])
                path = str(jobject.file_path)
                TABS[2].gallery.add_image(path, title)
        # self.edit.get_window().set_cursor(self._old_cursor)

    def _toggle_text_chooser(self, widget):
        # self._old_cursor = self.edit.get_window().get_cursor()
        # self.edit.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
        GObject.idle_add(self.__text_chooser)

    def __text_chooser(self):
        chooser = ObjectChooser(what_filter=mime.GENERIC_TYPE_TEXT)
        result = chooser.run()
        if result == Gtk.ResponseType.ACCEPT:
            jobject = chooser.get_selected_object()
            if jobject and jobject.file_path:
                title = str(jobject.metadata['title'])
                path = str(jobject.file_path)
                fp = open(path, 'r')
                text = fp.read()
                fp.close()
                article_data = dehtml(text, title)
                TABS[0].set_source_article(Article(article_data))
        # self.edit.get_window().set_cursor(self._old_cursor)

    def _toggle_cb(self, widget, toggles):
        for tab in TABS:
            for i in tab.toolitems:
                i.hide()

        if not widget.get_active():
            index = 3
        else:
            for t in range(0, len(toggles)):
                if toggles[t] != widget:
                    toggles[t].set_active(False)
                else:
                    index = t

        for i in TABS[index].toolitems:
            i.show()

        # We don't require any article data to display jounal images
        if book.wiki.article and index != 2:
            TABS[index].set_source_article(book.wiki.article)
        if book.custom.article:
            TABS[index].set_working_article(book.custom.article)

        self.edit.set_current_page(index)
Ejemplo n.º 22
0
class DrawEditToolbar(EditToolbar):

    def __init__(self, activity):
        EditToolbar.__init__(self)

        self._activity = activity

        self.undo.set_tooltip(_('Undo'))
        self.redo.set_tooltip(_('Redo'))
        self.copy.set_tooltip(_('Copy'))
        self.paste.set_tooltip(_('Paste'))

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

        self._clear_all = ToolButton('edit-clear')
        self.insert(self._clear_all, -1)
        self._clear_all.set_tooltip(_('Clear'))
        self._clear_all.show()

        self._sound = ToggleToolButton('speaker-100')
        self._sound.set_tooltip(_('Enable sound'))

        if self._activity.area._player is not None:
            self.insert(self._sound, -1)

        self._sound.show()
        self._sound.connect('clicked', self.__sound_cb)

        self.undo.connect('clicked', self._undo_cb)
        self.redo.connect('clicked', self._redo_cb)

        self.copy.connect('clicked', self._copy_cb)
        self.paste.connect('clicked', self._paste_cb)
        self._clear_all.connect('clicked', self._clear_all_cb)

        self._activity.area.connect('undo', self._on_signal_undo_cb)
        self._activity.area.connect('redo', self._on_signal_redo_cb)
        self._activity.area.connect('select', self._on_signal_select_cb)
        self._activity.area.connect('action-saved',
                                    self._on_signal_action_saved_cb)

    def _undo_cb(self, widget, data=None):
        self._activity.area.undo()

    def _redo_cb(self, widget, data=None):
        self._activity.area.redo()

    def _copy_cb(self, widget, data=None):
        self._activity.area.copy()

    def _paste_cb(self, widget, data=None):
        self._activity.area.paste(self._activity.area)

    def _on_signal_undo_cb(self, widget, data=None):
        self._verify_sensitive_buttons()

    def _on_signal_redo_cb(self, widget, data=None):
        self._verify_sensitive_buttons()

    def _on_signal_select_cb(self, widget, data=None):
        self._verify_sensitive_buttons()

    def _on_signal_action_saved_cb(self, widget, data=None):
        self._verify_sensitive_buttons()

    # define when a button is active
    def _verify_sensitive_buttons(self):
        self.undo.set_sensitive(self._activity.area.can_undo())
        self.redo.set_sensitive(self._activity.area.can_redo())
        self.copy.set_sensitive(self._activity.area.is_selected())
        # TODO: it is not possible to verify this yet.
        # self.paste.set_sensitive(self._activity.area.can_paste())

    def _clear_all_cb(self, widget, data=None):
        self._activity.area.clear()

    def __sound_cb(self, widget):
        self._activity.area.enable_sounds(widget.get_active())
        if widget.get_active():
            self._sound.set_tooltip(_('Disable sound'))
        else:
            self._sound.set_tooltip(_('Enable sound'))
Ejemplo n.º 23
0
class MainToolbox(ToolbarBox):

    query_changed_signal = GObject.Signal('query-changed',
                                          arg_types=([object]))

    def __init__(self, default_what_filter=None, default_filter_type=None):
        ToolbarBox.__init__(self)
        self._mount_point = None
        self._filter_type = default_filter_type
        self._what_filter = default_what_filter
        self._when_filter = None

        self._default_what_filter = default_what_filter
        self._default_filter_type = default_filter_type

        self.search_entry = iconentry.IconEntry()
        self.search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                             'entry-search')
        text = _('Search in %s') % _('Journal')
        self.search_entry.set_placeholder_text(text)
        self.search_entry.connect('activate', self._search_entry_activated_cb)
        self.search_entry.connect('changed', self._search_entry_changed_cb)
        self.search_entry.add_clear_button()
        self._autosearch_timer = None
        self._add_widget(self.search_entry, expand=True)

        self._favorite_button = ToggleToolButton('emblem-favorite')
        self._favorite_button.set_tooltip(_('Favorite entries'))
        self._favorite_button.connect('toggled',
                                      self.__favorite_button_toggled_cb)
        self.toolbar.insert(self._favorite_button, -1)
        self._favorite_button.show()

        self._proj_list_button = ToggleToolButton('project-box')
        self._proj_list_button.set_tooltip(_('Projects'))
        self._proj_list_button.connect('toggled',
                                       self._proj_list_button_clicked_cb)
        self.toolbar.insert(self._proj_list_button, -1)
        self._proj_list_button.show()

        if not self._proj_list_button.props.active:
            self._what_widget_contents = None
            self._what_widget = Gtk.ToolItem()
            self._what_search_button = FilterToolItem('view-type',
                                                      _('Anything'),
                                                      self._what_widget)
            self._what_widget.show()
            self.toolbar.insert(self._what_search_button, -1)
            self._what_search_button.show()

        self._when_search_button = FilterToolItem(
            'view-created', _('Anytime'), self._get_when_search_items())
        self.toolbar.insert(self._when_search_button, -1)
        self._when_search_button.show()

        self._sorting_button = SortingButton()
        self.toolbar.insert(self._sorting_button, -1)
        self._sorting_button.connect('sort-property-changed',
                                     self.__sort_changed_cb)
        self._sorting_button.show()
        '''
        # TODO: enable it when the DS supports saving the buddies.
        self._with_widget = Gtk.ToolItem()
        self._with_search_button = FilterToolItem(
            'view-who', _('Anyone'), self._with_widget)
        self._with_widget.show()
        self.toolbar.insert(self._with_search_button, -1)
        self._with_search_button.show()
        self._get_with_search_items()
        '''

        self._query = self._build_query()

        self.refresh_filters()

        self.connect('size-allocate', self.__size_allocate_cb)

    def __size_allocate_cb(self, widget, allocation):
        GLib.idle_add(self._update_buttons, allocation.width)

    def _update_buttons(self, toolbar_width):
        # Show the label next to the button icon if there is room on
        # the toolbar.
        important = toolbar_width > 13 * style.GRID_CELL_SIZE

        if not important:
            self.search_entry.set_size_request(
                toolbar_width - style.GRID_CELL_SIZE * 7, 0)

        self._what_search_button.set_is_important(important)
        self._when_search_button.set_is_important(important)
        # self._with_search_button.set_is_important(important)

        return False

    def _get_when_search_items(self):
        when_list = []
        when_list.append({
            'label': _('Anytime'),
            'callback': self._when_palette_cb,
            'id': _ACTION_ANYTIME
        })
        when_list.append({'separator': True})
        when_list.append({
            'label': _('Today'),
            'callback': self._when_palette_cb,
            'id': _ACTION_TODAY
        })
        when_list.append({
            'label': _('Since yesterday'),
            'callback': self._when_palette_cb,
            'id': _ACTION_SINCE_YESTERDAY
        })
        when_list.append({
            'label': _('Past week'),
            'callback': self._when_palette_cb,
            'id': _ACTION_PAST_WEEK
        })
        when_list.append({
            'label': _('Past month'),
            'callback': self._when_palette_cb,
            'id': _ACTION_PAST_MONTH
        })
        when_list.append({
            'label': _('Past year'),
            'callback': self._when_palette_cb,
            'id': _ACTION_PAST_YEAR
        })

        return set_palette_list(when_list)

    '''
    def _get_with_search_items(self):
        with_list = []
        with_list.append({'label':_('Anyone'),
                          'callback': self._with_palette_cb,
                          'id': _ACTION_EVERYBODY})
        with_list.append({'separator': True})
        with_list.append({'label':_('My friends'),
                          'callback': self._with_palette_cb,
                          'id': _ACTION_MY_FRIENDS})
        with_list.append({'label':_('My class'),
                          'callback': self._with_palette_cb,
                          'id': _ACTION_MY_CLASS})
        with_list.append({'separator': True})
        # TODO: Ask the model for buddies.
        for i, buddy in enumerate(model.get_buddies()):
            nick, color = buddy
            with_list.append({'label': nick,
                              'callback': self._with_palette_cb,
                              'icon': 'computer-xo',
                              'xocolors': XOColor(color),
                              'id': i + _ACTION_MY_CLASS + 1})

        widget = set_palette_list(with_list)
        self._with_widget.add(widget)
        widget.show()
    '''

    def _add_widget(self, widget, expand=False):
        tool_item = Gtk.ToolItem()
        tool_item.set_expand(expand)

        tool_item.add(widget)
        widget.show()

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

    def _build_query(self):
        query = {}

        if self._mount_point:
            query['mountpoints'] = [self._mount_point]

        if self._favorite_button.props.active:
            query['keep'] = 1

        if self._proj_list_button.props.active:
            query['activity'] = 'org.sugarlabs.Project'

        elif self._what_filter:
            filter_type = self._filter_type
            value = self._what_filter

            if filter_type == FILTER_TYPE_GENERIC_MIME:
                generic_type = mime.get_generic_type(value)
                if generic_type:
                    mime_types = generic_type.mime_types
                    query['mime_type'] = mime_types
                else:
                    logging.error('filter_type="generic_mime", '
                                  'but "%s" is not a generic mime' % value)

            elif filter_type == FILTER_TYPE_ACTIVITY:
                query['activity'] = value

            elif self._filter_type == FILTER_TYPE_MIME_BY_ACTIVITY:
                registry = bundleregistry.get_registry()
                bundle = \
                    registry.get_bundle(value)
                if bundle is not None:
                    query['mime_type'] = bundle.get_mime_types()
                else:
                    logging.error('Trying to filter using activity mimetype '
                                  'but bundle id is wrong %s' % value)

        if self._when_filter:
            date_from, date_to = self._get_date_range()
            query['timestamp'] = {'start': date_from, 'end': date_to}

        if self.search_entry.props.text:
            text = self.search_entry.props.text.strip()
            if text:
                query['query'] = text

        property_, order = self._sorting_button.get_current_sort()

        if order == Gtk.SortType.ASCENDING:
            sign = '+'
        else:
            sign = '-'
        query['order_by'] = [sign + property_]

        return query

    def _get_date_range(self):
        today_start = datetime.today().replace(hour=0, minute=0, second=0)
        right_now = datetime.today()

        if self._when_filter == _ACTION_TODAY:
            date_range = (today_start, right_now)
        elif self._when_filter == _ACTION_SINCE_YESTERDAY:
            date_range = (today_start - timedelta(1), right_now)
        elif self._when_filter == _ACTION_PAST_WEEK:
            date_range = (today_start - timedelta(7), right_now)
        elif self._when_filter == _ACTION_PAST_MONTH:
            date_range = (today_start - timedelta(30), right_now)
        elif self._when_filter == _ACTION_PAST_YEAR:
            date_range = (today_start - timedelta(356), right_now)

        return (time.mktime(date_range[0].timetuple()),
                time.mktime(date_range[1].timetuple()))

    def __sort_changed_cb(self, button):
        self._update_if_needed()

    def _update_if_needed(self):
        new_query = self._build_query()
        if self._query != new_query:
            self._query = new_query
            self.query_changed_signal.emit(self._query)

    def _search_entry_activated_cb(self, search_entry):
        if self._autosearch_timer:
            GLib.source_remove(self._autosearch_timer)
        self._update_if_needed()

    def _search_entry_changed_cb(self, search_entry):
        if not search_entry.props.text:
            search_entry.activate()
            return

        if self._autosearch_timer:
            GLib.source_remove(self._autosearch_timer)
        self._autosearch_timer = GLib.timeout_add(_AUTOSEARCH_TIMEOUT,
                                                  self._autosearch_timer_cb)

    def _autosearch_timer_cb(self):
        logging.debug('_autosearch_timer_cb')
        self._autosearch_timer = None
        self.search_entry.activate()
        return False

    def set_mount_point(self, mount_point):
        self._mount_point = mount_point
        self._update_if_needed()

    def set_what_filter(self, what_filter):
        for item in self._what_list:
            if 'id' in item and item['id'] == what_filter:
                self._what_search_button.set_widget_label(item['label'])

                if item['id'] == 0:
                    self._what_search_button.set_widget_icon(
                        icon_name='view-type')
                elif 'icon' in item:
                    self._what_search_button.set_widget_icon(
                        icon_name=item['icon'])
                    self._filter_type = FILTER_TYPE_GENERIC_MIME
                elif 'file' in item:
                    self._what_search_button.set_widget_icon(
                        file_name=item['file'])
                    if self._default_filter_type is not None:
                        self._filter_type = self._default_filter_type
                    else:
                        self._filter_type = FILTER_TYPE_ACTIVITY
                self._what_filter = what_filter
                break

    def update_filters(self, mount_point, what_filter, filter_type=None):
        self._mount_point = mount_point
        self._filter_type = filter_type
        self._what_filter = what_filter
        self.set_what_filter(what_filter)
        self._update_if_needed()

    def set_filter_type(self, filter_type):
        self._filter_type = filter_type
        self._update_if_needed()

    def _what_palette_cb(self, widget, event, item):
        self._what_search_button.set_widget_label(item['label'])

        if item['id'] == 0:
            self._what_search_button.set_widget_icon(icon_name='view-type')
        elif 'icon' in item:
            self._what_search_button.set_widget_icon(icon_name=item['icon'])
            self._filter_type = FILTER_TYPE_GENERIC_MIME
        elif 'file' in item:
            self._what_search_button.set_widget_icon(file_name=item['file'])
            if self._default_filter_type is not None:
                self._filter_type = self._default_filter_type
            else:
                self._filter_type = FILTER_TYPE_ACTIVITY

        self._what_filter = item['id']

        new_query = self._build_query()
        if self._query != new_query:
            self._query = new_query
            self.query_changed_signal.emit(self._query)

    def _when_palette_cb(self, widget, event, item):
        self._when_search_button.set_widget_label(item['label'])

        self._when_filter = item['id']

        new_query = self._build_query()
        if self._query != new_query:
            self._query = new_query
            self.query_changed_signal.emit(self._query)

    def refresh_filters(self):
        # refresh_what_filters
        self._what_list = []
        what_list_activities = []

        try:
            # TRANS: Item on a palette that filters by entry type.
            self._what_list.append({
                'label': _('Anything'),
                'icon': 'application-octet-stream',
                'callback': self._what_palette_cb,
                'id': _ACTION_ANYTHING
            })

            registry = bundleregistry.get_registry()
            appended_separator = False

            types = mime.get_all_generic_types()
            for generic_type in types:
                if not appended_separator:
                    self._what_list.append({'separator': True})
                    appended_separator = True
                self._what_list.append({
                    'label': generic_type.name,
                    'icon': generic_type.icon,
                    'callback': self._what_palette_cb,
                    'id': generic_type.type_id
                })

            self._what_list.append({'separator': True})

            for bundle_id in model.get_unique_values('activity'):
                activity_info = registry.get_bundle(bundle_id)
                if activity_info is None:
                    continue

                # try activity-provided icon
                if os.path.exists(activity_info.get_icon()):
                    try:
                        what_list_activities.append({
                            'label':
                            activity_info.get_name(),
                            'file':
                            activity_info.get_icon(),
                            'callback':
                            self._what_palette_cb,
                            'id':
                            bundle_id
                        })
                    except GLib.GError as exception:
                        # fall back to generic icon
                        logging.warning(
                            'Falling back to default icon for'
                            ' "what" filter because %r (%r) has an'
                            ' invalid icon: %s', activity_info.get_name(),
                            str(bundle_id), exception)
                        what_list_activities.append({
                            'label':
                            activity_info.get_name(),
                            'icon':
                            'application-octet-stream',
                            'callback':
                            self._what_palette_cb,
                            'id':
                            bundle_id
                        })
        finally:
            for item in sorted(what_list_activities, key=lambda x: x['label']):
                self._what_list.append(item)

            if self._what_widget_contents is not None:
                self._what_widget.remove(self._what_widget_contents)
            self._what_widget_contents = set_palette_list(self._what_list)
            self._what_widget.add(self._what_widget_contents)
            self._what_widget_contents.show()

    def _proj_list_button_clicked_cb(self, proj_list_button):
        if self._proj_list_button.props.active:
            self._what_widget.hide()
            self._what_search_button.hide()
        else:
            self._what_widget.show()
            self._what_search_button.show()
        self._update_if_needed()

    def __favorite_button_toggled_cb(self, favorite_button):
        self._update_if_needed()

    def is_filter_changed(self):
        return not (self._filter_type == self._default_filter_type
                    and self._what_filter == self._default_what_filter
                    and self._when_filter is None
                    and self._favorite_button.props.active is False
                    and self.search_entry.props.text == '')

    def clear_query(self):
        self.search_entry.props.text = ''
        self._filter_type = self._default_filter_type

        self._what_search_button.set_widget_icon(icon_name='view-type')
        self._what_search_button.set_widget_label(_('Anything'))
        self.set_what_filter(self._default_what_filter)

        self._when_search_button.set_widget_icon(icon_name='view-created')
        self._when_search_button.set_widget_label(_('Anytime'))
        self._when_filter = None
        '''
        self._with_search_button.set_widget_icon(icon_name='view-who')
        self._with_search_button.set_widget_label(_('Anyone'))
        self._with_filter = None
        '''

        self._favorite_button.props.active = False

        if self._proj_list_button.props.active:
            self._what_widget.show()
            self._what_search_button.show()
            self._proj_list_button.props.active = False

        self._update_if_needed()
Ejemplo n.º 24
0
class SpeechToolbar(Gtk.Toolbar):

    def __init__(self, activity):
        Gtk.Toolbar.__init__(self)
        self._activity = activity
        if not speech.supported:
            return
        self.is_paused = False

        self._cnf_client = GConf.Client.get_default()
        self.load_speech_parameters()

        self.sorted_voices = [i for i in speech.voices()]
        self.sorted_voices.sort(self.compare_voices)
        default = 0
        for voice in self.sorted_voices:
            if voice[0] == speech.voice[0]:
                break
            default = default + 1

        # Play button
        self.play_btn = ToggleToolButton('media-playback-start')
        self.play_btn.show()
        self.play_btn.connect('toggled', self.play_cb)
        self.insert(self.play_btn, -1)
        self.play_btn.set_tooltip(_('Play / Pause'))

        # Stop button
        self.stop_btn = ToolButton('media-playback-stop')
        self.stop_btn.show()
        self.stop_btn.connect('clicked', self.stop_cb)
        self.stop_btn.set_sensitive(False)
        self.insert(self.stop_btn, -1)
        self.stop_btn.set_tooltip(_('Stop'))

        self.voice_combo = ComboBox()
        for voice in self.sorted_voices:
            self.voice_combo.append_item(voice, voice[0])
        self.voice_combo.set_active(default)

        self.voice_combo.connect('changed', self.voice_changed_cb)
        combotool = ToolComboBox(self.voice_combo)
        self.insert(combotool, -1)
        combotool.show()
        speech.reset_buttons_cb = self.reset_buttons_cb

    def compare_voices(self,  a,  b):
        if a[0].lower() == b[0].lower():
            return 0
        if a[0] .lower() < b[0].lower():
            return -1
        if a[0] .lower() > b[0].lower():
            return 1

    def voice_changed_cb(self, combo):
        speech.voice = combo.props.value
        speech.say(speech.voice[0])
        self.save_speech_parameters()

    def load_speech_parameters(self):
        speech_parameters = {}
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        if os.path.exists(data_file_name):
            f = open(data_file_name, 'r')
            try:
                speech_parameters = json.load(f)
                speech.voice = speech_parameters['voice']
            finally:
                f.close()

        self._cnf_client.add_dir('/desktop/sugar/speech',
                                 GConf.ClientPreloadType.PRELOAD_NONE)
        speech.pitch = self._cnf_client.get_int('/desktop/sugar/speech/pitch')
        speech.rate = self._cnf_client.get_int('/desktop/sugar/speech/rate')
        self._cnf_client.notify_add('/desktop/sugar/speech/pitch',
                                    self.__conf_changed_cb, None)
        self._cnf_client.notify_add('/desktop/sugar/speech/rate',
                                    self.__conf_changed_cb, None)

    def __conf_changed_cb(self, client, connection_id, entry, args):
        key = entry.get_key()
        value = client.get_int(key)
        if key == '/desktop/sugar/speech/pitch':
            speech.pitch = value
        if key == '/desktop/sugar/speech/rate':
            speech.rate = value

    def save_speech_parameters(self):
        speech_parameters = {}
        speech_parameters['voice'] = speech.voice
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        f = open(data_file_name, 'w')
        try:
            json.dump(speech_parameters, f)
        finally:
            f.close()

    def reset_buttons_cb(self):
        self.play_btn.set_icon_name('media-playback-start')
        self.stop_btn.set_sensitive(False)
        self.is_paused = False

    def play_cb(self, widget):
        self.stop_btn.set_sensitive(True)
        if widget.get_active():
            self.play_btn.set_icon_name('media-playback-pause')
            if not self.is_paused:
                speech.play(self._activity._view.get_marked_words())
            else:
                speech.continue_play()
        else:
            self.play_btn.set_icon_name('media-playback-start')
            self.is_paused = True
            speech.pause()

    def stop_cb(self, widget):
        self.stop_btn.set_sensitive(False)
        self.play_btn.set_icon_name('media-playback-start')
        self.play_btn.set_active(False)
        self.is_paused = False
        speech.stop()
Ejemplo n.º 25
0
    def build_toolbar(self):
        self.max_participants = 4

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

        create_toolbar = ToolbarButton()
        create_toolbar.props.page = Gtk.Toolbar()
        create_toolbar.props.icon_name = 'magicpen'
        create_toolbar.props.label = _('Create')
        toolbar_box.toolbar.insert(create_toolbar, -1)
        self._insert_create_tools(create_toolbar)

        color = ColorToolButton('color')
        color.connect('notify::color', self.__color_notify_cb)
        toolbar_box.toolbar.insert(color, -1)
        color.show()

        random = ToggleToolButton('colorRandom')
        random.set_tooltip(_('Toggle random color'))
        toolbar_box.toolbar.insert(random, -1)
        random.set_active(True)
        random.connect('toggled', self.__random_toggled_cb)
        random.show()

        color.random = random
        random.color = color

        random.timeout_id = GLib.timeout_add(100, self.__timeout_cb, random)

        self._insert_stop_play_button(toolbar_box.toolbar)

        clear_trace = ToolButton('clear-trace')
        clear_trace.set_tooltip(_('Clear Trace Marks'))
        clear_trace.set_accelerator(_('<ctrl>x'))
        clear_trace.connect('clicked', self.clear_trace_cb)
        clear_trace.set_sensitive(False)
        toolbar_box.toolbar.insert(clear_trace, -1)
        clear_trace.show()
        self.clear_trace = clear_trace

        self._insert_clear_all_button(toolbar_box.toolbar)

        load_example = ToolButton('load-sample')
        load_example.set_tooltip(_('Show sample projects'))
        load_example.connect('clicked', self._create_store)

        toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1)
        toolbar_box.toolbar.insert(load_example, -1)
        load_example.show()

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

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

        separator = Gtk.SeparatorToolItem()
        activity_button.props.page.insert(separator, -1)
        separator.show()

        export_json = ToolButton('save-as-json')
        export_json.set_tooltip(_('Export tracked objects to journal'))
        export_json.connect('clicked', self._export_json_cb)
        activity_button.props.page.insert(export_json, -1)
        export_json.show()

        load_project = ToolButton('load-project')
        load_project.set_tooltip(_('Load project from journal'))
        load_project.connect('clicked', self._load_project)
        activity_button.props.page.insert(load_project, -1)
        load_project.show()

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show_all()
        create_toolbar.set_expanded(True)
        return toolbar_box
Ejemplo n.º 26
0
class MazeActivity(activity.Activity):
    def __init__(self, handle):
        """Set up the Maze activity."""
        activity.Activity.__init__(self, handle)
        self._busy_count = 0
        self._unbusy_idle_sid = None

        self.build_toolbar()

        self.pservice = PresenceService()
        self.owner = self.pservice.get_owner()

        state = None
        if 'state' in self.metadata:
            state = json.loads(self.metadata['state'])
        self.game = game.MazeGame(self, self.owner, state)
        self.set_canvas(self.game)
        self.game.show()
        self.connect("key_press_event", self.game.key_press_cb)

        self.text_channel = None
        self.my_key = profile.get_pubkey()
        self._alert = None

        if self.shared_activity:
            # we are joining the activity
            self._add_alert(_('Joining a maze'), _('Connecting...'))
            self.connect('joined', self._joined_cb)
            if self.get_shared():
                # we have already joined
                self._joined_cb()
        else:
            # we are creating the activity
            self.connect('shared', self._shared_cb)

    def busy(self):
        if self._busy_count == 0:
            if self._unbusy_idle_sid is not None:
                GLib.source_remove(self._unbusy_idle_sid)
                self._unbusy_idle_sid = None
            self._old_cursor = self.get_window().get_cursor()
            self._set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
        self._busy_count += 1

    def unbusy(self):
        self._unbusy_idle_sid = GLib.idle_add(self._unbusy_idle_cb)

    def _unbusy_idle_cb(self):
        self._unbusy_idle_sid = None
        self._busy_count -= 1
        if self._busy_count == 0:
            self._set_cursor(self._old_cursor)

    def _set_cursor(self, cursor):
        self.get_window().set_cursor(cursor)
        Gdk.flush()

    def build_toolbar(self):
        """Build our Activity toolbar for the Sugar system."""

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

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

        easier_button = ToolButton('create-easier')
        easier_button.set_tooltip(_('Easier level'))
        easier_button.connect('clicked', self._easier_button_cb)
        toolbar_box.toolbar.insert(easier_button, -1)

        harder_button = ToolButton('create-harder')
        harder_button.set_tooltip(_('Harder level'))
        harder_button.connect('clicked', self._harder_button_cb)
        toolbar_box.toolbar.insert(harder_button, -1)

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

        self.show_trail_button = ToggleToolButton('show-trail')
        self.show_trail_button.set_tooltip(_('Show trail'))
        self.show_trail_button.set_active(True)
        self.show_trail_button.connect('toggled', self._toggled_show_trail_cb)
        toolbar_box.toolbar.insert(self.show_trail_button, -1)

        separator = Gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_size_request(0, -1)
        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_all()

        return toolbar_box

    def _easier_button_cb(self, button):
        self.game.easier()

    def _harder_button_cb(self, button):
        self.game.harder()

    def _toggled_show_trail_cb(self, button):
        if self.game.set_show_trail(button.get_active()):
            self.broadcast_msg('show_trail:%s' % str(button.get_active()))

    def _shared_cb(self, activity):
        logging.debug('Maze was shared')
        self._add_alert(_('Sharing'), _('This maze is shared.'))
        self._setup()

    def _joined_cb(self, activity):
        """Joined a shared activity."""
        if not self.shared_activity:
            return
        logging.debug('Joined a shared chat')
        for buddy in self.shared_activity.get_joined_buddies():
            self._buddy_already_exists(buddy)
        self._setup()
        # request maze data
        self.broadcast_msg('req_maze')

    def _setup(self):
        self.text_channel = TextChannelWrapper(
            self.shared_activity.telepathy_text_chan,
            self.shared_activity.telepathy_conn, self.pservice)
        self.text_channel.set_received_callback(self._received_cb)
        self.shared_activity.connect('buddy-joined', self._buddy_joined_cb)
        self.shared_activity.connect('buddy-left', self._buddy_left_cb)

    def _received_cb(self, buddy, text):
        if buddy == self.owner:
            return
        self.game.msg_received(buddy, text)

    def _add_alert(self, title, text=None):
        self.grab_focus()
        self._alert = ErrorAlert()
        self._alert.props.title = title
        self._alert.props.msg = text
        self.add_alert(self._alert)
        self._alert.connect('response', self._alert_cancel_cb)
        self._alert.show()

    def _alert_cancel_cb(self, alert, response_id):
        self.remove_alert(alert)
        self._alert = None

    def update_alert(self, title, text=None):
        if self._alert is not None:
            self._alert.props.title = title
            self._alert.props.msg = text

    def show_accelerator_alert(self):
        self.grab_focus()
        self._alert = NotifyAlert()
        self._alert.props.title = _('Tablet mode detected.')
        self._alert.props.msg = _('Hold your XO flat and tilt to play!')
        self.add_alert(self._alert)
        self._alert.connect('response', self._alert_cancel_cb)
        self._alert.show()

    def _buddy_joined_cb(self, activity, buddy):
        """Show a buddy who joined"""
        logging.debug('buddy joined')
        if buddy == self.owner:
            logging.debug('its me, exit!')
            return
        self.game.buddy_joined(buddy)

    def _buddy_left_cb(self, activity, buddy):
        self.game.buddy_left(buddy)

    def _buddy_already_exists(self, buddy):
        """Show a buddy already in the chat."""
        if buddy == self.owner:
            return
        self.game.buddy_joined(buddy)

    def broadcast_msg(self, message):
        if self.text_channel:
            # FIXME: can't identify the sender at the other end,
            # add the pubkey to the text message
            self.text_channel.send('%s|%s' % (self.my_key, message))

    def write_file(self, file_path):
        logging.debug('Saving the state of the game...')
        data = {
            'seed': self.game.maze.seed,
            'width': self.game.maze.width,
            'height': self.game.maze.height,
            'finish_time': self.game.finish_time
        }
        logging.debug('Saving data: %s', data)
        self.metadata['state'] = json.dumps(data)

    def can_close(self):
        self.game.close_finish_window()
        return True

    def read_file(self, file_path):
        pass
Ejemplo n.º 27
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)
Ejemplo n.º 28
0
class SpeechToolbar(Gtk.Toolbar):
    def __init__(self, activity):
        Gtk.Toolbar.__init__(self)
        self._activity = activity
        self._speech = SpeechManager()
        self._is_paused = False

        self.load_speech_parameters()

        self._voices = self._speech.get_all_voices()  # a dictionary

        locale = os.environ.get('LANG', '')
        language_location = locale.split('.', 1)[0].lower()
        language = language_location.split('_')[0]
        # if the language is es but not es_es default to es_la (latin voice)
        if language == 'es' and language_location != 'es_es':
            language_location = 'es_la'

        self._voice = 'en_us'
        if language_location in self._voices:
            self._voice = language_location
        elif language in self._voices:
            self._voice = language

        voice_names = []
        for language, name in self._voices.iteritems():
            voice_names.append((language, name))
        voice_names.sort(self._compare_voice)

        # Play button
        self._play_button = ToggleToolButton('media-playback-start')
        self._play_button.show()
        self._play_button.connect('toggled', self._play_toggled_cb)
        self.insert(self._play_button, -1)
        self._play_button.set_tooltip(_('Play / Pause'))

        # Stop button
        self._stop_button = ToolButton('media-playback-stop')
        self._stop_button.show()
        self._stop_button.connect('clicked', self._stop_clicked_cb)
        self._stop_button.set_sensitive(False)
        self.insert(self._stop_button, -1)
        self._stop_button.set_tooltip(_('Stop'))

        # Language list
        combo = ComboBox()
        which = 0
        for pair in voice_names:
            language, name = pair
            combo.append_item(language, name)
            if language == self._voice:
                combo.set_active(which)
            which += 1

        combo.connect('changed', self._voice_changed_cb)
        combotool = ToolComboBox(combo)
        self.insert(combotool, -1)
        combotool.show()

        self._speech.connect('stop', self._reset_buttons_cb)

    def _compare_voice(self, a, b):
        if a[1].lower() == b[1].lower():
            return 0
        if a[1].lower() < b[1].lower():
            return -1
        if a[1].lower() > b[1].lower():
            return 1

    def _voice_changed_cb(self, combo):
        self._voice = combo.props.value
        self._speech.say_text(self._voices[self._voice])
        self.save_speech_parameters()

    def load_speech_parameters(self):
        speech_parameters = {}
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        if os.path.exists(data_file_name):
            f = open(data_file_name, 'r')
            try:
                speech_parameters = json.load(f)
                self._voice = speech_parameters['voice']
            finally:
                f.close()

    def save_speech_parameters(self):
        speech_parameters = {}
        speech_parameters['voice'] = self._voice
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        f = open(data_file_name, 'w')
        try:
            json.dump(speech_parameters, f)
        finally:
            f.close()

    def _reset_buttons_cb(self, widget=None):
        self._play_button.set_icon_name('media-playback-start')
        self._stop_button.set_sensitive(False)
        self._is_paused = False

    def _play_toggled_cb(self, widget):
        self._stop_button.set_sensitive(True)
        if widget.get_active():
            self._play_button.set_icon_name('media-playback-pause')
            if not self._is_paused:
                self._speech.say_text(self._activity._view.get_marked_words(),
                                      lang_code=self._voice)
            else:
                self._speech.restart()
        else:
            self._play_button.set_icon_name('media-playback-start')
            self._is_paused = True
            self._speech.pause()

    def _stop_clicked_cb(self, widget):
        self._stop_button.set_sensitive(False)
        self._play_button.set_icon_name('media-playback-start')
        self._play_button.set_active(False)
        self._is_paused = False
        self._speech.stop()
Ejemplo n.º 29
0
class DrawEditToolbar(EditToolbar):
    def __init__(self, activity):
        EditToolbar.__init__(self)

        self._activity = activity

        self.undo.set_tooltip(_('Undo'))
        self.redo.set_tooltip(_('Redo'))
        self.copy.set_tooltip(_('Copy'))
        self.paste.set_tooltip(_('Paste'))

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

        self._clear_all = ToolButton('edit-clear')
        self.insert(self._clear_all, -1)
        self._clear_all.set_tooltip(_('Clear'))
        self._clear_all.show()

        self._sound = ToggleToolButton('speaker-100')
        self._sound.set_tooltip(_('Enable sound'))

        if self._activity.area._player is not None:
            self.insert(self._sound, -1)

        self._sound.show()
        self._sound.connect('clicked', self.__sound_cb)

        self.undo.connect('clicked', self._undo_cb)
        self.redo.connect('clicked', self._redo_cb)

        self.copy.connect('clicked', self._copy_cb)
        self.paste.connect('clicked', self._paste_cb)
        self._clear_all.connect('clicked', self._clear_all_cb)

        self._activity.area.connect('undo', self._on_signal_undo_cb)
        self._activity.area.connect('redo', self._on_signal_redo_cb)
        self._activity.area.connect('select', self._on_signal_select_cb)
        self._activity.area.connect('action-saved',
                                    self._on_signal_action_saved_cb)

    def _undo_cb(self, widget, data=None):
        self._activity.area.undo()

    def _redo_cb(self, widget, data=None):
        self._activity.area.redo()

    def _copy_cb(self, widget, data=None):
        self._activity.area.copy()

    def _paste_cb(self, widget, data=None):
        self._activity.area.paste(self._activity.area)

    def _on_signal_undo_cb(self, widget, data=None):
        self._verify_sensitive_buttons()

    def _on_signal_redo_cb(self, widget, data=None):
        self._verify_sensitive_buttons()

    def _on_signal_select_cb(self, widget, data=None):
        self._verify_sensitive_buttons()

    def _on_signal_action_saved_cb(self, widget, data=None):
        self._verify_sensitive_buttons()

    # define when a button is active
    def _verify_sensitive_buttons(self):
        self.undo.set_sensitive(self._activity.area.can_undo())
        self.redo.set_sensitive(self._activity.area.can_redo())
        self.copy.set_sensitive(self._activity.area.is_selected())
        # TODO: it is not possible to verify this yet.
        # self.paste.set_sensitive(self._activity.area.can_paste())

    def _clear_all_cb(self, widget, data=None):
        self._activity.area.clear()

    def __sound_cb(self, widget):
        self._activity.area.enable_sounds(widget.get_active())
        if widget.get_active():
            self._sound.set_tooltip(_('Disable sound'))
        else:
            self._sound.set_tooltip(_('Enable sound'))
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)
        self.set_title('FotoToon')

        self._max_participants = 1

        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)
        view_toolbar.insert(slideview_btn, -1)
        slideview_btn.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
        text_button = ToolbarButton()
        text_button.props.page = TextToolbar(self.page)
        text_button.props.icon_name = 'format-text-size'
        text_button.props.label = _('Text')
        slideview_btn.connect('clicked', self._switch_view_mode, text_button)
        toolbar_box.toolbar.insert(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()

        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()

        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
Ejemplo n.º 31
0
class SpeechToolbar(Gtk.Toolbar):

    def __init__(self, activity):
        Gtk.Toolbar.__init__(self)
        voicebar = Gtk.Toolbar()
        self._activity = activity
        if not speech.supported:
            return

        self.load_speech_parameters()

        self.sorted_voices = [i for i in speech.voices()]
        self.sorted_voices.sort(self.compare_voices)
        default = 0
        for voice in self.sorted_voices:
            if voice[0] == speech.voice[0]:
                break
            default = default + 1

        # Play button
        self.play_btn = ToggleToolButton('media-playback-start')
        self.play_btn.show()
        self.play_btn.connect('toggled', self.play_cb)
        self.insert(self.play_btn, -1)
        self.play_btn.set_tooltip(_('Play / Pause'))

        self.voice_combo = ComboBox()
        for voice in self.sorted_voices:
            self.voice_combo.append_item(voice, voice[0])
        self.voice_combo.set_active(default)

        self.voice_combo.connect('changed', self.voice_changed_cb)
        combotool = ToolComboBox(self.voice_combo)
        self.insert(combotool, -1)
        combotool.show()

        self.pitchadj = Gtk.Adjustment(0, -100, 100, 1, 10, 0)
        pitchbar = Gtk.HScale(self.pitchadj)
        pitchbar.set_draw_value(False)
        pitchbar.set_update_policy(Gtk.UPDATE_DISCONTINUOUS)
        pitchbar.set_size_request(150, 15)
        self.pitchadj.set_value(speech.pitch)
        pitchtool = Gtk.ToolItem()
        pitchtool.add(pitchbar)
        pitchtool.show()
        self.insert(pitchtool, -1)
        pitchbar.show()

        self.rateadj = Gtk.Adjustment(0, -100, 100, 1, 10, 0)
        ratebar = Gtk.HScale(self.rateadj)
        ratebar.set_draw_value(False)
        ratebar.set_update_policy(Gtk.UPDATE_DISCONTINUOUS)
        ratebar.set_size_request(150, 15)
        self.rateadj.set_value(speech.rate)
        ratetool = Gtk.ToolItem()
        ratetool.add(ratebar)
        ratetool.show()
        self.insert(ratetool, -1)
        ratebar.show()
        self.pitchadj.connect("value_changed", self.pitch_adjusted_cb)
        self.rateadj.connect("value_changed", self.rate_adjusted_cb)

    def compare_voices(self,  a,  b):
        if a[0].lower() == b[0].lower():
            return 0
        if a[0] .lower() < b[0].lower():
            return -1
        if a[0] .lower() > b[0].lower():
            return 1

    def voice_changed_cb(self, combo):
        speech.voice = combo.props.value
        speech.say(speech.voice[0])
        self.save_speech_parameters()

    def pitch_adjusted_cb(self, get):
        speech.pitch = int(get.value)
        speech.say(_("pitch adjusted"))
        self.save_speech_parameters()

    def rate_adjusted_cb(self, get):
        speech.rate = int(get.value)
        speech.say(_("rate adjusted"))
        self.save_speech_parameters()

    def load_speech_parameters(self):
        speech_parameters = {}
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        if os.path.exists(data_file_name):
            f = open(data_file_name, 'r')
            try:
                speech_parameters = simplejson.load(f)
                speech.pitch = speech_parameters['pitch']
                speech.rate = speech_parameters['rate']
                speech.voice = speech_parameters['voice']
            finally:
                f.close()

    def save_speech_parameters(self):
        speech_parameters = {}
        speech_parameters['pitch'] = speech.pitch
        speech_parameters['rate'] = speech.rate
        speech_parameters['voice'] = speech.voice
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        f = open(data_file_name, 'w')
        try:
            simplejson.dump(speech_parameters, f)
        finally:
            f.close()

    def play_cb(self, widget):
        if widget.get_active():
            self.play_btn.set_named_icon('media-playback-pause')
            if speech.is_stopped():
                speech.play(self._activity._view.get_marked_words())
        else:
            self.play_btn.set_named_icon('media-playback-start')
            speech.stop()
Ejemplo n.º 32
0
class SpeechToolbar(Gtk.Toolbar):
    def __init__(self, activity):
        GObject.GObject.__init__(self)
        self._activity = activity
        if not speech.supported:
            return
        self.is_paused = False
        self._cnf_client = GConf.Client.get_default()
        self.load_speech_parameters()

        self.sorted_voices = [i for i in speech.voices()]
        self.sorted_voices.sort(self.compare_voices)
        default = 0
        for voice in self.sorted_voices:
            if voice[0] == speech.voice[0]:
                break
            default = default + 1

        # Play button
        self.play_btn = ToggleToolButton("media-playback-start")
        self.play_btn.show()
        self.play_toggled_handler = self.play_btn.connect("toggled", self.play_cb)
        self.insert(self.play_btn, -1)
        self.play_btn.set_tooltip(_("Play / Pause"))

        # Stop button
        self.stop_btn = ToolButton("media-playback-stop")
        self.stop_btn.show()
        self.stop_btn.connect("clicked", self.stop_cb)
        self.stop_btn.set_sensitive(False)
        self.insert(self.stop_btn, -1)
        self.stop_btn.set_tooltip(_("Stop"))

        self.voice_combo = ComboBox()
        for voice in self.sorted_voices:
            self.voice_combo.append_item(voice, voice[0])
        self.voice_combo.set_active(default)

        self.voice_combo.connect("changed", self.voice_changed_cb)
        combotool = ToolComboBox(self.voice_combo)
        self.insert(combotool, -1)
        combotool.show()
        speech.reset_cb = self.reset_buttons_cb
        speech.end_text_cb = self.reset_buttons_cb

    def compare_voices(self, a, b):
        if a[0].lower() == b[0].lower():
            return 0
        if a[0].lower() < b[0].lower():
            return -1
        if a[0].lower() > b[0].lower():
            return 1

    def voice_changed_cb(self, combo):
        speech.voice = combo.props.value
        speech.say(speech.voice[0])
        self.save_speech_parameters()

    def load_speech_parameters(self):
        speech_parameters = {}
        data_path = os.path.join(self._activity.get_activity_root(), "data")
        data_file_name = os.path.join(data_path, "speech_params.json")
        if os.path.exists(data_file_name):
            f = open(data_file_name, "r")
            try:
                speech_parameters = json.load(f)
                speech.voice = speech_parameters["voice"]
            finally:
                f.close()
        else:
            speech.voice = self.get_default_voice()
            logging.error("Default voice %s", speech.voice)

        self._cnf_client.add_dir("/desktop/sugar/speech", GConf.ClientPreloadType.PRELOAD_NONE)
        speech.pitch = self._cnf_client.get_int("/desktop/sugar/speech/pitch")
        speech.rate = self._cnf_client.get_int("/desktop/sugar/speech/rate")
        self._cnf_client.notify_add("/desktop/sugar/speech/pitch", self.__conf_changed_cb, None)
        self._cnf_client.notify_add("/desktop/sugar/speech/rate", self.__conf_changed_cb, None)

    def get_default_voice(self):
        """Try to figure out the default voice, from the current locale
           ($LANG)
           Fall back to espeak's voice called Default."""
        voices = speech.get_all_voices()

        locale = os.environ.get("LANG", "")
        language_location = locale.split(".", 1)[0].lower()
        language = language_location.split("_")[0]
        variant = ""
        if language_location.find("_") > -1:
            variant = language_location.split("_")[1]
        # if the language is es but not es_es default to es_la (latin voice)
        if language == "es" and language_location != "es_es":
            language_location = "es_la"

        best = voices.get(language_location) or voices.get(language) or "default"
        logging.debug("Best voice for LANG %s seems to be %s", locale, best)
        return [best, language, variant]

    def __conf_changed_cb(self, client, connection_id, entry, args):
        key = entry.get_key()
        value = client.get_int(key)
        if key == "/desktop/sugar/speech/pitch":
            speech.pitch = value
        if key == "/desktop/sugar/speech/rate":
            speech.rate = value

    def save_speech_parameters(self):
        speech_parameters = {}
        speech_parameters["voice"] = speech.voice
        data_path = os.path.join(self._activity.get_activity_root(), "data")
        data_file_name = os.path.join(data_path, "speech_params.json")
        f = open(data_file_name, "w")
        try:
            json.dump(speech_parameters, f)
        finally:
            f.close()

    def reset_buttons_cb(self):
        logging.error("reset buttons")
        self.play_btn.set_icon_name("media-playback-start")
        self.stop_btn.set_sensitive(False)
        self.play_btn.handler_block(self.play_toggled_handler)
        self.play_btn.set_active(False)
        self.play_btn.handler_unblock(self.play_toggled_handler)
        self.is_paused = False

    def play_cb(self, widget):
        self.stop_btn.set_sensitive(True)
        if widget.get_active():
            self.play_btn.set_icon_name("media-playback-pause")
            logging.error("Paused %s", self.is_paused)
            if not self.is_paused:
                # get the text to speech, if there are a selection,
                # play selected text, if not, play all
                abi = self._activity.abiword_canvas
                selection = abi.get_selection("text/plain")
                if not selection or selection[0] is None or selection[1] == 0:
                    # nothing selected
                    abi.select_all()
                    text = abi.get_selection("text/plain")[0]
                    abi.moveto_bod()
                else:
                    text = selection[0]
                speech.play(text)
            else:
                logging.error("Continue play")
                speech.continue_play()
        else:
            self.play_btn.set_icon_name("media-playback-start")
            self.is_paused = True
            speech.pause()

    def stop_cb(self, widget):
        self.stop_btn.set_sensitive(False)
        self.play_btn.set_icon_name("media-playback-start")
        self.play_btn.set_active(False)
        self.is_paused = False
        speech.stop()
Ejemplo n.º 33
0
class WriteBooksActivity(activity.Activity):

    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        self._book_model = BookModel()
        self._actual_page = 1

        # we do not have collaboration features
        # make the share option insensitive
        self.max_participants = 1

        # get the language configured by the user
        # will be used to translate the names of the media files
        locale = os.environ.get('LANG', '')
        language_location = locale.split('.', 1)[0].lower()
        self._language = language_location.split('_')[0]
        if self._language == 'en':
            # we don't need translate the file names if langauage is 'en'
            self._language = None
        self._translations = None
        if self._language is not None:
            # read the translations file if available
            dict_path = os.path.join(activity.get_bundle_path(), 'data',
                                     "%s_dict.csv" % self._language)
            logging.debug('Looking for media translation dictionary %s',
                          dict_path)
            if os.path.exists(dict_path):
                logging.debug('Loading translations')
                self._translations = {}
                with open(dict_path) as dict_file:
                    for line in dict_file:
                        words = line.split(',')
                        self._translations[words[0]] = words[1].strip()

        toolbar_box = ToolbarBox()

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

        self._edit_toolbar = EditToolbar()
        edit_toolbar_button = ToolbarButton(
            page=self._edit_toolbar, icon_name='toolbar-edit')
        toolbar_box.toolbar.insert(edit_toolbar_button, 1)

        set_background_button = ToolButton('set-background')
        set_background_button.set_tooltip(_('Set the background'))
        set_background_button.connect('clicked',
                                      self.__set_background_clicked_cb)
        toolbar_box.toolbar.insert(set_background_button, -1)

        insert_picture_button = ToolButton('insert-picture')
        insert_picture_button.set_tooltip(_('Add a picture'))
        insert_picture_button.connect('clicked',
                                      self.__add_image_clicked_cb)
        toolbar_box.toolbar.insert(insert_picture_button, -1)

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

        self._duplicate_page_button = ToolButton()
        icon = Icon(icon_name='edit-duplicate', xo_color=profile.get_color())
        self._duplicate_page_button.set_icon_widget(icon)

        self._duplicate_page_button.set_tooltip(_('Duplicate page'))
        self._duplicate_page_button.connect(
            'clicked', self.__duplicate_page_clicked_cb)
        toolbar_box.toolbar.insert(self._duplicate_page_button, -1)

        self._add_page_button = ToolButton('list-add')
        self._add_page_button.set_tooltip(_('Add a page'))
        self._add_page_button.connect('clicked', self.__add_page_clicked_cb)
        toolbar_box.toolbar.insert(self._add_page_button, -1)

        self._remove_button = ToolButton('edit-delete')
        self._remove_button.set_tooltip(_('Remove an image or page'))
        self._remove_button.connect('clicked', self.__remove_clicked_cb)
        toolbar_box.toolbar.insert(self._remove_button, -1)

        self._prev_page_button = ToolButton('go-previous-paired')
        self._prev_page_button.set_tooltip(_('Previous page'))
        self._prev_page_button.connect('clicked', self.__prev_page_clicked_cb)
        toolbar_box.toolbar.insert(self._prev_page_button, -1)

        self._next_page_button = ToolButton('go-next-paired')
        self._next_page_button.set_tooltip(_('Next page'))
        self._next_page_button.connect('clicked', self.__next_page_clicked_cb)
        toolbar_box.toolbar.insert(self._next_page_button, -1)

        self._view_list_button = ToggleToolButton('view-list')
        self._view_list_button.set_tooltip(_('View pages'))
        self._view_list_button.connect('toggled', self.__view_list_toggled_cb)
        toolbar_box.toolbar.insert(self._view_list_button, -1)

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

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

        # add export buttons
        activity_toolbar = activity_button.props.page
        epub_button = ToolButton('save-as-epub')
        epub_button.set_tooltip(_('Save as EPUB book'))
        epub_button.connect('clicked', self.__save_ebook_clicked_cb)
        activity_toolbar.insert(epub_button, -1)
        epub_button.show()

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show_all()

        edition_canvas = self.create_edition_canvas()

        hbox = Gtk.HBox()
        self._preview_panel = PreviewPanel(self._book_model.get_pages())
        self._preview_panel.connect('page-activated', self.__page_activated_cb)
        self._preview_panel.connect('page-moved', self.__page_moved_cb)
        hbox.pack_start(self._preview_panel, False, False, 0)
        hbox.pack_start(edition_canvas, True, True, 0)

        self.set_canvas(hbox)
        self.prepare_edit_toolbar()
        self._update_page_buttons()

        self.show_all()
        self._preview_panel.hide()

    def create_edition_canvas(self):
        self._image_canvas = ImageCanvas()
        self._image_canvas.connect('images-modified',
                                   self.__images_modified_cb)
        self._image_canvas.set_halign(Gtk.Align.CENTER)
        self._image_canvas.set_valign(Gtk.Align.CENTER)
        self._image_canvas.set_vexpand(True)

        self._text_editor = TextEditor()
        self._text_changed_signal_id = self._text_editor.connect(
            'changed', self.__text_changed_cb)

        self._page_counter_label = Gtk.Label('1 / 1')
        font_desc = Pango.font_description_from_string('12')
        self._page_counter_label.modify_font(font_desc)
        self._page_counter_label.set_halign(Gtk.Align.END)
        self._page_counter_label.set_valign(Gtk.Align.END)
        self._page_counter_label.set_margin_right(style.DEFAULT_PADDING)
        self._page_counter_label.set_margin_top(style.DEFAULT_PADDING)

        background = Gtk.EventBox()
        rgba = Gdk.RGBA()
        rgba.red, rgba.green, rgba.blue, rgba.alpha = 1., 1., 1., 1.
        background.override_background_color(Gtk.StateFlags.NORMAL, rgba)

        self._scrolled_window = Gtk.ScrolledWindow()
        self._scrolled_window.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
        self._scrolled_window.set_size_request(
            Gdk.Screen.width() - style.GRID_CELL_SIZE * 2,
            style.GRID_CELL_SIZE * 2)
        self._scrolled_window.set_policy(Gtk.PolicyType.NEVER,
                                         Gtk.PolicyType.AUTOMATIC)
        self._scrolled_window.add(self._text_editor)
        self._scrolled_window.set_margin_left(style.GRID_CELL_SIZE)
        self._scrolled_window.set_margin_right(style.GRID_CELL_SIZE)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        box.pack_start(self._page_counter_label, False, False, 0)
        box.pack_start(self._image_canvas, True, True, 0)
        box.pack_start(self._scrolled_window, False, False,
                       style.DEFAULT_PADDING)
        background.add(box)
        background.show_all()
        background.connect('size_allocate', self.__background_size_allocate_cb)
        return background

    def __background_size_allocate_cb(self, widget, allocation):
        height = allocation.height / 4 * 3
        width = height / 3 * 4
        logging.debug('size allocate %s x %s', width, height)
        self._image_canvas.set_size_request(width, height)
        widget.check_resize()

    def __view_list_toggled_cb(self, button):
        if button.get_active():
            self._preview_panel.update_model(self._book_model.get_pages())
            self._preview_panel.show()
            self._image_canvas.set_editable(False)
            self._text_editor.set_editable(False)
            self._scrolled_window.set_size_request(
                (Gdk.Screen.width() * 3 / 4) - style.GRID_CELL_SIZE * 2,
                style.GRID_CELL_SIZE * 2)
        else:
            self._preview_panel.hide()
            self._image_canvas.set_editable(True)
            self._text_editor.set_editable(True)
            self._scrolled_window.set_size_request(
                Gdk.Screen.width() - style.GRID_CELL_SIZE * 2,
                style.GRID_CELL_SIZE * 2)

    def write_file(self, file_path):
        self._book_model.write(file_path)
        self.metadata['mime_type'] = 'application/x-writebooks-activity'

    def read_file(self, file_path):
        self._book_model.read(file_path)
        self._update_page_buttons()

    def prepare_edit_toolbar(self):
        self._edit_toolbar.copy.connect('clicked', self.__copy_clicked_cb)
        self._edit_toolbar.paste.connect('clicked', self.__paste_clicked_cb)
        self._edit_toolbar.undo.connect('clicked', self.__undo_clicked_cb)
        self._edit_toolbar.redo.connect('clicked', self.__redo_clicked_cb)

    def __copy_clicked_cb(self, button):
        if self._text_editor.get_buffer().get_has_selection():
            self._text_editor.get_buffer().copy_clipboard(
                Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD))
        elif self._image_canvas.is_image_active():
            # if not text is selected
            # and a image is selected, copy as pixbuf
            clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
            pxb = self._image_canvas.create_pixbuf_with_active_image()
            clipboard.set_image(pxb)

    def __paste_clicked_cb(self, button):
        self._text_editor.get_buffer().paste_clipboard(
            Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD), None, True)

    def __undo_clicked_cb(self, button):
        self._text_editor.get_buffer().undo()

    def __redo_clicked_cb(self, button):
        self._text_editor.get_buffer().redo()

    def __set_background_clicked_cb(self, button):
        categories = {
            _('Indoors'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Indoors')],
            _('Nature'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Nature')],
            _('Outdoors'):
                [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Outdoors')],
            _('Sports'): [os.path.join(SCRATCH_BACKGROUNDS_PATH, 'Sports')]}

        chooser = ImageFileChooser(image_type='backgrounds',
                                   title=_('Select a background'),
                                   categories=categories,
                                   language=self._language,
                                   translations=self._translations,
                                   parent=self.get_window())
        chooser.connect('response', self.__chooser_response_cb,
                        self._change_background)
        self.set_sensitive(False)
        chooser.show()

    def __chooser_response_cb(self, chooser, response_id, operation_function):
        self.set_sensitive(True)
        if response_id == Gtk.ResponseType.ACCEPT:
            logging.error('selected %s', chooser.get_selected_object_id())
            file_path = chooser.get_selected_object_id()
            tempfile_name = \
                os.path.join(self.get_activity_root(),
                             'instance', 'tmp%i' % time.time())
            os.link(file_path, tempfile_name)
            operation_function(tempfile_name)
        chooser.destroy()
        del chooser
        if response_id == Gtk.ResponseType.REJECT:
            try:
                chooser = ObjectChooser(self, what_filter='Image',
                                        filter_type=FILTER_TYPE_GENERIC_MIME,
                                        show_preview=True)
            except:
                # for compatibility with older versions
                chooser = ObjectChooser(self, what_filter='Image')

            try:
                result = chooser.run()
                if result == Gtk.ResponseType.ACCEPT:
                    logging.error('ObjectChooser: %r' %
                                  chooser.get_selected_object())
                    jobject = chooser.get_selected_object()
                    if jobject and jobject.file_path:
                        logging.error("imagen seleccionada: %s",
                                      jobject.file_path)
                        tempfile_name = \
                            os.path.join(self.get_activity_root(),
                                         'instance', 'tmp%i' % time.time())
                        os.link(jobject.file_path, tempfile_name)
                        operation_function(tempfile_name)
            finally:
                chooser.destroy()
                del chooser

    def _change_background(self, file_name):
        self._book_model.set_page_background(self._actual_page, file_name)
        self._update_page_view()

    def __add_image_clicked_cb(self, button):
        categories = {
            _('Animals'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Animals'),
                           os.path.join(TUXPAINT_STAMPS_PATH, 'animals')],
            _('Fantasy'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Fantasy'),
                           os.path.join(TUXPAINT_STAMPS_PATH, 'cartoon')],
            _('Letters'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Letters')],
            _('People'): [os.path.join(SCRATCH_COSTUMES_PATH, 'People'),
                          os.path.join(TUXPAINT_STAMPS_PATH, 'people')],
            _('Things'): [os.path.join(SCRATCH_COSTUMES_PATH, 'Things'),
                          os.path.join(TUXPAINT_STAMPS_PATH, 'clothes'),
                          os.path.join(TUXPAINT_STAMPS_PATH, 'hobbies'),
                          os.path.join(TUXPAINT_STAMPS_PATH, 'medical'),
                          os.path.join(TUXPAINT_STAMPS_PATH, 'household'),
                          os.path.join(TUXPAINT_STAMPS_PATH, 'food')],
            _('Transportation'): [
                os.path.join(SCRATCH_COSTUMES_PATH, 'Transportation'),
                os.path.join(TUXPAINT_STAMPS_PATH, 'vehicles')]}

        chooser = ImageFileChooser(image_type='actors',
                                   title=_('Select an image to add'),
                                   categories=categories,
                                   language=self._language,
                                   translations=self._translations,
                                   parent=self.get_window())
        chooser.connect('response', self.__chooser_response_cb,
                        self._add_image)
        self.set_sensitive(False)
        chooser.show()

    def _add_image(self, file_name):
        logging.error('Add image %s', file_name)
        self._book_model.add_image(self._actual_page, file_name)
        self._update_page_view()

    def __remove_clicked_cb(self, file_name):
        if self._image_canvas.is_image_active():
            alert = ConfirmationAlert()
            alert.props.title = _('Do you want remove the selected image?')
            # alert.props.msg = _('')
            alert.connect('response', self.__confirm_remove_image_cb)
            self.add_alert(alert)
        else:
            if len(self._book_model.get_pages()) > 1:
                alert = ConfirmationAlert()
                alert.props.title = _('Do you want remove the page?')
                # alert.props.msg = _('')
                alert.connect('response', self.__confirm_remove_page_cb)
                self.add_alert(alert)

    def __confirm_remove_image_cb(self, alert, response_id):
        # Callback for conf alert
        self.remove_alert(alert)
        if response_id is Gtk.ResponseType.OK:
            self._image_canvas.remove_active_image()

    def __confirm_remove_page_cb(self, alert, response_id):
        # Callback for conf alert
        self.remove_alert(alert)
        if response_id is Gtk.ResponseType.OK:
            if self._book_model.remove_page(self._actual_page):
                if self._actual_page > len(self._book_model.get_pages()):
                    self._actual_page -= 1
                self._update_page_buttons()
                self._preview_panel.update_model(self._book_model.get_pages())

    def __images_modified_cb(self, canvas, images_views):
        self._book_model.update_images(self._actual_page, images_views)

    def _update_page_buttons(self):
        cant_pages = len(self._book_model.get_pages())
        self._page_counter_label.set_text('%d / %d' %
                                          (self._actual_page, cant_pages))
        self._prev_page_button.set_sensitive(self._actual_page > 1)
        self._next_page_button.set_sensitive(self._actual_page < cant_pages)
        self._update_page_view()

    def _update_page_view(self):
        page_model = self._book_model.get_page_model(self._actual_page)
        self._image_canvas.set_background(page_model.background_path)
        self._image_canvas.set_images(page_model.images)
        self._text_editor.disconnect(self._text_changed_signal_id)
        self._text_editor.set_text(page_model.text)
        self._text_changed_signal_id = self._text_editor.connect(
            'changed', self.__text_changed_cb)

    def __add_page_clicked_cb(self, button):
        self._book_model.add_page()
        self._actual_page = len(self._book_model.get_pages())
        self._update_page_buttons()
        self._preview_panel.update_model(self._book_model.get_pages())

    def __duplicate_page_clicked_cb(self, button):
        actual_page_model = self._book_model.get_page_model(self._actual_page)
        self._book_model.add_page(actual_page_model)
        self._actual_page = len(self._book_model.get_pages())
        self._update_page_buttons()
        self._preview_panel.update_model(self._book_model.get_pages())

    def __next_page_clicked_cb(self, button):
        self._actual_page += 1
        self._update_page_buttons()
        self._preview_panel.update_position(1)

    def __prev_page_clicked_cb(self, button):
        self._actual_page -= 1
        self._update_page_buttons()
        self._preview_panel.update_position(-1)

    def __page_activated_cb(self, preview_panel, order):
        self._actual_page = order
        self._update_page_buttons()

    def __page_moved_cb(self, preview_panel, pages_order_array):
        new_pages = []
        for n in pages_order_array:
            new_pages.append(self._book_model.get_pages()[n])
        # actual_page is 1 based and order is 0 based
        actual_page_order = self._actual_page - 1
        new_order_actual_page = pages_order_array.index(actual_page_order)
        self._actual_page = new_order_actual_page + 1
        self._book_model.set_pages(new_pages)
        self._update_page_buttons()
        preview_panel.update_model(self._book_model.get_pages())

    def __text_changed_cb(self, texteditor):
        self._book_model.set_page_text(self._actual_page,
                                       texteditor.get_text())

    def __save_ebook_clicked_cb(self, button):
        alert = Alert()
        alert.props.title = _('Book creation')
        alert.props.msg = _('Do you want to add an image for the cover?')
        icon = Icon(icon_name='dialog-ok')
        alert.add_button(Gtk.ResponseType.YES, _('Yes'), icon)
        icon.show()
        icon = Icon(icon_name='dialog-cancel')
        alert.add_button(Gtk.ResponseType.NO, _('No'), icon)
        icon.show()
        alert.connect('response', self.__add_cover_response_cb,
                      self._set_cover_and_create_book)
        self.add_alert(alert)

    def __add_cover_response_cb(self, alert, response_id, operation_function):
        if response_id == Gtk.ResponseType.YES:
            try:
                chooser = ObjectChooser(self, what_filter='Image',
                                        filter_type=FILTER_TYPE_GENERIC_MIME,
                                        show_preview=True)
            except:
                # for compatibility with older versions
                chooser = ObjectChooser(self, what_filter='Image')

            try:
                result = chooser.run()
                if result == Gtk.ResponseType.ACCEPT:
                    logging.error('ObjectChooser: %r' %
                                  chooser.get_selected_object())
                    jobject = chooser.get_selected_object()
                    if jobject and jobject.file_path:
                        logging.error("imagen seleccionada: %s",
                                      jobject.file_path)
                        mime_type = mime.get_for_file(jobject.file_path)
                        extension = mime.get_primary_extension(mime_type)
                        tempfile_name = \
                            os.path.join(
                                self.get_activity_root(), 'instance',
                                'tmp%i.%s' % (time.time(), extension))
                        os.link(jobject.file_path, tempfile_name)
                        operation_function(tempfile_name)
            finally:
                chooser.destroy()
                del chooser

        elif response_id == Gtk.ResponseType.NO:
            self._save_epub()
        self.remove_alert(alert)

    def _set_cover_and_create_book(self, cover_file_name):
        self._book_model.cover_path = cover_file_name
        self._save_epub()

    def _save_epub(self):
        epub_file_name = create_ebub_from_book_model(
            self.metadata['title'], self._book_model)

        # create a new journal item
        fileObject = datastore.create()
        fileObject.metadata['title'] = \
            _('"%s" as book') % self.metadata['title']
        fileObject.metadata['mime_type'] = 'application/epub+zip'

        full_text = ''
        for page in self._book_model.get_pages():
            full_text += page.text + '\n'
        fileObject.metadata['fulltext'] = full_text
        fileObject.metadata['icon-color'] = self.metadata['icon-color']
        fileObject.metadata['keep'] = self.metadata.get('keep', '0')

        fileObject.metadata['preview'] = self.metadata['preview']
        fileObject.file_path = epub_file_name

        # store the journal item
        datastore.write(fileObject, transfer_ownership=True)
        book_object_id = fileObject.object_id

        fileObject.destroy()
        del fileObject
        shutil.rmtree(os.path.dirname(epub_file_name))

        finish_alert = Alert()
        finish_alert.props.title = _('Book created')
        finish_alert.props.msg = _('You can read the book in your Journal')
        open_icon = Icon(icon_name='zoom-activity')
        finish_alert.add_button(Gtk.ResponseType.APPLY,
                                _('Show in Journal'), open_icon)
        open_icon.show()
        ok_icon = Icon(icon_name='dialog-ok')
        finish_alert.add_button(Gtk.ResponseType.OK, _('Ok'), ok_icon)
        ok_icon.show()
        # Remove other alerts
        for alert in self._alerts:
            self.remove_alert(alert)

        self.add_alert(finish_alert)
        finish_alert.connect('response', self.__book_saved_alert_response_cb,
                             book_object_id)
        finish_alert.show()

    def __book_saved_alert_response_cb(self, alert, response_id,
                                       book_object_id):
        if response_id is Gtk.ResponseType.APPLY:
            activity.show_object_in_journal(book_object_id)
        self.remove_alert(alert)
Ejemplo n.º 34
0
class Record(activity.Activity):
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        if Gst.version() == (1, 0, 10, 0):
            return self._incompatible()

        # for fullscreen feature, use local rather than toolkit
        self.props.enable_fullscreen_mode = False

        self._state = None
        Instance(self)

        # the main classes
        self.model = Model(self)
        self.ui_init()

        # CSCL
        self.connect("shared", self._shared_cb)
        if self.get_shared_activity():
            # have you joined or shared this activity yourself?
            if self.get_shared():
                self._joined_cb(self)
            else:
                self.connect("joined", self._joined_cb)

        # Changing to the first toolbar kicks off the rest of the setup
        if self.model.get_cameras():
            self.model.change_mode(constants.MODE_PHOTO)
        else:
            self.model.change_mode(constants.MODE_AUDIO)

        # Start live video pipeline when the video window becomes visible
        def on_defer_cb():
            self.model.set_visible(True)
            self.connect("notify::active", self.__active_cb)
            return False

        def on_event_cb(widget, event):
            if event.state == Gdk.VisibilityState.UNOBSCURED:
                GLib.timeout_add(50, on_defer_cb)
                self._media_view._video.disconnect_by_func(on_event_cb)

        self._media_view._video.add_events(
            Gdk.EventMask.VISIBILITY_NOTIFY_MASK)
        self._media_view._video.connect('visibility-notify-event', on_event_cb)

    def _incompatible(self):
        ''' Display abbreviated activity user interface with alert '''
        toolbox = ToolbarBox()
        stop = StopButton(self)
        toolbox.toolbar.add(stop)
        self.set_toolbar_box(toolbox)

        title = _('Activity not compatible with this system.')
        msg = _('Please downgrade activity and try again.')
        alert = Alert(title=title, msg=msg)
        alert.add_button(0, 'Stop', Icon(icon_name='activity-stop'))
        self.add_alert(alert)

        label = Gtk.Label(_('Uh oh, GStreamer is too old.'))
        self.set_canvas(label)

        alert.connect('response', self.__incompatible_response_cb)
        stop.connect('clicked', self.__incompatible_stop_clicked_cb,
                     alert)

        self.show_all()

    def __incompatible_stop_clicked_cb(self, button, alert):
        self.remove_alert(alert)

    def __incompatible_response_cb(self, alert, response):
        self.remove_alert(alert)
        self.close()

    def read_file(self, path):
        if hasattr(self, 'model'):
            self.model.read_file(path)

    def write_file(self, path):
        if hasattr(self, 'model'):
            self.model.write_file(path)

    def close(self, **kwargs):
        if hasattr(self, 'model'):
            self.model.close()
        activity.Activity.close(self, **kwargs)

    def __active_cb(self, widget, pspec):
        self.model.set_visible(self.props.active)

    def _shared_cb(self, activity):
        self.model.collab.set_activity_shared()

    def _joined_cb(self, activity):
        self.model.collab.joined()

    def ui_init(self):
        self._fullscreen = False
        self._showing_info = False

        # FIXME: if _thumb_tray becomes some kind of button group, we wouldn't
        # have to track which recd is active
        self._active_recd = None

        self.connect('key-press-event', self._key_pressed)

        self._active_toolbar_idx = 0

        toolbar_box = ToolbarBox()
        self._activity_toolbar_button = ActivityToolbarButton(self)
        toolbar_box.toolbar.insert(self._activity_toolbar_button, 0)
        self.set_toolbar_box(toolbar_box)
        self._toolbar = self.get_toolbar_box().toolbar

        tool_group = None
        if self.model.get_cameras():
            self._photo_button = RadioToolButton()
            self._photo_button.props.group = tool_group
            tool_group = self._photo_button
            self._photo_button.props.icon_name = 'camera-external'
            self._photo_button.props.label = _('Photo')
            self._photo_button.props.accelerator = '<ctrl>1'
            self._photo_button.props.tooltip = _(
                'Picture camera mode\n\n'
                'When the record button is pressed,\n'
                'take one picture from the camera.')
            self._photo_button.mode = constants.MODE_PHOTO
            self._photo_button.connect('clicked', self._mode_button_clicked)
            self._toolbar.insert(self._photo_button, -1)

            self._video_button = RadioToolButton()
            self._video_button.props.group = tool_group
            self._video_button.props.icon_name = 'media-video'
            self._video_button.props.accelerator = '<ctrl>2'
            self._video_button.props.label = _('Video')
            self._video_button.props.tooltip = _(
                'Video camera mode\n\n'
                'When the record button is pressed,\n'
                'take photographs many times a second,\n'
                'and record sound using the microphone,\n'
                'until the button is pressed again.')
            self._video_button.mode = constants.MODE_VIDEO
            self._video_button.connect('clicked', self._mode_button_clicked)
            self._toolbar.insert(self._video_button, -1)
        else:
            self._photo_button = None
            self._video_button = None

        self._audio_button = RadioToolButton()
        self._audio_button.props.group = tool_group
        self._audio_button.props.icon_name = 'media-audio'
        self._audio_button.props.accelerator = '<ctrl>3'
        self._audio_button.props.label = _('Audio')
        self._audio_button.props.tooltip = _(
            'Audio recording mode\n\n'
            'When the record button is pressed,\n'
            'take one photograph,\n'
            'and record sound using the microphone,\n'
            'until the button is pressed again.')
        self._audio_button.mode = constants.MODE_AUDIO
        self._audio_button.connect('clicked', self._mode_button_clicked)
        self._toolbar.insert(self._audio_button, -1)

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

        self._mirror_btn = ToggleToolButton('mirror-horizontal')
        self._mirror_btn.set_tooltip(_(
            'Mirror view\n\n'
            'Swap left for right, as if looking at a mirror.\n'
            'Does not affect recording.'))
        self._mirror_btn.props.accelerator = '<ctrl>m'
        self._mirror_btn.show()
        self._mirror_btn.connect('toggled', self.__mirror_toggled_cb)
        self._toolbar.insert(self._mirror_btn, -1)

        self._toolbar_controls = RecordControl(self._toolbar)

        if self.model.get_cameras() and len(self.model.get_cameras()) > 1:
            switch_camera_btn = ToolButton('switch-camera')
            switch_camera_btn.set_tooltip(_('Switch camera'))
            switch_camera_btn.show()
            switch_camera_btn.connect('clicked', self.__switch_camera_click_cb)
            self._toolbar.insert(switch_camera_btn, -1)

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

        self._media_view = MediaView()
        self._media_view.connect('media-clicked',
                                 self._media_view_media_clicked)
        self._media_view.connect('pip-clicked', self._media_view_pip_clicked)
        self._media_view.connect('info-clicked', self._media_view_info_clicked)
        self._media_view.connect('fullscreen-clicked',
                                 self._media_view_fullscreen_clicked)
        self._media_view.connect('tags-changed', self._media_view_tags_changed)
        self._media_view.show()

        self._controls_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        trim_height_shutter_button = 7
        self._controls_hbox.set_size_request(-1, style.GRID_CELL_SIZE +
                                             trim_height_shutter_button)

        self._shutter_button = ShutterButton()
        self._shutter_button.connect("clicked", self._shutter_clicked)
        self._shutter_button.modify_bg(Gtk.StateType.NORMAL, COLOR_BLACK)
        self._controls_hbox.pack_start(self._shutter_button, True, False, 0)

        self._countdown_image = CountdownImage()
        self._controls_hbox.pack_start(self._countdown_image, True, False, 0)

        self._play_button = PlayButton()
        self._play_button.connect('clicked', self._play_pause_clicked)
        self._controls_hbox.pack_start(self._play_button, False, True, 0)

        self._playback_scale = PlaybackScale(self.model)
        self._controls_hbox.pack_start(self._playback_scale, True, True, 0)

        self._progress = ProgressInfo()
        self._controls_hbox.pack_start(self._progress, True, True, 0)

        self._title_label = Gtk.Label()
        self._title_label.set_markup("<b><span foreground='white'>" +
                                     _('Title:') + '</span></b>')
        self._controls_hbox.pack_start(self._title_label, False, True, 0)

        self._title_entry = Gtk.Entry()
        self._title_entry.modify_bg(Gtk.StateType.INSENSITIVE, COLOR_BLACK)
        self._title_entry.connect('changed', self._title_changed)
        self._controls_hbox.pack_start(self._title_entry, expand=True,
                                       fill=True, padding=10)
        self._controls_hbox.show()

        height_tray = 150  # height of tray

        self._thumb_tray = HTray(hexpand=True, height_request=height_tray)
        self._thumb_tray.show()

        height = Gdk.Screen.height() - style.GRID_CELL_SIZE * 2 - \
            height_tray - trim_height_shutter_button
        self._media_view.set_size_request(-1, height)

        self._grid = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL)
        self._media_view.props.hexpand = True
        self._media_view.props.vexpand = True
        for row in [self._media_view, self._controls_hbox, self._thumb_tray]:
            self._grid.add(row)
        self._grid.modify_bg(Gtk.StateType.NORMAL, COLOR_BLACK)
        self._grid.show()
        self.set_canvas(self._grid)

    def set_title_visible(self, visible):
        self._grid.remove(self._controls_hbox)

        if visible:
            self._grid.attach_next_to(self._controls_hbox, self._media_view,
                                      Gtk.PositionType.TOP, 1, 1)
        else:
            self._grid.attach_next_to(self._controls_hbox, self._media_view,
                                      Gtk.PositionType.BOTTOM, 1, 1)

    def __switch_camera_click_cb(self, btn):
        self.model.switch_camera()

    def __mirror_toggled_cb(self, button):
        self.model.set_mirror(button.props.active)

    def serialize(self):
        data = {}

        data['timer'] = self._toolbar_controls.get_timer_idx()
        data['duration'] = self._toolbar_controls.get_duration_idx()
        data['quality'] = self._toolbar_controls.get_quality()

        return data

    def deserialize(self, data):
        self._toolbar_controls.set_timer_idx(data.get('timer', 0))
        self._toolbar_controls.set_duration_idx(data.get('duration', 0))
        self._toolbar_controls.set_quality(data.get('quality', 0))

    def _key_pressed(self, widget, event):
        key = event.keyval
        ctrl = event.state & Gdk.ModifierType.CONTROL_MASK

        # while activity toolbar is visible, only escape key is taken
        if self._activity_toolbar_button.is_expanded():
            if key == Gdk.KEY_Escape:
                self._activity_toolbar_button.set_expanded(False)
                return True

            return False

        # while title is focused, only escape key is taken
        if self._title_entry.is_focus():
            if key == Gdk.KEY_Escape:
                self.model.set_state(constants.STATE_READY)

            return False

        # while info tags are focused, only escape key is taken
        if self._media_view.info_view.textview.is_focus():
            if key == Gdk.KEY_Escape:
                self.model.set_state(constants.STATE_READY)

            return False

        if ctrl and key == Gdk.KEY_f:
            self._toggle_fullscreen()
            return True

        if ctrl and key == Gdk.KEY_s:
            self.model.glive.stop()
            return True

        if ctrl and key == Gdk.KEY_p:
            self.model.glive.play()
            return True

        if (ctrl and key == Gdk.KEY_space) or \
           (ctrl and key == Gdk.KEY_r) or \
           key == Gdk.KEY_KP_Page_Up:  # game key O

            if self._shutter_button.props.visible:
                if self._shutter_button.props.sensitive:
                    self._shutter_button.clicked()
            else:  # return to live mode
                self.model.set_state(constants.STATE_READY)
            return True

        if key == Gdk.KEY_space and self._active_recd:
            if self._active_recd.type in (constants.TYPE_VIDEO,
                                          constants.TYPE_AUDIO):
                self.model.play_pause()
                return True

        # if viewing media, return to live mode
        if key == Gdk.KEY_Escape and self._active_recd:
            self.model.set_state(constants.STATE_READY)
            return True

        if self.model.ui_frozen():
            return True

        if ctrl and key == Gdk.KEY_c:
            self._copy_to_clipboard(self._active_recd)
            return True

        if key == Gdk.KEY_i and self._active_recd:
            self._toggle_info()
            return True

        if key == Gdk.KEY_Escape and self._fullscreen:
            self._toggle_fullscreen()
            return True

        return False

    def _play_pause_clicked(self, widget):
        self.model.play_pause()

    def set_mode(self, mode):
        self._toolbar_controls.set_mode(mode)

    # can be called from GStreamer thread, so must not do any GTK+ stuff
    def set_glive_sink(self, sink):
        return self._media_view.set_video_sink(sink)

    # can be called from GStreamer thread, so must not do any GTK+ stuff
    def set_gplay_sink(self, sink):
        return self._media_view.set_video2_sink(sink)

    def get_selected_quality(self):
        return self._toolbar_controls.get_quality()

    def get_selected_timer(self):
        return self._toolbar_controls.get_timer()

    def get_selected_duration(self):
        return self._toolbar_controls.get_duration() * 60  # convert to secs

    def set_progress(self, value, text):
        self._progress.set_progress(value)
        self._progress.set_text(text)

    def set_countdown(self, value):
        if value == 0:
            self._shutter_button.show()
            self._countdown_image.hide()
            return

        self._shutter_button.hide()
        self._countdown_image.show()
        self._countdown_image.set_value(value)

    def _title_changed(self, widget):
        self._active_recd.setTitle(self._title_entry.get_text())

    def _media_view_media_clicked(self, widget):
        if self._play_button.props.visible and \
           self._play_button.props.sensitive:
            self._play_button.clicked()

    def _media_view_pip_clicked(self, widget):
        # clicking on the PIP always returns to live mode
        self.model.set_state(constants.STATE_READY)

    def _media_view_info_clicked(self, widget):
        self._toggle_info()

    def _toggle_info(self):
        recd = self._active_recd
        if not recd:
            return

        if self._showing_info:
            self._show_recd(recd, play=False)
            return

        self._showing_info = True
        still_modes = (constants.MODE_PHOTO, constants.MODE_AUDIO)
        if self.model.get_mode() in still_modes:
            func = self._media_view.show_info_photo
        else:
            func = self._media_view.show_info_video

        self._play_button.hide()
        self._progress.hide()
        self._playback_scale.hide()
        self._title_entry.set_text(recd.title)
        self._title_entry.show()
        self._title_label.show()
        self.set_title_visible(True)

        func(recd.recorderName, recd.colorStroke, recd.colorFill,
             utils.getDateString(recd.time), recd.tags)

    def _media_view_fullscreen_clicked(self, widget):
        # logger.debug('_media_view_fullscreen_clicked')
        self._toggle_fullscreen()

    def _media_view_tags_changed(self, widget, tbuffer):
        text = tbuffer.get_text(tbuffer.get_start_iter(),
                                tbuffer.get_end_iter(), True)
        self._active_recd.setTags(text)

    def _toggle_fullscreen(self):
        # logger.debug('_toggle_fullscreen')
        self._fullscreen = not self._fullscreen

        if not self._active_recd:
            self.model.glive.stop()

        if self._fullscreen:
            self.get_toolbar_box().hide()
            self._thumb_tray.hide()
            if self._active_recd:
                self._controls_hbox.hide()
        else:
            self.get_toolbar_box().show()
            self._thumb_tray.show()
            self._controls_hbox.show()

        self._media_view.set_fullscreen(self._fullscreen)

        if self._active_recd:
            return

        if self.model.get_state() == constants.STATE_RECORDING:
            return

        # hack, reason unknown
        # problem: call to self.mode.glive.play() does not show live view
        # solution: defer until after VideoBox resize is complete

        self._timer_hid = None

        def on_timer_cb():
            self.model.glive.play()
            self._timer_hid = None
            return False

        self._timer_hid = GLib.timeout_add(1000, on_timer_cb)

        def on_defer_cb():
            self.model.glive.play()
            if self._timer_hid:
                GLib.source_remove(self._timer_hid)
                self._timer_hid = None
            return False

        def on_event_cb(widget, event):
            if event.state == Gdk.VisibilityState.UNOBSCURED:
                GLib.timeout_add(30, on_defer_cb)
                self._media_view._video.disconnect_by_func(on_event_cb)

        self._media_view._video.add_events(
            Gdk.EventMask.VISIBILITY_NOTIFY_MASK)
        self._media_view._video.connect('visibility-notify-event', on_event_cb)

        # FIXME: fullscreen toggle during video recording gives black
        # window, TODO: do the same as above for the video recording
        # pipeline when it is active

    def _mode_button_clicked(self, button):
        self.model.change_mode(button.mode)

    def _shutter_clicked(self, arg):
        self.model.do_shutter()

    def set_shutter_sensitive(self, value):
        self._shutter_button.set_sensitive(value)

    def set_state(self, state):
        radio_state = (state == constants.STATE_READY)
        for item in (self._photo_button,
                     self._audio_button,
                     self._video_button):
            if item:
                item.set_sensitive(radio_state)

        self._showing_info = False
        if state == constants.STATE_READY:
            if self._state == constants.STATE_PROCESSING:
                self.unbusy()
            self._active_recd = None
            self._mirror_btn.props.sensitive = True
            self._title_entry.hide()
            self._title_label.hide()
            self.set_title_visible(False)
            self._play_button.hide()
            self._playback_scale.hide()
            self._progress.hide()
            self._controls_hbox.set_child_packing(self._shutter_button,
                                                  expand=True, fill=False,
                                                  padding=0,
                                                  pack_type=Gtk.PackType.START)
            self._shutter_button.set_normal()
            self._shutter_button.set_sensitive(True)
            self._shutter_button.show()
            self._media_view.show_live()
        elif state == constants.STATE_RECORDING:
            self._mirror_btn.props.sensitive = False
            self._shutter_button.set_recording()
            self._controls_hbox.set_child_packing(self._shutter_button,
                                                  expand=False, fill=False,
                                                  padding=0,
                                                  pack_type=Gtk.PackType.START)
            self._progress.show()
        elif state == constants.STATE_PROCESSING:
            self.busy()
            self._shutter_button.hide()
            self._progress.show()
        elif state == constants.STATE_DOWNLOADING:
            self._shutter_button.hide()
            self._progress.show()
        self._state = state

    def set_paused(self, value):
        if value:
            self._play_button.set_play()
        else:
            self._play_button.set_pause()

    def _thumbnail_clicked(self, button, recd):
        if self.model.ui_frozen():
            return

        self.model.abort_countdown()
        self.model.glive.stop()
        self._mirror_btn.props.sensitive = False
        self._active_recd = recd
        self._show_recd(recd)

    def add_thumbnail(self, recd):
        button = RecdButton(recd)
        clicked_handler = button.connect("clicked",
                                         self._thumbnail_clicked, recd)
        remove_handler = button.connect("remove-requested",
                                        self._remove_recd)
        clipboard_handler = button.connect("copy-clipboard-requested",
                                           self._thumbnail_copy_clipboard)
        button.handler_ids = (clicked_handler, remove_handler,
                              clipboard_handler)
        button.show()
        self._thumb_tray.add_item(button)
        self._thumb_tray.scroll_to_item(button)
        # FIXME: possible toolkit bug; scroll_to_item is ineffective,
        # only noticed when the tray is full

    def _copy_to_clipboard(self, recd):
        if recd is None:
            return
        if not recd.isClipboardCopyable():
            return

        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
        clipboard.set_image(recd.getCopyClipboardPixbuf())

    def _thumbnail_copy_clipboard(self, recdbutton):
        self._copy_to_clipboard(recdbutton.get_recd())

    def _remove_recd(self, recdbutton):
        recd = recdbutton.get_recd()
        self.model.delete_recd(recd)
        if self._active_recd == recd:
            self.model.set_state(constants.STATE_READY)

        self._remove_thumbnail(recdbutton)

    def _remove_thumbnail(self, recdbutton):
        for handler in recdbutton.handler_ids:
            recdbutton.disconnect(handler)

        self._thumb_tray.remove_item(recdbutton)
        recdbutton.cleanup()

    def show_still(self, pixbuf):
        self._media_view.show_still(pixbuf)

    def _show_photo(self, recd):
        path = self._get_photo_path(recd)
        self._media_view.show_photo(path)
        self._title_entry.set_text(recd.title)
        self._title_entry.show()
        self._title_label.show()
        self.set_title_visible(True)
        self._shutter_button.hide()
        self._progress.hide()

    def _show_audio(self, recd, play):
        self._progress.hide()
        self._shutter_button.hide()
        self._title_entry.hide()
        self._title_label.hide()
        self.set_title_visible(False)
        self._play_button.show()
        self._playback_scale.show()
        path = recd.getAudioImageFilepath()
        self._media_view.show_photo(path)
        if play:
            self.model.play_audio(recd)

    def _show_video(self, recd, play):
        self._progress.hide()
        self._shutter_button.hide()
        self._title_entry.hide()
        self._title_label.hide()
        self.set_title_visible(False)
        self._play_button.show()
        self._playback_scale.show()
        self._media_view.show_video()
        if play:
            self.model.play_video(recd)

    def set_playback_scale(self, value):
        self._playback_scale.set_value(value)

    def _get_photo_path(self, recd):
        # FIXME should live (partially) in recd?

        # downloading = self.ca.requestMeshDownload(recd)
        # self.MESHING = downloading

        if True:  # not downloading:
            # self.progressWindow.updateProgress(0, "")
            return recd.getMediaFilepath()

        # maybe it is not downloaded from the mesh yet...
        # but we can show the low res thumb in the interim
        return recd.getThumbFilepath()

    def _show_recd(self, recd, play=True):
        self._showing_info = False

        if recd.buddy and not recd.downloadedFromBuddy:
            self.model.request_download(recd)
        elif recd.type == constants.TYPE_PHOTO:
            self._show_photo(recd)
        elif recd.type == constants.TYPE_AUDIO:
            self._show_audio(recd, play)
        elif recd.type == constants.TYPE_VIDEO:
            self._show_video(recd, play)

    def remote_recd_available(self, recd):
        self.model.set_state(constants.STATE_INVISIBLE)
        if recd == self._active_recd:
            self._show_recd(recd)

    def update_download_progress(self, recd):
        if recd != self._active_recd:
            return

        if not recd.meshDownloading:
            msg = _('Download failed.')
        elif recd.meshDownloadingProgress:
            msg = _('Downloading...')
        else:
            msg = _('Requesting...')

        self.set_progress(recd.meshDownlodingPercent, msg)
Ejemplo n.º 35
0
    def __init__(self, abiword_canvas):
        GObject.GObject.__init__(self)

        self.font_name_combo = FontComboBox()
        self.font_name_combo.set_font_name('Sans')
        self._fonts_changed_id = self.font_name_combo.connect(
            'changed', self._font_changed_cb, abiword_canvas)
        self._abi_handler = abiword_canvas.connect('font-family',
                                                   self._font_family_cb)
        self.insert(ToolComboBox(self.font_name_combo), -1)

        self.font_size = FontSize()
        self._abi_handler = abiword_canvas.connect('font-size',
                                                   self._font_size_cb)
        self._changed_id = self.font_size.connect(
            'changed', self._font_size_changed_cb, abiword_canvas)
        self.insert(self.font_size, -1)

        bold = ToggleToolButton('format-text-bold')
        bold.set_tooltip(_('Bold'))
        bold.props.accelerator = '<Ctrl>B'
        bold_id = bold.connect('clicked', lambda sender:
                               abiword_canvas.toggle_bold())
        abiword_canvas.connect('bold', lambda abi, b:
                               self._setToggleButtonState(bold, b, bold_id))
        self.insert(bold, -1)

        italic = ToggleToolButton('format-text-italic')
        italic.set_tooltip(_('Italic'))
        italic.props.accelerator = '<Ctrl>I'
        italic_id = italic.connect('clicked', lambda sender:
                                   abiword_canvas.toggle_italic())
        abiword_canvas.connect('italic', lambda abi, b:
                               self._setToggleButtonState(italic, b,
                                                          italic_id))
        self.insert(italic, -1)

        underline = ToggleToolButton('format-text-underline')
        underline.set_tooltip(_('Underline'))
        underline.props.accelerator = '<Ctrl>U'
        underline_id = underline.connect('clicked', lambda sender:
                                         abiword_canvas.toggle_underline())
        abiword_canvas.connect('underline', lambda abi, b:
                               self._setToggleButtonState(underline, b,
                                                          underline_id))
        self.insert(underline, -1)

        color = ColorToolButton()
        color.connect('notify::color', self._text_color_cb,
                      abiword_canvas)
        tool_item = Gtk.ToolItem()
        tool_item.add(color)
        self.insert(tool_item, -1)
        abiword_canvas.connect(
            'color', lambda abi, r, g, b:
            color.set_color(Gdk.Color(r * 256, g * 256, b * 256)))

        # MAGIC NUMBER WARNING: Secondary toolbars are not a standard height?
        self.set_size_request(-1, style.GRID_CELL_SIZE)

        def append_align(icon_name, tooltip, do_abi_cb, style_name, button,
                         menu_box):
            menu_item = AbiMenuItem(abiword_canvas, style_name, do_abi_cb,
                                    icon_name, tooltip, button)
            menu_box.append_item(menu_item)
            menu_item.show()

        self._aligment_btn = ToolButton(icon_name='format-justify-left')
        self._aligment_btn.props.tooltip = _('Choose alignment')
        self._aligment_btn.props.hide_tooltip_on_click = False
        self._aligment_btn.palette_invoker.props.toggle_palette = True

        menu_box = PaletteMenuBox()
        self._aligment_btn.props.palette.set_content(menu_box)
        menu_box.show()

        append_align('format-justify-left', _('Left justify'),
                     abiword_canvas.align_left, 'left-align',
                     self._aligment_btn, menu_box)

        append_align('format-justify-center', _('Center justify'),
                     abiword_canvas.align_center, 'center-align',
                     self._aligment_btn, menu_box)

        append_align('format-justify-right', _('Right justify'),
                     abiword_canvas.align_right, 'right-align',
                     self._aligment_btn, menu_box)

        append_align('format-justify-fill', _('Fill justify'),
                     abiword_canvas.align_justify, 'justify-align',
                     self._aligment_btn, menu_box)

        self.insert(self._aligment_btn, -1)

        self.show_all()
Ejemplo n.º 36
0
class CardEditor(Gtk.EventBox):

    __gsignals__ = {
        'has-text': (GObject.SignalFlags.RUN_FIRST, None,
                     [GObject.TYPE_PYOBJECT]),
        'has-picture': (GObject.SignalFlags.RUN_FIRST, None,
                        [GObject.TYPE_PYOBJECT]),
        'has-sound': (GObject.SignalFlags.RUN_FIRST, None,
                      [GObject.TYPE_PYOBJECT]),
        'change-font': (GObject.SignalFlags.RUN_FIRST, None,
                        [GObject.TYPE_PYOBJECT]),
    }

    def __init__(self, game, editor_index):
        Gtk.EventBox.__init__(self)
        self._game = game
        self.snd = None
        self.editor_index = editor_index
        self.temp_folder = None

        box = Gtk.Grid()
        box.set_column_spacing(style.DEFAULT_SPACING)
        box.set_row_spacing(style.DEFAULT_SPACING)
        box.props.margin = style.DEFAULT_SPACING

        self.card = Card(
            -1, {'front_text': {'card_text': '',
                                'text_color': style.Color('#ffffff')}},
            None, PAIR_SIZE, '#c0c0c0')
        self.card.flip()
        card_align = Gtk.Alignment.new(.5, .5, 0, 0)
        card_align.add(self.card)
        box.attach(card_align, 0, 0, 1, 1)

        self.textentry = Gtk.Entry()
        self.textentry.connect('changed', self.update_text)
        self.textentry.set_valign(Gtk.Align.START)
        box.attach(self.textentry, 0, 1, 1, 1)

        toolbar = Gtk.VBox()
        toolbar.set_valign(Gtk.Align.CENTER)

        browsepicture = ToolButton(icon_name='import_picture',
                                   tooltip=_('Insert picture'))
        toolbar.add(browsepicture)

        browsesound = ToolButton(icon_name='import_sound',
                                 tooltip=_('Insert sound'))
        toolbar.add(browsesound)

        browsepicture.connect('clicked', self._load_image)
        browsesound.connect('clicked', self._load_audio)

        self.usespeak = ToggleToolButton(icon_name='speak')
        self.usespeak.set_palette(SpeakPalette(self))
        toolbar.add(self.usespeak)
        self.usespeak.connect('toggled', self._usespeak_cb)

        self.fontbutton = FontButton()
        toolbar.add(self.fontbutton)
        self.id_font_changed = self.fontbutton.connect(
            'changed', self.__font_changed_cb)
        box.attach(toolbar, 1, 0, 1, 2)

        self.add(box)

    def __font_changed_cb(self, widget):
        font = widget.get_font_name()
        if font:
            self.card.change_font(font)
            self.emit('change-font', font)

    def set_font_name(self, font_name):
        self.fontbutton.handler_block(self.id_font_changed)
        self.fontbutton.set_font_name(font_name)
        self.fontbutton.handler_unblock(self.id_font_changed)

    def update_text(self, entry):
        self.card.change_text(entry.get_text())
        if len(entry.get_text()) == 0:
            self.emit('has-text', False)
        else:
            self.emit('has-text', True)

    def get_text(self):
        return self.textentry.get_text()

    def set_text(self, newtext):
        if newtext is None:
            newtext = ''
        self.textentry.set_text(newtext)

    def get_speak(self):
        if self.usespeak is None:
            return None
        if self.usespeak.props.active:
            return self.usespeak.palette.face.status.voice.language

    def set_speak(self, value):
        if self.usespeak is None:
            return
        if value is None:
            self.usespeak.props.active = False
        else:
            try:
                self.usespeak.handler_block_by_func(self._usespeak_cb)
                self.usespeak.props.active = True
            finally:
                self.usespeak.handler_unblock_by_func(self._usespeak_cb)
            self.usespeak.palette.voices.resume(value)

    def get_image_path(self):
        return self.card.get_image_path()

    def set_image_path(self, image_path):
        self.card.set_image_path(image_path)
        self.emit('has-picture', True)

    def _load_image(self, widget):
        def load(jobject):
            origin_path = jobject.file_path
            self._game.model.mark_modified()
            self._game.model.create_temp_directories()
            destination_path = join(self._game.model.data['pathimg'],
                                    basename(origin_path))
            shutil.copy(origin_path, destination_path)
            self.set_speak(None)
            self.card.set_image_path(destination_path)
            logging.debug('Picture Loaded: %s', destination_path)
            self.emit('has-picture', True)

        chooser.pick(parent=self.get_toplevel(),
                     what=chooser.IMAGE,
                     cb=load)

    def _load_audio(self, widget):
        def load(jobject):
            origin_path = jobject.file_path
            self.set_speak(None)
            self._game.model.mark_modified()
            self._game.model.create_temp_directories()
            destination_path = join(self._game.model.data['pathsnd'],
                                    basename(origin_path))
            shutil.copy(origin_path, destination_path)
            self.set_snd(destination_path)
            logging.debug('Audio Loaded: %s', destination_path)

            # add a icon too
            sound_icon_path = join(activity.get_bundle_path(),
                                   'icons/sound.svg')
            destination_path = join(self._game.model.data['pathimg'],
                                    'sound.svg')
            shutil.copy(sound_icon_path, destination_path)

            self.card.set_image_path(destination_path)
            self.emit('has-sound', True)

        chooser.pick(parent=self.get_toplevel(),
                     what=chooser.AUDIO,
                     cb=load)

    def _usespeak_cb(self, button):
        self.card.change_speak(button.props.active)

        if not button.props.active:
            self.usespeak.palette.face.shut_up()
            return

        self.snd = None
        self.emit('has-sound', False)
        self.emit('has-picture', False)

        button.palette.face.say(self.get_text())

    def set_snd(self, snd):
        self.snd = snd

    def get_snd(self):
        return self.snd

    def get_font_name(self):
        return self.fontbutton.get_font_name()

    def clean(self):
        self.textentry.set_text('')
        self.card.set_image_path(None)
        self.snd = None
        self.emit('has-text', False)
        self.emit('has-picture', False)
        self.emit('has-sound', False)
        if self.usespeak is not None and self.usespeak.palette is not None:
            self.usespeak.props.active = False
            self.usespeak.palette.face.shut_up()
Ejemplo n.º 37
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)
Ejemplo n.º 38
0
    def make_toolbar(self):
        def make_separator(toolbar, expand=True):
            separator = Gtk.SeparatorToolItem()
            separator.props.draw = not expand
            separator.set_expand(expand)
            toolbar.insert(separator, -1)

        toolbar_box = ToolbarBox()
        toolbar = toolbar_box.toolbar

        activity_button = ToolButton()
        activity_button.set_icon_widget(ActivityIcon(None))
        toolbar.insert(activity_button, -1)

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

        toolbar_file = Gtk.Toolbar()
        boton_toolbar_file = ToolbarButton(page=toolbar_file, icon_name='txt')
        toolbar.add(boton_toolbar_file)

        toolbar_edit = EditToolbar()
        button_toolbar_edit = ToolbarButton(page=toolbar_edit,
                                            icon_name='toolbar-edit')
        toolbar.insert(button_toolbar_edit, -1)

        toolbar_view = Gtk.Toolbar()
        boton_toolbar_view = ToolbarButton(page=toolbar_view,
                                           icon_name='toolbar-view')
        toolbar.insert(boton_toolbar_view, -1)

        self.button_undo = toolbar_edit.undo
        self.button_undo.props.accelerator = '<Ctrl>Z'
        self.button_undo.set_sensitive(False)
        toolbar_edit.undo.connect('clicked', self.undo)

        self.button_redo = toolbar_edit.redo
        self.button_redo.props.accelerator = '<Ctrl><Mayus>Z'
        self.button_redo.set_sensitive(False)
        self.button_redo.connect('clicked', self.redo)

        self.entry_search = IconEntry()
        item_entry = Gtk.ToolItem()
        self.entry_search.set_size_request(250, -1)
        self.entry_search.set_placeholder_text('Search...')
        self.entry_search.set_icon_from_name(Gtk.EntryIconPosition.SECONDARY,
                                             'search')
        self.entry_search.connect('changed', self.search_text)
        self.entry_search.connect('activate', self.search_text, True)
        item_entry.add(self.entry_search)
        toolbar_edit.insert(item_entry, -1)

        self.entry_replace = IconEntry()
        item_entry = Gtk.ToolItem()
        self.entry_replace.set_size_request(250, -1)
        self.entry_replace.set_placeholder_text('Replace...')
        self.entry_replace.connect('activate', self.replace_text)
        item_entry.add(self.entry_replace)
        toolbar_edit.insert(item_entry, -1)

        button_new = ToolButton('new-file')
        button_new.props.accelerator = '<Ctrl>N'
        button_new.connect('clicked', lambda w: self.new_page())
        button_new.set_tooltip(_('New file'))
        toolbar_file.insert(button_new, -1)

        button_open = ToolButton('fileopen')
        button_open.props.accelerator = '<Ctrl>O'
        button_open.set_tooltip(_('Open file from file system'))
        button_open.connect('clicked', self.file_chooser_open)
        toolbar_file.insert(button_open, -1)

        self.button_save = ToolButton('filesave')
        self.button_save.props.accelerator = '<Ctrl>S'
        self.button_save.set_tooltip(_('Save file to the file system'))
        self.button_save.connect('clicked', self.file_chooser_save)
        toolbar_file.insert(self.button_save, -1)

        button_save_as = ToolButton('save-as')
        button_save_as.props.accelerator = '<Ctrl><Mayus>S'
        button_save_as.set_tooltip(_('Save as file to the file system'))
        button_save_as.connect('clicked', self.file_chooser_save, True)
        toolbar_file.insert(button_save_as, -1)

        make_separator(toolbar_file, False)

        button_print = ToolButton('printer')
        button_print.props.accelerator = '<Ctrl>I'
        button_print.set_tooltip(_('Print file'))
        button_print.connect('clicked', self.print_file)
        toolbar_file.insert(button_print, -1)

        make_separator(toolbar_edit, False)

        button_clock = ToolButton('clock')
        button_clock.props.accelerator = '<Ctrl>T'
        button_clock.set_tooltip(_('Insert date and time'))
        button_clock.connect('clicked', self.insert_date_and_time)
        toolbar_edit.insert(button_clock, -1)

        button_wrap_none = Gtk.RadioToolButton()
        button_wrap_none.set_icon_name('wrap-none')
        button_wrap_none.connect("toggled", self.wrap_mode_changed, 'none')
        toolbar_view.insert(button_wrap_none, -1)

        button_wrap_char = Gtk.RadioToolButton.new_from_widget(
            button_wrap_none)
        button_wrap_char.set_icon_name('format-justify-fill')
        button_wrap_char.connect("toggled", self.wrap_mode_changed, 'char')
        toolbar_view.insert(button_wrap_char, -1)

        button_wrap_word = Gtk.RadioToolButton.new_from_widget(
            button_wrap_none)
        button_wrap_word.set_icon_name('format-justify-left')
        button_wrap_word.connect("toggled", self.wrap_mode_changed, 'word')
        toolbar_view.insert(button_wrap_word, -1)

        if self.conf['wrap-mode'] == 'none':
            button_wrap_none.set_active(True)

        elif self.conf['wrap-mode'] == 'char':
            button_wrap_none.set_active(True)

        elif self.conf['wrap-mode'] == 'word':
            button_wrap_none.set_active(True)

        make_separator(toolbar_view, False)

        item_font_size = FontSize()
        item_font_size.set_font_size(self.conf['font-size'])
        item_font_size.connect('changed', self.font_size_changed)
        toolbar_view.insert(item_font_size, -1)

        combo_font = FontComboBox(self.conf['font'])
        combo_font.connect('changed', self.font_changed)
        toolbar_view.insert(combo_font, -1)

        make_separator(toolbar_view, False)

        button_numbers = ToggleToolButton('show-numbers')
        button_numbers.props.accelerator = '<Ctrl><Mayus>N'
        button_numbers.set_tooltip(_('Show line numbers'))
        button_numbers.set_active(self.conf['show-line-numbers'])
        button_numbers.connect('toggled', self.show_numbers_changed)
        toolbar_view.insert(button_numbers, -1)

        button_right_line = ToggleToolButton('show-right-line')
        button_right_line.props.accelerator = '<Ctrl>L'
        button_right_line.set_tooltip(_('Show a line in a specific position'))
        button_right_line.set_active(self.conf['show-right-line'])
        button_right_line.connect('toggled', self.show_right_line_changed)
        toolbar_view.insert(button_right_line, -1)

        self.spinner_right_line = Spinner(self.conf['right-line-pos'], 1, 150)
        self.spinner_right_line.set_sensitive(self.conf['show-right-line'])
        self.spinner_right_line.connect('value-changed',
                                        self.right_line_pos_changed)
        toolbar_view.insert(self.spinner_right_line, -1)

        make_separator(toolbar_view, False)

        combo_styles = ComboStyles(self.conf['theme'])
        combo_styles.connect('theme-changed', self.theme_changed)
        toolbar_view.insert(combo_styles, -1)

        make_separator(toolbar, True)

        button_stop = ToolButton('activity-stop')
        button_stop.props.accelerator = '<Ctrl>Q'
        button_stop.connect('clicked', self._exit)
        toolbar.insert(button_stop, -1)

        toolbar_file.show_all()
        toolbar_edit.show_all()
        toolbar_view.show_all()

        toolbar_edit.copy.hide()
        toolbar_edit.paste.hide()

        self.set_toolbar_box(toolbar_box)
Ejemplo n.º 39
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)
        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
Ejemplo n.º 40
0
class ClockActivity(activity.Activity):
    """The clock activity displays a simple clock widget.
    """

    def __init__(self, handle):
        """Create and initialize the clock activity.
        """
        super(ClockActivity, self).__init__(handle)

        # TRANS: Title of the activity
        self.set_title(_('What Time Is It?'))

        # TRANS: The format used when writing the time in full
        # letters.  You must take care to use a font size large enough
        # so that kids can read it easily, but also small enough so
        # that all times combination fit on the screen, even when the
        # screen is rotated.  Pango markup:
        # http://www.pyGtk.org/docs/pyGtk/pango-markup-language.html
        self._TIME_LETTERS_FORMAT = _('<markup>\
<span lang="en" font_desc="Sans 20">%s</span></markup>')

        # TRANS: The format used to display the weekday and date
        # (example: Tuesday 10/21/2008) We recommend to use the same
        # font size as for the time display.  See
        # http://docs.python.org/lib/module-time.html for available
        # strftime formats.  xgettext:no-python-format
        self._DATE_SHORT_FORMAT = _('<markup>\
<span lang="en" font_desc="Sans 20">\
<span foreground="#B20008">%A</span>, \
<span foreground="#5E008C">%m</span>/\
<span foreground="#B20008">%d</span>/\
<span foreground="#9A5200">%Y</span></span></markup>')

        # Should we write the time in full letters?
        self._time_writer = None
        self._time_in_letters = self.get_title()
        self._time_letters = None
        self._date = None
        self._time_speaker = None

        if 'clock-mode' not in self.metadata.keys():
            self.metadata['clock-mode'] = _MODE_SIMPLE_CLOCK
        else:
            self.metadata['clock-mode'] = int(self.metadata['clock-mode'])

        if 'write-time' in self.metadata.keys():
            self._write_time = bool(self.metadata['write-time'])
        else:
            self._write_time = False

        if 'speak-time' in self.metadata.keys():
            self._speak_time = bool(self.metadata['speak-time'])
        else:
            self._speak_time = False

        if 'write-date' in self.metadata.keys():
            self._write_date = bool(self.metadata['write-date'])
        else:
            self._write_date = False

        self._make_display()
        self._make_toolbars()

        # Show the activity on the screen
        self.show_all()

        # We want to be notified when the minutes change
        self._clock.connect("time_minute", self._minutes_changed_cb)

        if not self.powerd_running():
            try:
                bus = dbus.SystemBus()
                proxy = bus.get_object('org.freedesktop.ohm',
                                       '/org/freedesktop/ohm/Keystore')
                self.ohm_keystore = dbus.Interface(
                    proxy, 'org.freedesktop.ohm.Keystore')
            except dbus.DBusException:
                self.ohm_keystore = None

    def write_file(self, file_path):
        self.metadata['write-time'] = 'True' if self._write_time else ''
        self.metadata['write-date'] = 'True' if self._write_date else ''
        self.metadata['speak-time'] = 'True' if self._speak_time else ''
        self.metadata['clock-mode'] = str(self._clock._mode)

    def powerd_running(self):
        self.using_powerd = os.access(POWERD_INHIBIT_DIR, os.W_OK)
        return self.using_powerd

    def _inhibit_suspend(self):
        if self.using_powerd:
            fd = open(POWERD_INHIBIT_DIR + "/%u" % os.getpid(), 'w')
            fd.close()
            return True

        if self.ohm_keystore is not None:
            try:
                self.ohm_keystore.SetKey('suspend.inhibit', 1)
                return self.ohm_keystore.GetKey('suspend.inhibit')
            except dbus.exceptions.DBusException:
                return False
        else:
            return False

    def _allow_suspend(self):
        if self.using_powerd:
            os.unlink(POWERD_INHIBIT_DIR + "/%u" % os.getpid())
            return True

        if self.ohm_keystore is not None:
            try:
                self.ohm_keystore.SetKey('suspend.inhibit', 0)
                return self.ohm_keystore.GetKey('suspend.inhibit')
            except dbus.exceptions.DBusException:
                return False
        else:
            return False

    def _make_toolbars(self):
        """Prepare and set the toolbars of the activity.

        Load and show icons. Associate them to the call back methods.
        """
        self.max_participants = 1
        toolbar_box = ToolbarBox()
        activity_button = ActivityToolbarButton(self)
        activity_button.show()
        toolbar_box.toolbar.insert(activity_button, 0)

        self._add_clock_controls(toolbar_box.toolbar)

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

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

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show_all()
        return toolbar_box

    def _add_clock_controls(self, display_toolbar):

        # First group of radio button to select the type of clock to display
        button1 = RadioToolButton(icon_name="simple-clock")
        button1.set_tooltip(_('Simple Clock'))
        button1.connect("toggled", self._display_mode_changed_cb,
                        _MODE_SIMPLE_CLOCK)
        display_toolbar.insert(button1, -1)
        button2 = RadioToolButton(icon_name="nice-clock",
                                  group=button1)
        button2.set_tooltip(_('Nice Clock'))
        button2.connect("toggled", self._display_mode_changed_cb,
                        _MODE_NICE_CLOCK)
        display_toolbar.insert(button2, -1)
        button3 = RadioToolButton(icon_name="digital-clock",
                                  group=button1)
        button3.set_tooltip(_('Digital Clock'))
        button3.connect("toggled", self._display_mode_changed_cb,
                        _MODE_DIGITAL_CLOCK)
        display_toolbar.insert(button3, -1)

        # A separator between the two groups of buttons
        separator = Gtk.SeparatorToolItem()
        separator.set_draw(True)
        display_toolbar.insert(separator, -1)

        # Now the options buttons to display other elements: date, day
        # of week...  A button in the toolbar to write the time in
        # full letters
        button = ToggleToolButton("write-time")
        button.set_tooltip(_('Display time in full letters'))
        button.connect("toggled", self._write_time_clicked_cb)
        display_toolbar.insert(button, -1)

        # The button to display the weekday and date
        button = ToggleToolButton("write-date")
        button.set_tooltip(_('Display weekday and date'))
        button.connect("toggled", self._write_date_clicked_cb)
        display_toolbar.insert(button, -1)

        # Another button to speak aloud the time
        button = ToggleToolButton("microphone")
        button.set_tooltip(_('Talking clock'))
        button.connect("toggled", self._speak_time_clicked_cb)
        display_toolbar.insert(button, -1)

        # A separator between the two groups of buttons
        separator = Gtk.SeparatorToolItem()
        separator.set_draw(True)
        display_toolbar.insert(separator, -1)

        # And another button to toggle grabbing the hands
        self._grab_button = ToggleToolButton("grab")
        self._grab_button.set_tooltip(_('Grab the hands'))
        self._grab_button.connect("toggled", self._grab_clicked_cb)
        display_toolbar.insert(self._grab_button, -1)

    def _make_display(self):
        """Prepare the display of the clock.

        The display has two parts: the clock face at the top, and the
        time in full letters at the bottom, when the user selects to
        show it.
        """
        # The clock face
        self._clock = ClockFace()

        # The label to print the time in full letters
        self._time_letters = Gtk.Label()
        self._time_letters.set_no_show_all(True)
        # Following line in ineffective!
        # self._time_letters.set_line_wrap(True)
        # Resize the invisible label so that Gtk will know in advance
        # the height when we show it.
        self._time_letters.set_markup(
            self._TIME_LETTERS_FORMAT % self._time_in_letters)

        # The label to write the date
        self._date = Gtk.Label()
        self._date.set_no_show_all(True)
        self._date.set_markup(
            self._clock.get_time().strftime(self._DATE_SHORT_FORMAT))

        # Put all these widgets in a vertical box
        vbox = Gtk.VBox()
        vbox.pack_start(self._clock, True, True, 0)
        vbox.pack_start(self._time_letters, False, False, 0)
        vbox.pack_start(self._date, False, False, 0)

        # Attach the display to the activity
        self.set_canvas(vbox)

    def _write_date_clicked_cb(self, button):
        """The user clicked on the "write date" button to display the
        current weekday and date.
        """
        if button.get_active():
            self._date.show()
        else:
            self._date.hide()

    def _display_mode_changed_cb(self, radiobutton, display_mode):
        """The user selected a clock display mode (simple clock, nice
        or digital).
        """
        self._clock.set_display_mode(display_mode)
        self._clock.queue_draw()

        is_digital = display_mode == _MODE_DIGITAL_CLOCK

        # Exit grab hands mode if the clock is digital
        if self._clock.grab_hands_mode and is_digital:
            self._grab_button.set_active(False)

        # The hands can't be grabbed in the digital clock mode
        self._grab_button.props.sensitive = not is_digital

    def _write_time_clicked_cb(self, button):
        """The user clicked on the "write time" button to print the
        current time.
        """
        self._write_time = button.get_active()
        if self._write_time:
            self._time_letters.show()
            self._write_and_speak(False)
        else:
            self._time_letters.hide()

    def _speak_time_clicked_cb(self, button):
        """The user clicked on the "speak time" button to hear the
        talking clock.
        """
        self._speak_time = button.get_active()
        if self._speak_time:
            self._write_and_speak(True)

    def _grab_clicked_cb(self, button):
        """The user clicked on the "grab hands" button to toggle
        grabbing the hands.
        """
        self._clock.change_grab_hands_mode(button.get_active())

    def _minutes_changed_cb(self, clock):
        """Minutes have changed on the clock face: we have to update
        the display of the time in full letters if the user has chosen
        to have it and eventually croak the time.
        """
        # Change time display and talk, if necessary
        self._write_and_speak(True)

        # Update the weekday and date in case it was midnight
        self._date.set_markup(
            clock.get_time().strftime(self._DATE_SHORT_FORMAT))

    def _notify_active_cb(self, widget, event):
        """Sugar notify us that the activity is becoming active or
        inactive.

        When we are inactive, we change the activity status of the
        clock face widget, so that it can stop updating every seconds.
        """
        self._clock.active = self.props.active
        if self.props.active:
            self._inhibit_suspend()
        else:
            self._allow_suspend()

    def _write_and_speak(self, speak):
        """
        Write and speak the time (called in another thread not to
        block the clock).
        """
        # A helper function for the running thread
        def thread_write_and_speak():
            # Only update the time in full letters when necessary
            if self._write_time or self._speak_time:
                self._do_write_time()

            # And if requested, say it aloud
            if self._speak_time and speak:
                self._do_speak_time()

        # Now detach a thread to do the big job
        thread = threading.Thread(target=thread_write_and_speak)
        thread.start()

    def _do_write_time(self):
        """Translate the time to full letters.
        """
        if self._time_writer is None:
            self._time_writer = TimeWriter()
        hour = self._clock.get_time().hour
        minute = self._clock.get_time().minute
        self._time_in_letters = self._time_writer.write_time(hour, minute)
        self._time_letters.set_markup(
            self._TIME_LETTERS_FORMAT % self._time_in_letters)

    def _do_speak_time(self):
        """Speak aloud the current time.
        """

        def gstmessage_cb(bus, message, pipe):
            if message.type in (Gst.MessageType.EOS, Gst.MessageType.ERROR):
                pipe.set_state(Gst.State.NULL)

        if self._time_speaker is None:
            self._time_speaker = Speaker()

        pipeline = 'espeak text="%(text)s" voice="%(voice)s" pitch="%(pitch)s" \
            rate="%(rate)s" gap="%(gap)s" ! autoaudiosink' % {
            'text': self._untag(self._time_in_letters),
            'voice': self._time_speaker.VOICE,
            'pitch': self._time_speaker.PITCH,
            'rate': self._time_speaker.SPEED,
            'gap': self._time_speaker.WORD_GAP}
        try:
            pipe = Gst.parse_launch(pipeline)
            bus = pipe.get_bus()
            bus.add_signal_watch()
            bus.connect('message', gstmessage_cb, pipe)
            pipe.set_state(Gst.State.PLAYING)
        except:
            self._time_speaker.speak(self._untag(self._time_in_letters))

    def _untag(self, text):
        """Remove all the tags (pango markup) from a text.
        """
        if text is False or "<" not in text:
            return text
        else:
            result = ""
            for s in re.findall(r"(<.*?>)|([^<>]+)", text):
                result += s[1]
            return result
Ejemplo n.º 41
0
class FileChooserOpen(Gtk.Window):

    __gsignals__ = {'open-file': (GObject.SIGNAL_RUN_FIRST, None, [str])}

    def __init__(self, activity, folder=None):
        Gtk.Window.__init__(self)

        self._activity = activity
        self.vbox = Gtk.VBox()
        self.view = Gtk.IconView()
        self.model = Gtk.ListStore(str, GdkPixbuf.Pixbuf)

        self.folder = folder or os.path.expanduser('~/')
        self.files = []
        self.show_hidden_files = False

        if os.path.isfile(self.folder):
            self.folder = self.go_up(self.folder, _return=True)

        self.set_modal(True)
        self.set_decorated(False)
        self.set_resizable(False)
        self.set_size_request(WIDTH, HEIGHT)
        self.set_border_width(style.LINE_WIDTH)
        self.add_events(Gdk.EventMask.KEY_RELEASE_MASK)
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        self.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color())
        self.view.set_model(self.model)
        self.view.set_selection_mode(Gtk.SelectionMode.MULTIPLE)
        self.view.set_text_column(0)
        self.view.set_pixbuf_column(1)

        self.connect('key-release-event', self.__key_release_event_cb)
        self.view.connect('selection-changed', self.__selection_changed)
        self.view.connect('button-press-event', self.__button_press_event_cb)

        scrolled = Gtk.ScrolledWindow()
        scrolled.add(self.view)

        self.__make_toolbar()
        self.show_folder()

        self.vbox.pack_end(scrolled, True, True, 0)
        self.add(self.vbox)
        self.show_all()

        GObject.timeout_add(500, self.check_files)

    def __make_toolbar(self):
        self.toolbar = Gtk.Toolbar()
        self.toolbar.modify_bg(Gtk.StateType.NORMAL,
                               style.COLOR_TOOLBAR_GREY.get_gdk_color())

        self.go_up_button = ToolButton(icon_name='go-up')
        self.go_up_button.props.accelerator = '<Alt>S'
        self.go_up_button.set_tooltip(_('Go to pather directory'))
        self.go_up_button.connect('clicked', self.go_up)
        self.toolbar.insert(self.go_up_button, -1)

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

        self.hidden_files_button = ToggleToolButton('show-hidden-files')
        self.hidden_files_button.props.accelerator = '<Ctrl>H'
        self.hidden_files_button.set_tooltip(_('Show hidden files'))
        self.hidden_files_button.connect('clicked', self.__show_hidden_files)
        self.toolbar.insert(self.hidden_files_button, -1)

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

        item = Gtk.ToolItem()
        self.entry = Gtk.Entry()
        self.entry.set_size_request(300, -1)
        self.entry.set_text(self.folder)
        self.entry.connect('activate', self.__open_path_from_entry)
        item.add(self.entry)
        self.toolbar.insert(item, -1)

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

        self.button_open = ToolButton(icon_name='fileopen')
        self.button_open.set_tooltip(_('Open selected file'))
        self.button_open.set_sensitive(False)
        self.button_open.connect('clicked', self.__open_path)
        self.toolbar.insert(self.button_open, -1)

        self.close_button = ToolButton(icon_name='dialog-cancel')
        self.close_button.connect('clicked', self.close)
        self.toolbar.insert(self.close_button, -1)

        self.vbox.pack_start(self.toolbar, False, False, 0)

    def __key_release_event_cb(self, widget, event):
        if event.keyval == 65293:  # Enter
            self.__open_path()

    def go_up(self, button=None, _return=False):
        path = '/'
        folders = []

        if self.folder == '/':
            return

        for folder in self.folder.split('/'):
            if not folder:
                continue
            folders.append(folder)

        if not folders:
            return

        for folder in folders[:-1]:
            if folder:
                path += folder + '/'

        if not _return:
            self.folder = path
            self.check_files()
        else:
            return path

    def __show_hidden_files(self, button):
        self.show_hidden_files = button.get_active()
        self.show_folder()

    def __open_path(self, button=None):
        if len(self.view.get_selected_items()) == 1:
            if os.path.isdir(self.selected_path):
                self.folder = self.selected_path
                self.selected_path = None

            elif os.path.isfile(self.selected_path):
                self.emit('open-file', self.selected_path)

        else:
            files = []
            directory = None

            for item in self.view.get_selected_items():
                iter = self.model.get_iter(item)
                path = os.path.join(self.folder, self.model.get_value(iter, 0))

                if os.path.isfile(path):
                    files.append(path)

                elif os.path.isdir(path) and not directory:
                    directory = path

            if files:
                for path in files:
                    GObject.idle_add(self.emit, 'open-file', path)
                    self.emit('open-file', path)
                    self.selected_path = None

            else:
                if directory:
                    self.folder = directory
                    return  # Evit destroy

            self.destroy()

    def __open_path_from_entry(self, entry):
        path = self.entry.get_text()

        if not os.path.exists(path):
            self.create_alert(path)
            return

        if os.path.isdir(path):
            self.folder = path
            self.check_files()

        elif os.path.isfile(path):
            self.emit('open-file', path)
            self.destroy()

    def create_alert(self, path):
        alert = TimeoutAlert(10)
        alert.props.title = _('This file not exists.')
        alert.props.msg = _(
            "Apparently you've selected a file that does not exist.")
        image = Gtk.Image.new_from_stock(Gtk.STOCK_OK, Gtk.IconSize.MENU)
        alert.add_button(Gtk.ResponseType.NO, _('Ok'), icon=image)

        alert.connect('response', self.__alert_response)

        self.vbox.pack_start(alert, False, False, 0)
        self.vbox.reorder_child(alert, 1)

    def __alert_response(self, alert):
        self.vbox.remove(alert)

    def check_files(self):
        files = os.listdir(self.folder)
        files.sort()

        if files != self.files:
            self.selected_path = None

            self.entry.set_text(self.folder)
            self.go_up_button.set_sensitive(self.folder != '/')

            self.show_folder()

        return True

    def show_folder(self):
        self.files = os.listdir(self.folder)
        self.files.sort()
        self.model.clear()

        folders = []
        files = []

        for x in self.files:
            path = os.path.join(self.folder, x)
            if os.path.isdir(path):
                folders.append(path)

            elif os.path.isfile(path):
                files.append(path)

        for path in folders + files:
            if not self.show_hidden_files:
                if path.endswith('~') or path.split('/')[-1].startswith('.'):
                    continue

            pixbuf = G.get_pixbuf_from_path(path)
            self.model.append([path.split('/')[-1], pixbuf])

    def __selection_changed(self, view):
        if self.view.get_selected_items():
            path = self.view.get_selected_items()[0]
            iter = self.model.get_iter(path)
            self.selected_path = os.path.join(self.folder,
                                              self.model.get_value(iter, 0))
            self.button_open.set_sensitive(True)

        else:
            self.selected_path = None
            self.button_open.set_sensitive(False)

    def __button_press_event_cb(self, view, event):
        if event.button != 1:
            return

        try:
            path = view.get_path_at_pos(int(event.x), int(event.y))
            iter = self.model.get_iter(path)
            directory = os.path.join(self.folder,
                                     self.model.get_value(iter, 0))

            if event.type.value_name == 'GDK_2BUTTON_PRESS':
                if os.path.isdir(directory):
                    self.folder = directory

                elif os.path.isfile(directory):
                    self.emit('open-file', directory)
                    self.destroy()

        except TypeError:
            self.selected_path = None
            self.button_open.set_sensitive(False)

    def close(self, button=None):
        self.destroy()
class GetIABooksActivity(activity.Activity):

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

        self._sequence = 0
        self.selected_book = None
        self.queryresults = None
        self._getter = None
        self.show_images = True
        self.languages = {}
        self._lang_code_handler = languagenames.LanguageNames()
        self.catalogs_configuration = {}
        self.catalog_history = []

        if os.path.exists('/etc/get-books.cfg'):
            self._read_configuration('/etc/get-books.cfg')
        else:
            self._read_configuration()

        toolbar_box = ToolbarBox()
        activity_button = ToolButton()
        color = profile.get_color()
        bundle = ActivityBundle(activity.get_bundle_path())
        icon = Icon(file=bundle.get_icon(), xo_color=color)
        activity_button.set_icon_widget(icon)
        activity_button.show()

        toolbar_box.toolbar.insert(activity_button, 0)
        self._add_search_controls(toolbar_box.toolbar)

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

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

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show_all()
        self._books_toolbar = toolbar_box.toolbar

        self._create_controls()

        self.using_powerd = os.access(POWERD_INHIBIT_DIR, os.W_OK)

        self.__book_downloader = self.__image_downloader = None

    def get_path(self):
        self._sequence += 1
        return os.path.join(self.get_activity_root(),
                            'instance', '%03d.tmp' % self._sequence)

    def _inhibit_suspend(self):
        if self.using_powerd:
            fd = open(POWERD_INHIBIT_DIR + "/%u" % os.getpid(), 'w')
            logging.error("inhibit_suspend file is %s", (POWERD_INHIBIT_DIR \
                    + "/%u" % os.getpid()))
            fd.close()
            return True

        return False

    def _allow_suspend(self):
        if self.using_powerd:
            if os.path.exists(POWERD_INHIBIT_DIR + "/%u" % os.getpid()):
                os.unlink(POWERD_INHIBIT_DIR + "/%u" % os.getpid())
            logging.error("allow_suspend unlinking %s", (POWERD_INHIBIT_DIR \
                    + "/%u" % os.getpid()))
            return True

        return False

    def _read_configuration(self, file_name='get-books.cfg'):
        logging.error('Reading configuration from file %s', file_name)
        config = ConfigParser.ConfigParser()
        config.readfp(open(file_name))
        if config.has_option('GetBooks', 'show_images'):
            self.show_images = config.getboolean('GetBooks', 'show_images')
        self.languages = {}
        if config.has_option('GetBooks', 'languages'):
            languages_param = config.get('GetBooks', 'languages')
            for language in languages_param.split(','):
                lang_code = language.strip()
                if len(lang_code) > 0:
                    self.languages[lang_code] = \
                    self._lang_code_handler.get_full_language_name(lang_code)

        for section in config.sections():
            if section != 'GetBooks' and not section.startswith('Catalogs'):
                name = config.get(section, 'name')
                _SOURCES[section] = name
                repo_config = {}
                repo_config['query_uri'] = config.get(section, 'query_uri')
                repo_config['opds_cover'] = config.get(section, 'opds_cover')
                if config.has_option(section, 'summary_field'):
                    repo_config['summary_field'] = \
                        config.get(section, 'summary_field')
                else:
                    repo_config['summary_field'] = None
                if config.has_option(section, 'blacklist'):
                    blacklist = config.get(section, 'blacklist')
                    repo_config['blacklist'] = blacklist.split(',')
                    # TODO strip?
                else:
                    repo_config['blacklist'] = []

                _SOURCES_CONFIG[section] = repo_config

        logging.error('_SOURCES %s', pformat(_SOURCES))
        logging.error('_SOURCES_CONFIG %s', pformat(_SOURCES_CONFIG))

        for section in config.sections():
            if section.startswith('Catalogs'):
                catalog_source = section.split('_')[1]
                if not catalog_source in _SOURCES_CONFIG:
                    logging.error('There are not a source for the catalog ' +
                            'section  %s', section)
                    break
                source_config = _SOURCES_CONFIG[catalog_source]
                opds_cover = source_config['opds_cover']
                for catalog in config.options(section):
                    catalog_config = {}
                    catalog_config['query_uri'] = config.get(section, catalog)
                    catalog_config['opds_cover'] = opds_cover
                    catalog_config['source'] = catalog_source
                    catalog_config['name'] = catalog
                    catalog_config['summary_field'] = \
                        source_config['summary_field']
                    self.catalogs_configuration[catalog] = catalog_config

        self.source = _SOURCES_CONFIG.keys()[0]

        self.filter_catalogs_by_source()

        logging.error('languages %s', pformat(self.languages))
        logging.error('catalogs %s', pformat(self.catalogs))

    def _add_search_controls(self, toolbar):
        book_search_item = Gtk.ToolItem()
        toolbar.search_entry = iconentry.IconEntry()
        toolbar.search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                'system-search')
        toolbar.search_entry.add_clear_button()
        toolbar.search_entry.connect('activate',
                self.__search_entry_activate_cb)
        width = int(Gdk.Screen.width() / 4)
        toolbar.search_entry.set_size_request(width, -1)
        book_search_item.add(toolbar.search_entry)
        toolbar.search_entry.show()
        toolbar.insert(book_search_item, -1)
        book_search_item.show()

        toolbar.source_combo = ComboBox()
        toolbar.source_combo.props.sensitive = True
        toolbar.source_changed_cb_id = \
            toolbar.source_combo.connect('changed', self.__source_changed_cb)
        combotool = ToolComboBox(toolbar.source_combo)
        toolbar.insert(combotool, -1)
        combotool.show()

        self.bt_catalogs = ToggleToolButton('books')
        self.bt_catalogs.set_tooltip(_('Catalogs'))
        toolbar.insert(self.bt_catalogs, -1)
        self.bt_catalogs.connect('toggled', self.__toggle_cats_cb)
        if len(self.catalogs) > 0:
            self.bt_catalogs.show()

        if len(self.languages) > 0:
            toolbar.config_toolbarbutton = ToolbarButton()
            toolbar.config_toolbarbutton.props.icon_name = 'preferences-system'
            toolbar.config_toolbarbox = Gtk.Toolbar()
            toolbar.config_toolbarbutton.props.page = toolbar.config_toolbarbox
            toolbar.language_combo = ComboBox()
            toolbar.language_combo.props.sensitive = True
            combotool = ToolComboBox(toolbar.language_combo)
            toolbar.language_combo.append_item('all', _('Any language'))
            for key in self.languages.keys():
                toolbar.language_combo.append_item(key, self.languages[key])
            toolbar.language_combo.set_active(0)
            toolbar.config_toolbarbutton.props.page.insert(combotool, -1)
            toolbar.insert(toolbar.config_toolbarbutton, -1)
            toolbar.config_toolbarbutton.show()
            combotool.show()
            toolbar.language_changed_cb_id = \
                toolbar.language_combo.connect('changed',
                self.__language_changed_cb)

        self._device_manager = devicemanager.DeviceManager()
        self._refresh_sources(toolbar)
        self._device_manager.connect('device-changed',
                self.__device_changed_cb)

        toolbar.search_entry.grab_focus()
        return toolbar

    def __bt_catalogs_clicked_cb(self, button):
        palette = button.get_palette()
        palette.popup(immediate=True, state=palette.SECONDARY)

    def __switch_catalog_cb(self, catalog_name):
        catalog_config = self.catalogs[catalog_name.decode('utf-8')]
        self.__activate_catalog_cb(None, catalog_config)

    def __activate_catalog_cb(self, menu, catalog_config):
        query_language = self.get_query_language()

        self.enable_button(False)
        self.clear_downloaded_bytes()
        self.book_selected = False
        self.listview.handler_block(self.selection_cb_id)
        self.listview.clear()
        self.listview.handler_unblock(self.selection_cb_id)
        logging.error('SOURCE %s', catalog_config['source'])
        self._books_toolbar.search_entry.props.text = ''
        self.source = catalog_config['source']
        position = _SOURCES_CONFIG[self.source]['position']
        self._books_toolbar.source_combo.set_active(position)

        if self.queryresults is not None:
            self.queryresults.cancel()
            self.queryresults = None

        self.queryresults = opds.RemoteQueryResult(catalog_config,
                '', query_language)
        self.show_message(_('Performing lookup, please wait...'))
        # README: I think we should create some global variables for
        # each cursor that we are using to avoid the creation of them
        # every time that we want to change it
        self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))

        self.queryresults.connect('updated', self.__query_updated_cb)

    def update_format_combo(self, links):
        self.format_combo.handler_block(self.__format_changed_cb_id)
        self.format_combo.remove_all()
        for key in _MIMETYPES.keys():
            if _MIMETYPES[key] in links.keys():
                self.format_combo.append_item(_MIMETYPES[key], key)
        self.format_combo.set_active(0)
        self.format_combo.handler_unblock(self.__format_changed_cb_id)

    def get_search_terms(self):
        return self._books_toolbar.search_entry.props.text

    def __device_changed_cb(self, mgr):
        logging.debug('Device was added/removed')
        self._refresh_sources(self._books_toolbar)

    def _refresh_sources(self, toolbar):
        toolbar.source_combo.handler_block(toolbar.source_changed_cb_id)

        #TODO: Do not blindly clear this
        toolbar.source_combo.remove_all()

        position = 0
        for key in _SOURCES.keys():
            toolbar.source_combo.append_item(_SOURCES[key], key,
                icon_name='internet-icon')
            _SOURCES_CONFIG[key]['position'] = position
            position = position + 1

        # Add menu for local books
        if len(_SOURCES) > 0:
            toolbar.source_combo.append_separator()
        toolbar.source_combo.append_item('local_books', _('My books'),
                icon_name='activity-journal')

        devices = self._device_manager.get_devices()

        first_device = True
        for device_name in devices:
            device = devices[device_name]
            logging.debug('device %s', device)
            if device['removable']:
                mount_point = device['mount_path']
                label = device['label']
                if label == '' or label is None:
                    capacity = device['size']
                    label = (_('%.2f GB Volume') % (capacity / (1024.0 ** 3)))
                logging.debug('Adding device %s', (label))
                if first_device:
                    toolbar.source_combo.append_separator()
                    first_device = False
                toolbar.source_combo.append_item(mount_point, label)

        toolbar.source_combo.set_active(0)
        toolbar.source_combo.handler_unblock(toolbar.source_changed_cb_id)

    def __format_changed_cb(self, combo):
        self.show_book_data(False)

    def __language_changed_cb(self, combo):
        self.find_books(self.get_search_terms())

    def __search_entry_activate_cb(self, entry):
        self.find_books(self.get_search_terms())

    def __get_book_cb(self, button):
        self.get_book()

    def enable_button(self,  state):
        self._download.props.sensitive = state
        self.format_combo.props.sensitive = state

    def move_up_catalog(self, treeview):
        len_cat = len(self.catalog_history)
        if len_cat == 1:
            return
        else:
            # move a level up the tree
            self.catalog_listview.handler_block(self._catalog_changed_id)
            self.catalog_history.pop()
            len_cat -= 1
            if(len_cat == 1):
                title = self.catalog_history[0]['title']
                self.bt_move_up_catalog.set_label(title)
                self.bt_move_up_catalog.hide_image()
            else:
                title = self.catalog_history[len_cat - 1]['title']
                self.bt_move_up_catalog.set_label(title)
                self.bt_move_up_catalog.show_image()
            self.catalogs = self.catalog_history[len_cat - 1]['catalogs']
            if len(self.catalogs) > 0:
                self.path_iter = {}
                self.categories = []
                for key in self.catalogs.keys():
                    self.categories.append({'text': key, 'dentro': []})
                self.treemodel.clear()
                for p in self.categories:
                    self.path_iter[p['text']] = \
                            self.treemodel.append([p['text']])
            self.catalog_listview.handler_unblock(self._catalog_changed_id)

    def move_down_catalog(self, treeview):
        treestore, coldex = \
                self.catalog_listview.get_selection().get_selected()
        len_cat = len(self.catalog_history)
        if len_cat > 0 and self.catalog_history[len_cat - 1]['catalogs'] == []:
            self.catalog_history.pop()
            len_cat = len(self.catalog_history)

        # README: when the Activity starts by default there is nothing
        # selected and this signal is called, so we have to avoid this
        # 'append' because it fails
        if coldex is not None:
            self.catalog_history.append(
                    {'title': treestore.get_value(coldex, 0), 'catalogs': []})
            self.__switch_catalog_cb(treestore.get_value(coldex, 0))

    def _sort_logfile(self, treemodel, itera, iterb):
        a = treemodel.get_value(itera, 0)
        b = treemodel.get_value(iterb, 0)
        if a == None or b == None:
            return 0
        a = a.lower()
        b = b.lower()
        if a > b:
            return 1
        if a < b:
            return -1
        return 0

    def __toggle_cats_cb(self, button):
        if button.get_active():
            self.tree_scroller.show_all()
            self.separa.show()
        else:
            self.tree_scroller.hide()
            self.separa.hide()

    def _create_controls(self):
        self._download_content_length = 0
        self._download_content_type = None

        self.msg_label = Gtk.Label()

        self.list_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)

        # Catalogs treeview
        self.catalog_listview = Gtk.TreeView()
        self.catalog_listview.headers_clickble = True
        self.catalog_listview.hover_expand = True
        self.catalog_listview.rules_hint = True
        self._catalog_changed_id = self.catalog_listview.connect(
                'cursor-changed', self.move_down_catalog)
        self.catalog_listview.set_enable_search(False)

        self.treemodel = Gtk.ListStore(str)
        self.treemodel.set_sort_column_id(0, Gtk.SortType.ASCENDING)
        self.catalog_listview.set_model(self.treemodel)

        renderer = Gtk.CellRendererText()
        renderer.set_property('wrap-mode', Pango.WrapMode.WORD)
        self.treecol = Gtk.TreeViewColumn(_('Catalogs'), renderer, text=0)
        self.treecol.set_property('clickable', True)
        self.treecol.connect('clicked', self.move_up_catalog)
        self.catalog_listview.append_column(self.treecol)
        self.bt_move_up_catalog = ButtonWithImage(_('Catalogs'))
        self.bt_move_up_catalog.hide_image()
        self.treecol.set_widget(self.bt_move_up_catalog)

        self.load_source_catalogs()

        self.tree_scroller = Gtk.ScrolledWindow(hadjustment=None,
                vadjustment=None)
        self.tree_scroller.set_policy(Gtk.PolicyType.NEVER,
                Gtk.PolicyType.AUTOMATIC)
        self.tree_scroller.add(self.catalog_listview)
        self.list_box.pack_start(self.tree_scroller, expand=False,
                fill=False, padding=0)
        self.separa = Gtk.VSeparator()
        self.list_box.pack_start(self.separa, expand=False,
                fill=False, padding=0)

        # books listview
        self.listview = ListView(self._lang_code_handler)
        self.selection_cb_id = self.listview.connect('selection-changed',
                                                     self.selection_cb)
        self.listview.set_enable_search(False)

        self.list_scroller = Gtk.ScrolledWindow(hadjustment=None,
                vadjustment=None)
        self.list_scroller.set_policy(Gtk.PolicyType.AUTOMATIC,
                Gtk.PolicyType.AUTOMATIC)
        vadjustment = self.list_scroller.get_vadjustment()
        vadjustment.connect('value-changed',
                self.__vadjustment_value_changed_cb)
        self.list_scroller.add(self.listview)
        self.list_box.pack_start(self.list_scroller, expand=True,
                fill=True, padding=0)

        self.scrolled = Gtk.ScrolledWindow()
        self.scrolled.set_policy(Gtk.PolicyType.NEVER,
                Gtk.PolicyType.AUTOMATIC)
        self.scrolled.props.shadow_type = Gtk.ShadowType.NONE
        self.textview = Gtk.TextView()
        self.textview.set_editable(False)
        self.textview.set_cursor_visible(False)
        self.textview.set_wrap_mode(Gtk.WrapMode.WORD)
        self.textview.set_justification(Gtk.Justification.LEFT)
        self.textview.set_left_margin(20)
        self.textview.set_right_margin(20)
        self.scrolled.add(self.textview)
        self.list_box.show_all()
        self.separa.hide()
        self.tree_scroller.hide()

        vbox_download = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        hbox_format = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        format_label = Gtk.Label(label=_('Format:'))
        self.format_combo = ComboBox()
        for key in _MIMETYPES.keys():
            self.format_combo.append_item(_MIMETYPES[key], key)
        self.format_combo.set_active(0)
        self.format_combo.props.sensitive = False
        self.__format_changed_cb_id = \
                self.format_combo.connect('changed', self.__format_changed_cb)

        hbox_format.pack_start(format_label, False, False, 10)
        hbox_format.pack_start(self.format_combo, False, False, 10)
        vbox_download.pack_start(hbox_format, False, False, 10)

        self._download = Gtk.Button(_('Get Book'))
        self._download.set_image(Icon(icon_name='data-download'))
        self._download.props.sensitive = False
        self._download.connect('clicked', self.__get_book_cb)
        vbox_download.pack_start(self._download, False, False, 10)

        self.progressbox = Gtk.Box(spacing=20,
                orientation=Gtk.Orientation.HORIZONTAL)
        self.progressbar = Gtk.ProgressBar()
        self.progressbar.set_fraction(0.0)
        self.progressbox.pack_start(self.progressbar, expand=True, fill=True,
                padding=0)
        self.cancel_btn = Gtk.Button(stock=Gtk.STOCK_CANCEL)
        self.cancel_btn.set_image(Icon(icon_name='dialog-cancel'))
        self.cancel_btn.connect('clicked', self.__cancel_btn_clicked_cb)
        self.progressbox.pack_start(self.cancel_btn, expand=False,
                fill=False, padding=0)
        vbox_download.pack_start(self.progressbox, False, False, 10)

        bottom_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)

        if self.show_images:
            self.__image_downloader = None
            self.image = Gtk.Image()
            self.add_default_image()
            bottom_hbox.pack_start(self.image, False, False, 10)
        bottom_hbox.pack_start(self.scrolled, True, True, 10)
        bottom_hbox.pack_start(vbox_download, False, False, 10)
        bottom_hbox.show_all()

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.pack_start(self.msg_label, False, False, 10)
        vbox.pack_start(self.list_box, True, True, 0)
        vbox.pack_start(bottom_hbox, False, False, 10)
        self.set_canvas(vbox)
        self.listview.show()
        vbox.show()
        self.list_scroller.show()
        self.progress_hide()
        self.show_message(
                _('Enter words from the Author or Title to begin search.'))

        self._books_toolbar.search_entry.grab_focus()
        if len(self.catalogs) > 0:
            self.bt_catalogs.set_active(True)

    def progress_hide(self):
        self.clear_downloaded_bytes()
        self.progressbar.set_sensitive(False)
        self.cancel_btn.set_sensitive(False)

    def progress_show(self):
        self.progressbar.set_sensitive(True)
        self.cancel_btn.set_sensitive(True)

    def filter_catalogs_by_source(self):
        self.catalogs = {}
        for catalog_key in self.catalogs_configuration:
            catalog = self.catalogs_configuration[catalog_key]
            if catalog['source'] == self.source:
                self.catalogs[catalog_key] = catalog

    def load_source_catalogs(self):
        self.filter_catalogs_by_source()

        if len(self.catalogs) > 0:
            self.categories = []
            self.path_iter = {}
            self.catalog_history = []
            self.catalog_history.append({'title': _('Catalogs'),
                'catalogs': self.catalogs})
            for key in self.catalogs.keys():
                self.categories.append({'text': key, 'dentro': []})
            self.treemodel.clear()

            for p in self.categories:
                self.path_iter[p['text']] = self.treemodel.append([p['text']])

    def can_close(self):
        if self.queryresults is not None:
            self.queryresults.cancel()
            self.queryresults = None
        return True

    def selection_cb(self, widget):
        selected_book = self.listview.get_selected_book()
        if self.source == 'local_books':
            if selected_book:
                self.selected_book = selected_book
                self._download.hide()
                self.show_book_data()
                self._object_id = selected_book.get_object_id()
                self._show_journal_alert(_('Selected book'),
                        self.selected_title)
        else:
            self.clear_downloaded_bytes()
            if selected_book:
                self.update_format_combo(selected_book.get_types())
                self.selected_book = selected_book
                self._download.show()
                self.show_book_data()

    def show_message(self, text):
        self.msg_label.set_text(text)
        self.msg_label.show()

    def hide_message(self):
        self.msg_label.hide()

    def show_book_data(self, load_image=True):
        self.selected_title = self.selected_book.get_title()
        book_data = _('Title:\t\t') + self.selected_title + '\n'
        self.selected_author = self.selected_book.get_author()
        book_data += _('Author:\t\t') + self.selected_author + '\n'
        self.selected_publisher = self.selected_book.get_publisher()
        self.selected_summary = self.selected_book.get_summary()
        if (self.selected_summary is not 'Unknown'):
            book_data += _('Summary:\t') + self.selected_summary + '\n'
        self.selected_language_code = self.selected_book.get_language()
        if self.selected_language_code != '':
            try:
                self.selected_language = \
                    self._lang_code_handler.get_full_language_name(
                        self.selected_book.get_language())
            except:
                self.selected_language = self.selected_book.get_language()
            book_data += _('Language:\t') + self.selected_language + '\n'
        book_data += _('Publisher:\t') + self.selected_publisher + '\n'
        textbuffer = self.textview.get_buffer()
        textbuffer.set_text('\n' + book_data)
        self.enable_button(True)

        # Cover Image
        self.exist_cover_image = False
        if self.show_images and load_image:
            if self.source == 'local_books':
                cover_image_buffer = self.get_journal_entry_cover_image(
                        self.selected_book.get_object_id())
                if (cover_image_buffer):
                    self.add_image_buffer(
                        self.get_pixbuf_from_buffer(cover_image_buffer))
                else:
                    self.add_default_image()
            else:
                url_image = self.selected_book.get_image_url()
                self.add_default_image()
                if url_image:
                    self.download_image(url_image.values()[0])

    def get_pixbuf_from_buffer(self, image_buffer):
        """Buffer To Pixbuf"""
        pixbuf_loader = GdkPixbuf.PixbufLoader()
        pixbuf_loader.write(image_buffer)
        pixbuf_loader.close()
        pixbuf = pixbuf_loader.get_pixbuf()
        return pixbuf

    def get_journal_entry_cover_image(self, object_id):
        ds_object = datastore.get(object_id)
        if 'cover_image' in ds_object.metadata:
            cover_data = ds_object.metadata['cover_image']
            return base64.b64decode(cover_data)
        elif 'preview' in ds_object.metadata:
            return ds_object.metadata['preview']
        else:
            return ""

    def download_image(self,  url):
        self._inhibit_suspend()
        self.progress_show()
        if self.__image_downloader is not None:
            self.__image_downloader.stop()
        self.__image_downloader = opds.FileDownloader(url, self.get_path())
        self.__image_downloader.connect('updated', self.__image_updated_cb)
        self.__image_downloader.connect('progress', self.__image_progress_cb)

    def __image_updated_cb(self, downloader, path, content_type):
        if path is not None:
            self.add_image(path)
            self.exist_cover_image = True
            os.remove(path)
        else:
            self.add_default_image()
        self.__image_downloader = None
        GObject.timeout_add(500, self.progress_hide)
        self._allow_suspend()

    def __image_progress_cb(self, downloader, progress):
        self.progressbar.set_fraction(progress)
        while Gtk.events_pending():
            Gtk.main_iteration()

    def add_default_image(self):
        file_path = os.path.join(activity.get_bundle_path(),
                'generic_cover.png')
        self.add_image(file_path)

    def add_image(self, file_path):
        pixbuf = GdkPixbuf.Pixbuf.new_from_file(file_path)
        self.add_image_buffer(pixbuf)

    def add_image_buffer(self, pixbuf):
        image_height = int(Gdk.Screen.height() / 4)
        image_width = image_height / 3 * 2
        width, height = pixbuf.get_width(), pixbuf.get_height()
        scale = 1
        if (width > image_width) or (height > image_height):
            scale_x = image_width / float(width)
            scale_y = image_height / float(height)
            scale = min(scale_x, scale_y)

        pixbuf2 = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB,
                pixbuf.get_has_alpha(), pixbuf.get_bits_per_sample(),
                image_width, image_height)

        pixbuf2.fill(style.COLOR_PANEL_GREY.get_int())

        margin_x = int((image_width - (width * scale)) / 2)
        margin_y = int((image_height - (height * scale)) / 2)

        pixbuf.scale(pixbuf2, margin_x, margin_y,
                image_width - (margin_x * 2), image_height - (margin_y * 2),
                margin_x, margin_y, scale, scale,
                GdkPixbuf.InterpType.BILINEAR)

        self.image.set_from_pixbuf(pixbuf2)

    def get_query_language(self):
        query_language = None
        if len(self.languages) > 0:
            query_language = self._books_toolbar.language_combo.props.value
        return query_language

    def find_books(self, search_text=''):
        self._inhibit_suspend()
        self.source = self._books_toolbar.source_combo.props.value

        query_language = self.get_query_language()

        self.enable_button(False)
        self.clear_downloaded_bytes()
        self.book_selected = False
        self.listview.handler_block(self.selection_cb_id)
        self.listview.clear()
        self.listview.handler_unblock(self.selection_cb_id)

        if self.queryresults is not None:
            self.queryresults.cancel()
            self.queryresults = None

        if self.source == 'local_books':
            self.listview.populate_with_books(
                    self.get_entrys_info(search_text))
        else:
            if search_text is None:
                return
            elif len(search_text) < 3:
                self.show_message(_('You must enter at least 3 letters.'))
                self._books_toolbar.search_entry.grab_focus()
                return
            if self.source == 'Internet Archive':
                self.queryresults = \
                        opds.InternetArchiveQueryResult(search_text,
                                                        self.get_path())
            elif self.source in _SOURCES_CONFIG:
                repo_configuration = _SOURCES_CONFIG[self.source]
                self.queryresults = opds.RemoteQueryResult(repo_configuration,
                        search_text, query_language)
            else:
                self.queryresults = opds.LocalVolumeQueryResult(self.source,
                        search_text, query_language)

            self.show_message(_('Performing lookup, please wait...'))
            self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH))
            self.queryresults.connect('updated', self.__query_updated_cb)

    def __query_updated_cb(self, query, midway):
        self.listview.populate(self.queryresults)
        if hasattr(self.queryresults, '_feedobj') and \
           'bozo_exception' in self.queryresults._feedobj:
            # something went wrong and we have to inform about this
            bozo_exception = self.queryresults._feedobj.bozo_exception
            if isinstance(bozo_exception, urllib2.URLError):
                if isinstance(bozo_exception.reason, socket.gaierror):
                    if bozo_exception.reason.errno == -2:
                        self.show_message(_('Could not reach the server. '
                            'Maybe you are not connected to the network'))
                        self.window.set_cursor(None)
                        return
            self.show_message(_('There was an error downloading the list.'))
        elif (len(self.queryresults.get_catalog_list()) > 0):
            self.show_message(_('New catalog list %s was found') \
                % self.queryresults._configuration["name"])
            self.catalogs_updated(query, midway)
        elif len(self.queryresults) == 0:
            self.show_message(_('Sorry, no books could be found.'))
        if not midway and len(self.queryresults) > 0:
            self.hide_message()
            query_language = self.get_query_language()
            if query_language != 'all' and query_language != 'en':
                # the bookserver send english books if there are not books in
                # the requested language
                only_english = True
                for book in self.queryresults.get_book_list():
                    if book.get_language() == query_language:
                        only_english = False
                        break
                if only_english:
                    self.show_message(
                            _('Sorry, we only found english books.'))
        self.get_window().set_cursor(None)
        self._allow_suspend()

    def catalogs_updated(self, query, midway):
        self.catalogs = {}
        for catalog_item in self.queryresults.get_catalog_list():
            logging.debug('Add catalog %s', catalog_item.get_title())
            catalog_config = {}
            download_link = ''
            download_links = catalog_item.get_download_links()
            for link in download_links.keys():
                download_link = download_links[link]
                break
            catalog_config['query_uri'] = download_link
            catalog_config['opds_cover'] = \
                catalog_item._configuration['opds_cover']
            catalog_config['source'] = catalog_item._configuration['source']
            source_config = _SOURCES_CONFIG[catalog_config['source']]
            catalog_config['name'] = catalog_item.get_title()
            catalog_config['summary_field'] = \
                catalog_item._configuration['summary_field']
            if catalog_item.get_title() in source_config['blacklist']:
                logging.debug('Catalog "%s" is in blacklist',
                    catalog_item.get_title())
            else:
                self.catalogs[catalog_item.get_title().strip()] = \
                        catalog_config

        if len(self.catalogs) > 0:
            len_cat = len(self.catalog_history)
            self.catalog_history[len_cat - 1]['catalogs'] = self.catalogs
            self.path_iter = {}
            self.categories = []
            for key in self.catalogs.keys():
                self.categories.append({'text': key, 'dentro': []})
            self.treemodel.clear()
            for p in self.categories:
                self.path_iter[p['text']] = \
                        self.treemodel.append([p['text']])

            title = self.catalog_history[len_cat - 1]['title']
            self.bt_move_up_catalog.set_label(title)
            self.bt_move_up_catalog.show_image()

        else:
            self.catalog_history.pop()

    def __source_changed_cb(self, widget):
        search_terms = self.get_search_terms()
        if search_terms == '':
            self.find_books(None)
        else:
            self.find_books(search_terms)
        # enable/disable catalogs button if configuration is available
        self.source = self._books_toolbar.source_combo.props.value

        # Get catalogs for this source
        self.load_source_catalogs()

        if len(self.catalogs) > 0:
            self.bt_catalogs.show()
            self.bt_catalogs.set_active(True)
        else:
            self.bt_catalogs.set_active(False)
            self.bt_catalogs.hide()

    def __vadjustment_value_changed_cb(self, vadjustment):

        if not self.queryresults.is_ready():
            return
        try:
            # Use various tricks to update resultset as user scrolls down
            if ((vadjustment.props.upper - vadjustment.props.lower) > 1000 \
                and (vadjustment.props.upper - vadjustment.props.value - \
                vadjustment.props.page_size) / (vadjustment.props.upper - \
                vadjustment.props.lower) < 0.3) or ((vadjustment.props.upper \
                - vadjustment.props.value
                - vadjustment.props.page_size) < 200):
                if self.queryresults.has_next():
                    self.queryresults.update_with_next()
        finally:
            return

    def __cancel_btn_clicked_cb(self, btn):
        if self.__image_downloader is not None:
            self.__image_downloader.stop()

        if self.__book_downloader is not None:
            self.__book_downloader.stop()

        self.progress_hide()
        self.enable_button(True)
        self.listview.props.sensitive = True
        self._books_toolbar.search_entry.set_sensitive(True)
        self._allow_suspend()

    def get_book(self):
        self.enable_button(False)
        self.clear_downloaded_bytes()
        self.progress_show()
        if self.source != 'local_books':
            self.selected_book.get_download_links(self.format_combo.props.value,
                                                  self.download_book,
                                                  self.get_path())

    def download_book(self,  url):
        logging.error('DOWNLOAD BOOK %s', url)
        self._inhibit_suspend()
        self.listview.props.sensitive = False
        self._books_toolbar.search_entry.set_sensitive(False)
        self.__book_downloader = opds.FileDownloader(url, self.get_path())
        self.__book_downloader.connect('updated', self.__book_updated_cb)
        self.__book_downloader.connect('progress', self.__book_progress_cb)

    def __book_updated_cb(self, downloader, path, content_type):
        self._books_toolbar.search_entry.set_sensitive(True)
        self.listview.props.sensitive = True
        self._allow_suspend()
        GObject.timeout_add(500, self.progress_hide)
        self.enable_button(True)
        self.__book_downloader = None

        if path is None:
            self._show_error_alert(_('Error: Could not download %s. ' +
                    'The path in the catalog seems to be incorrect.') %
                    self.selected_title)
            return

        if os.stat(path).st_size == 0:
            self._show_error_alert(_('Error: Could not download %s. ' +
                    'The other end sent an empty file.') %
                    self.selected_title)
            return

        if content_type.startswith('text/html'):
            self._show_error_alert(_('Error: Could not download %s. ' +
                    'The other end sent text/html instead of a book.') %
                    self.selected_title)
            return

        self.process_downloaded_book(path)

    def __book_progress_cb(self, downloader, progress):
        self.progressbar.set_fraction(progress)
        while Gtk.events_pending():
            Gtk.main_iteration()

    def clear_downloaded_bytes(self):
        self.progressbar.set_fraction(0.0)

    def process_downloaded_book(self, path):
        logging.debug("Got document %s", path)
        self.create_journal_entry(path)
        self._getter = None
        self._allow_suspend()

    def create_journal_entry(self, path):
        journal_entry = datastore.create()
        journal_title = self.selected_title
        if self.selected_author != '':
            journal_title = journal_title + ', by ' + self.selected_author
        journal_entry.metadata['title'] = journal_title
        journal_entry.metadata['title_set_by_user'] = '******'
        journal_entry.metadata['keep'] = '0'
        journal_entry.metadata['mime_type'] = \
                self.format_combo.props.value
        # Fix fake mime type for black&white pdfs
        if journal_entry.metadata['mime_type'] == _MIMETYPES['PDF BW']:
            journal_entry.metadata['mime_type'] = _MIMETYPES['PDF']

        journal_entry.metadata['buddies'] = ''
        journal_entry.metadata['icon-color'] = profile.get_color().to_string()
        textbuffer = self.textview.get_buffer()
        journal_entry.metadata['description'] = \
            textbuffer.get_text(textbuffer.get_start_iter(),
                                textbuffer.get_end_iter(), True)
        if self.exist_cover_image:
            image_buffer = self._get_preview_image_buffer()
            journal_entry.metadata['preview'] = dbus.ByteArray(image_buffer)
            image_buffer = self._get_cover_image_buffer()
            journal_entry.metadata['cover_image'] = \
                dbus.ByteArray(base64.b64encode(image_buffer))
        else:
            journal_entry.metadata['cover_image'] = ""

        journal_entry.metadata['tags'] = self.source
        journal_entry.metadata['source'] = self.source
        journal_entry.metadata['author'] = self.selected_author
        journal_entry.metadata['publisher'] = self.selected_publisher
        journal_entry.metadata['summary'] = self.selected_summary
        journal_entry.metadata['language'] = self.selected_language_code

        journal_entry.file_path = path
        datastore.write(journal_entry)
        os.remove(path)
        self.progress_hide()
        self._object_id = journal_entry.object_id
        self._show_journal_alert(_('Download completed'), self.selected_title)

    def _show_journal_alert(self, title, msg):
        _stop_alert = Alert()
        _stop_alert.props.title = title
        _stop_alert.props.msg = msg

        if _HAS_BUNDLE_LAUNCHER:
                bundle = get_bundle(object_id=self._object_id)

        if bundle is not None:
            icon = Icon(file=bundle.get_icon())
            label = _('Open with %s') % bundle.get_name()
            _stop_alert.add_button(Gtk.ResponseType.ACCEPT, label, icon)
        else:
            icon = Icon(icon_name='zoom-activity')
            label = _('Show in Journal')
            _stop_alert.add_button(Gtk.ResponseType.APPLY, label, icon)
        icon.show()

        ok_icon = Icon(icon_name='dialog-ok')
        _stop_alert.add_button(Gtk.ResponseType.OK, _('Ok'), ok_icon)
        ok_icon.show()
        # Remove other alerts
        for alert in self._alerts:
            self.remove_alert(alert)

        self.add_alert(_stop_alert)
        _stop_alert.connect('response', self.__stop_response_cb)
        _stop_alert.show()

    def __stop_response_cb(self, alert, response_id):
        if response_id is Gtk.ResponseType.APPLY:
            activity.show_object_in_journal(self._object_id)
        elif response_id is Gtk.ResponseType.ACCEPT:
            launch_bundle(object_id=self._object_id)
        self.remove_alert(alert)

    def _get_preview_image_buffer(self):
        preview_width, preview_height = style.zoom(300), style.zoom(225)

        pixbuf = self.image.get_pixbuf()
        width, height = pixbuf.get_width(), pixbuf.get_height()

        scale = 1
        if (width > preview_width) or (height > preview_height):
            scale_x = preview_width / float(width)
            scale_y = preview_height / float(height)
            scale = min(scale_x, scale_y)

        pixbuf2 = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB,
                pixbuf.get_has_alpha(), pixbuf.get_bits_per_sample(),
                preview_width, preview_height)
        pixbuf2.fill(style.COLOR_WHITE.get_int())

        margin_x = int((preview_width - (width * scale)) / 2)
        margin_y = int((preview_height - (height * scale)) / 2)

        pixbuf.scale(pixbuf2, margin_x, margin_y,
                preview_width - (margin_x * 2),
                preview_height - (margin_y * 2),
                margin_x, margin_y, scale, scale,
                GdkPixbuf.InterpType.BILINEAR)

        succes, data = pixbuf2.save_to_bufferv('png', [], [])
        return data

    def _get_cover_image_buffer(self):
        pixbuf = self.image.get_pixbuf()
        succes, data = pixbuf.save_to_bufferv('png', [], [])
        return data

    def _show_error_alert(self, title, text=None):
        alert = NotifyAlert(timeout=20)
        alert.props.title = title
        alert.props.msg = text
        self.add_alert(alert)
        alert.connect('response', self._alert_cancel_cb)
        alert.show()

    def _alert_cancel_cb(self, alert, response_id):
        self.remove_alert(alert)
        self.textview.grab_focus()

    def get_entrys_info(self, query):
        books = []
        for key in _MIMETYPES.keys():
            books.extend(self.get_entry_info_format(query, _MIMETYPES[key]))
        return books

    def get_entry_info_format(self, query, mime):
        books = []
        if query is not None and len(query) > 0:
            ds_objects, num_objects = datastore.find(
                    {'mime_type': '%s' % mime,
                    'query': '*%s*' % query})
        else:
            ds_objects, num_objects = datastore.find(
                    {'mime_type': '%s' % mime})

        logging.error('Local search %d books found %s format', num_objects,
                    mime)
        for i in range(0, num_objects):
            entry = {}
            entry['title'] = ds_objects[i].metadata['title']
            entry['mime'] = ds_objects[i].metadata['mime_type']
            entry['object_id'] = ds_objects[i].object_id

            if 'author' in ds_objects[i].metadata:
                entry['author'] = ds_objects[i].metadata['author']
            else:
                entry['author'] = ''

            if 'publisher' in ds_objects[i].metadata:
                entry['dcterms_publisher'] = \
                    ds_objects[i].metadata['publisher']
            else:
                entry['dcterms_publisher'] = ''

            if 'language' in ds_objects[i].metadata:
                entry['dcterms_language'] = \
                    ds_objects[i].metadata['language']
            else:
                entry['dcterms_language'] = ''

            if 'source' in ds_objects[i].metadata:
                entry['source'] = \
                    ds_objects[i].metadata['source']
            else:
                entry['source'] = ''

            if entry['source'] in _SOURCES_CONFIG:
                repo_configuration = _SOURCES_CONFIG[entry['source']]
                summary_field = repo_configuration['summary_field']
                if 'summary' in ds_objects[i].metadata:
                    entry[summary_field] = ds_objects[i].metadata['summary']
                else:
                    entry[summary_field] = ''
            else:
                repo_configuration = None
            books.append(opds.Book(repo_configuration, entry, ''))
        return books

    def close(self,  skip_save=False):
        "Override the close method so we don't try to create a Journal entry."
        activity.Activity.close(self,  True)

    def save(self):
        pass
Ejemplo n.º 43
0
class SimplePianoActivity(activity.Activity):
    """SimplePianoActivity class as specified in activity.info"""
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)
        GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.close)
        Gst.init(None)

        self._what_list = []

        self.play_recording_thread = None

        self.playing_recording = False
        self.firstTime = False
        self.playing = False
        self.regularity = 0.7
        self._drums_store = []
        self.recording = False
        self.recorded_keys = []
        self.is_valid_recording = False

        # we do not have collaboration features
        # make the share option insensitive
        self.max_participants = 1
        self.csnd = new_csound_client()
        self.rythmInstrument = 'drum1kick'
        # toolbar with the new toolbar redesign
        toolbar_box = ToolbarBox()
        activity_button = ActivityToolbarButton(self)
        toolbar_box.toolbar.insert(activity_button, 0)
        toolbar_box.toolbar.set_style(Gtk.ToolbarStyle.BOTH_HORIZ)

        self.play_index = 0

        self.play_recording_button = ToolButton(
            icon_name='media-playback-start')
        self.play_recording_button.set_property('can-default', True)
        self.play_recording_button.show()
        self.record_button = ToggleToolButton(icon_name='media-record')
        self.record_button.set_property('can-default', True)
        self.record_button.show()
        self.play_recording_button.set_sensitive(False)

        self.record_button.connect('clicked', self.__record_button_click_cb)

        self.play_recording_button.connect('clicked',
                                           self.handlePlayRecordingButton)

        toolbar_box.toolbar.set_style(Gtk.ToolbarStyle.BOTH_HORIZ)

        # TODO: disabe until is implemented with csnd6
        # self.createPercussionToolbar(toolbar_box)

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

        keybord_labels = RadioToolButton()
        keybord_labels.props.icon_name = 'q_key'
        keybord_labels.props.group = keybord_labels
        keybord_labels.connect('clicked', self.set_keyboard_labels_cb)
        toolbar_box.toolbar.insert(keybord_labels, -1)

        notes_labels = RadioToolButton()
        notes_labels.props.icon_name = 'do_key'
        notes_labels.props.group = keybord_labels
        notes_labels.connect('clicked', self.set_notes_labels_cb)
        toolbar_box.toolbar.insert(notes_labels, -1)

        ti_notes_labels = RadioToolButton()
        ti_notes_labels.props.icon_name = 'ti_key'
        ti_notes_labels.props.group = keybord_labels
        ti_notes_labels.connect('clicked', self.set_ti_notes_labels_cb)
        toolbar_box.toolbar.insert(ti_notes_labels, -1)

        german_labels = RadioToolButton()
        german_labels.props.icon_name = 'c_key'
        german_labels.props.group = keybord_labels
        german_labels.connect('clicked', self.set_german_labels_cb)
        toolbar_box.toolbar.insert(german_labels, -1)

        no_labels = RadioToolButton()
        no_labels.props.icon_name = 'edit-clear'
        no_labels.props.group = keybord_labels
        no_labels.connect('clicked', self.set_keyboard_no_labels_cb)
        toolbar_box.toolbar.insert(no_labels, -1)
        self._what_widget = Gtk.ToolItem()
        self._what_search_button = FilterToolItem(_('Select Instrument'),
                                                  'view-type', _('Piano'),
                                                  self._what_widget)
        self._what_widget.show()
        toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1)
        toolbar_box.toolbar.insert(self._what_search_button, -1)
        self._what_search_button.show()
        self._what_search_button.set_is_important(True)
        self._what_widget_contents = None
        self._what_drum_widget_contents = None

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

        toolbar_box.toolbar.insert(self.record_button, -1)
        toolbar_box.toolbar.insert(self.play_recording_button, -1)

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

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

        self._save_as_audio_bt = ToolButton(icon_name='save-as-audio')
        self._save_as_audio_bt.props.tooltip = _('Save as audio')
        self._save_as_audio_bt.connect('clicked', self._save_ogg_cb)
        self._save_as_audio_bt.show()
        self._save_as_audio_bt.set_sensitive(False)
        activity_button.page.insert(self._save_as_audio_bt, -1)

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show_all()

        self.keyboard_letters = ['ZSXDCVGBHNJM', 'Q2W3ER5T6Y7U', 'I']

        notes = [
            'DO', ['DO#', 'REb'], 'RE', ['RE#', 'MIb'], 'MI', 'FA',
            ['FA#', 'SOLb'], 'SOL', ['SOL#', 'LAb'], 'LA', ['LA#', 'SIb'], 'SI'
        ]
        self.notes_labels = [notes, notes, ['DO']]

        # some countries use TI instead of SI
        ti_notes = [
            'DO', ['DO#', 'REb'], 'RE', ['RE#', 'MIb'], 'MI', 'FA',
            ['FA#', 'SOLb'], 'SOL', ['SOL#', 'LAb'], 'LA', ['LA#', 'TIb'], 'TI'
        ]
        self.ti_notes_labels = [ti_notes, ti_notes, ['DO']]

        german_notes = [
            'C', ['C#', 'Db'], 'D', ['D#', 'Eb'], 'E', 'F', ['F#', 'Gb'], 'G',
            ['G#', 'Ab'], 'A', ['A#', 'Bb'], 'B'
        ]

        self.german_labels = [german_notes, german_notes, ['C']]

        self.piano = PianoKeyboard(octaves=2,
                                   add_c=True,
                                   labels=self.keyboard_letters)

        # init csound
        self.instrumentDB = InstrumentDB.getRef()
        self.timeout_ms = 50
        self.instVolume = 50
        self.drumVolume = 0.5
        self.instrument = 'piano'
        self.beat = 4
        self.reverb = 0.1
        self.tempo = PLAYER_TEMPO
        self.beatDuration = 60.0 / self.tempo
        self.ticksPerSecond = Config.TICKS_PER_BEAT * self.tempo / 60.0

        self.sequencer = MiniSequencer(self.recordStateButton,
                                       self.recordOverSensitivity)
        self.loop = Loop(self.beat, math.sqrt(self.instVolume * 0.01))

        self.drumFillin = Fillin(self.beat, self.tempo, self.rythmInstrument,
                                 self.reverb, self.drumVolume)

        self.muteInst = False
        self.csnd.setTempo(self.tempo)
        self.noteList = []
        for i in range(21):
            self.csnd.setTrackVolume(100, i)

        # TODO commented because apparently are not used in the activity
        # for i in range(10):
        #     self.csnd.load_instrument('guidice' + str(i + 1))

        self.volume = 100
        self.csnd.setMasterVolume(self.volume)

        self.enableKeyboard()
        self.setInstrument(self.instrument)

        self.connect('key-press-event', self.onKeyPress)
        self.connect('key-release-event', self.onKeyRelease)

        self.piano.connect('key_pressed', self.__key_pressed_cb)
        self.piano.connect('key_released', self.__key_released_cb)
        vbox = Gtk.VBox()
        vbox.set_homogeneous(False)
        self.load_instruments()
        self._event_box = Gtk.EventBox()
        self._event_box.modify_bg(Gtk.StateType.NORMAL,
                                  style.COLOR_WHITE.get_gdk_color())
        vbox.pack_start(self._event_box, False, False, 0)
        vbox.pack_end(self.piano, True, True, 0)
        vbox.show_all()
        self.set_canvas(vbox)
        piano_height = Gdk.Screen.width() / 2
        self._event_box.set_size_request(
            -1,
            Gdk.Screen.height() - piano_height - style.GRID_CELL_SIZE)
        self.connect('size-allocate', self.__allocate_cb)

        # TODO: disabe until is implemented with csnd6
        # GLib.idle_add(self.initializePercussion)

    def createPercussionToolbar(self, toolbar_box):

        self.beats_pm_button = IntensitySelector(range(2, 13), 4,
                                                 imagefile('beat3.svg'))
        self.tempo_button = \
            IntensitySelector(range(PLAYER_TEMPO_LOWER,
                                    PLAYER_TEMPO_UPPER + 1, PLAYER_TEMPO_STEP),
                              PLAYER_TEMPO, imagefile('tempo5.png'))

        self.complexity_button = IntensitySelector(xfrange(0, 1, 0.1),
                                                   self.regularity,
                                                   imagefile('complex6.svg'))

        self._play_percussion_btn = ToolButton(
            icon_name='media-playback-start')
        self._play_percussion_btn.set_property('can-default', True)
        self._play_percussion_btn.show()
        self._play_percussion_btn.connect('clicked', self.handlePlayButton)

        beats_toolbar = ToolbarBox()
        beats_toolbar.toolbar.insert(self._play_percussion_btn, -1)

        self._what_drum_widget = Gtk.ToolItem()
        self._what_drum_search_button = FilterToolItem(_('Select Drum'),
                                                       'view-type',
                                                       _('Jazz / Rock Kit'),
                                                       self._what_drum_widget)
        self._what_drum_search_button.set_widget_icon(
            file_name=imagefile("drum1kit.svg"))

        self._what_drum_widget.show()
        beats_toolbar.toolbar.insert(self._what_drum_search_button, -1)
        self._what_drum_search_button.show()
        self._what_drum_search_button.set_is_important(True)

        beats_toolbar.toolbar.insert(Gtk.SeparatorToolItem(), -1)
        beats_toolbar.toolbar.insert(self.complexity_button, -1)
        beats_toolbar.toolbar.insert(self.beats_pm_button, -1)
        beats_toolbar.toolbar.insert(self.tempo_button, -1)

        beats_toolbar_button = ToolbarButton(icon_name='toolbar-drums',
                                             page=beats_toolbar)
        beats_toolbar_button.show()

        toolbar_box.toolbar.insert(beats_toolbar_button, 1)

        self.beats_pm_button.set_tooltip(_("Beats per bar"))
        self.beats_pm_button.show()
        self.beats_pm_button.connect('changed', self.beatSliderChange, True)
        self.tempo_button.connect('changed', self.tempoSliderChange, True)
        self.complexity_button.connect('changed', self.handleComplexityChange,
                                       True)
        self.complexity_button.set_tooltip(_("Beat complexity"))
        self.tempo_button.show()
        self.tempo_button.set_tooltip(_('Tempo'))
        self.complexity_button.show()

    def initializePercussion(self):
        self.rythmInstrument = 'drum1kit'
        self.csnd.load_drumkit(self.rythmInstrument)
        self.csnd.setTempo(self.tempo)
        self.beatPickup = False

        def flatten(ll):
            rval = []
            for l in ll:
                rval += l
            return rval

        noteOnsets = []
        notePitchs = []

        i = 0
        self.noteList = []
        self.csnd.loopClear()
        for x in flatten(
                generator(self.rythmInstrument, self.beat, 0.8,
                          self.regularity, self.reverb)):
            x.amplitude = x.amplitude * self.drumVolume
            noteOnsets.append(x.onset)
            notePitchs.append(x.pitch)
            n = Note(0, x.trackId, i, x)
            self.noteList.append((x.onset, n))
            i = i + 1
            self.csnd.loopPlay(n, 1)  # add as active

        self.csnd.loopSetNumTicks(self.beat * Config.TICKS_PER_BEAT)
        self.drumFillin.unavailable(noteOnsets, notePitchs)

        if self.playing:
            self.csnd.loopStart()

    def __allocate_cb(self, widget, rect):
        GLib.idle_add(self.resize, rect.width, rect.height)
        return False

    def resize(self, width, height):
        logging.debug('activity.py resize......')
        piano_height = width / 2
        self._event_box.set_size_request(
            -1,
            Gdk.Screen.height() - piano_height - style.GRID_CELL_SIZE)
        return False

    def load_instruments(self):
        self._instruments_store = []

        # load the images
        images_path = os.path.join(activity.get_bundle_path(), 'instruments')
        logging.debug('Loading instrument images from %s', images_path)
        for file_name in os.listdir(images_path):
            image_file_name = os.path.join(images_path, file_name)
            pxb = GdkPixbuf.Pixbuf.new_from_file_at_size(
                image_file_name, 75, 75)
            # instrument_name = image_file_name[image_file_name.rfind('/'):]
            instrument_name = image_file_name[image_file_name.rfind('/') + 1:]
            instrument_name = instrument_name[:instrument_name.find('.')]
            instrument_desc = \
                self.instrumentDB.instNamed[instrument_name].nameTooltip

            file_path = os.path.join(images_path, file_name)

            # set the default icon
            if (instrument_name == 'piano'):
                self._what_search_button.set_widget_icon(file_name=file_path)

            self._instruments_store.append({
                "instrument_name":
                instrument_name,
                "pxb":
                pxb,
                "instrument_desc":
                instrument_desc,
                "file_name":
                file_path,
                "callback":
                self.__instrument_iconview_activated_cb
            })

        self._what_widget_contents = set_palette_list(self._instruments_store)
        self._what_widget.add(self._what_widget_contents)
        self._what_widget_contents.show()

        # TODO: disabe until is implemented with csnd6
        """
        for drum_number in range(0, DRUMCOUNT):
            drum_name = 'drum%dkit' % (drum_number + 1)
            self._drums_store.append({
                "instrument_name": drum_name,
                "file_name": imagefile(drum_name + '.svg'),
                "instrument_desc":
                    self.instrumentDB.instNamed[drum_name].nameTooltip,
                "callback": self.__drum_iconview_activated_cb
            })

        self._what_drum_widget_contents = set_palette_list(self._drums_store)
        self._what_drum_widget.add(self._what_drum_widget_contents)
        self._what_drum_widget_contents.show()
        """

    def __drum_iconview_activated_cb(self, widget, event, item):
        data = item['instrument_name']
        self.rythmInstrument = data
        self.csnd.load_drumkit(data)
        instrumentId = self.instrumentDB.instNamed[data].instrumentId
        for (o, n) in self.noteList:
            self.csnd.loopUpdate(n, NoteDB.PARAMETER.INSTRUMENT, instrumentId,
                                 -1)
        self.drumFillin.setInstrument(self.rythmInstrument)
        self._what_drum_search_button.set_widget_label(
            label=item['instrument_desc'])
        self._what_drum_search_button.set_widget_icon(
            file_name=item['file_name'])

    def __instrument_iconview_activated_cb(self, widget, event, item):
        self.setInstrument(item['instrument_name'])
        self._what_search_button.set_widget_icon(file_name=item['file_name'])
        self._what_search_button.set_widget_label(
            label=item['instrument_desc'])

    def set_notes_labels_cb(self, widget):
        self.piano.font_size = 16
        self.piano.set_labels(self.notes_labels)

    def set_ti_notes_labels_cb(self, widget):
        self.piano.font_size = 16
        self.piano.set_labels(self.ti_notes_labels)

    def set_keyboard_labels_cb(self, widget):
        self.piano.font_size = 25
        self.piano.set_labels(self.keyboard_letters)

    def set_german_labels_cb(self, widget):
        self.piano.font_size = 25
        self.piano.set_labels(self.german_labels)

    def beatSliderChange(self, widget, event):
        self.beat = int(self.beats_pm_button.get_value())
        self.sequencer.beat = self.beat
        self.loop.beat = self.beat
        self.drumFillin.setBeats(self.beat)
        img = int(self.scale(self.beat, 2, 12, 1, 11))
        self.beats_pm_button.set_image(imagefile('beat' + str(img) + '.svg'))
        self.beatPickup = False
        self.regenerate()
        self.beatPickup = True

    def regenerate(self):
        def flatten(ll):
            rval = []
            for l in ll:
                rval += l
            return rval

        noteOnsets = []
        notePitchs = []
        i = 0
        self.noteList = []
        self.csnd.loopClear()
        for x in flatten(
                generator(self.rythmInstrument, self.beat, 0.8,
                          self.regularity, self.reverb)):
            x.amplitude = x.amplitude * self.drumVolume
            noteOnsets.append(x.onset)
            notePitchs.append(x.pitch)
            n = Note(0, x.trackId, i, x)
            self.noteList.append((x.onset, n))
            i = i + 1
            self.csnd.loopPlay(n, 1)  # add as active
        self.csnd.loopSetNumTicks(self.beat * Config.TICKS_PER_BEAT)
        self.drumFillin.unavailable(noteOnsets, notePitchs)
        self.recordOverSensitivity(False)
        if self.playing:
            self.csnd.loopStart()

    def handlePlayRecordingButton(self, val):
        if not self.playing_recording:
            self.playing_recording = True
            self.play_recording_button.props.icon_name = 'media-playback-stop'
            self.play_recording_thread = \
                GLib.timeout_add(100, self._play_recorded_keys)
        else:
            self.playing_recording = False
            self.play_recording_button.props.icon_name = 'media-playback-start'

    def _save_ogg_cb(self, widget):
        self._wav_tempfile = tempfile.NamedTemporaryFile(mode='w+b',
                                                         suffix='.wav',
                                                         dir='/tmp/')
        self.csnd.inputMessage(Config.CSOUND_RECORD_PERF %
                               self._wav_tempfile.name)

        self.playing_recording = True
        self.play_recording_thread = \
            GLib.timeout_add(100, self._play_recorded_keys,
                             self._save_ogg_end_cb)

    def _save_ogg_end_cb(self):
        self.csnd.inputMessage(Config.CSOUND_STOP_RECORD_PERF %
                               self._wav_tempfile.name)

        self._ogg_tempfile = tempfile.NamedTemporaryFile(mode='w+b',
                                                         suffix='.ogg',
                                                         dir='/tmp/')

        line = 'filesrc location=%s ! ' \
            'wavparse ! audioconvert ! vorbisenc ! oggmux ! ' \
            'filesink location=%s' % (self._wav_tempfile.name,
                                      self._ogg_tempfile.name)
        pipe = Gst.parse_launch(line)
        pipe.get_bus().add_signal_watch()
        pipe.get_bus().connect('message::eos', self._save_ogg_eos_cb, pipe)
        pipe.set_state(Gst.State.PLAYING)

    def _save_ogg_eos_cb(self, bus, message, pipe):
        bus.remove_signal_watch()
        pipe.set_state(Gst.State.NULL)

        title = '%s saved as audio' % self.metadata['title']

        jobject = datastore.create()
        jobject.metadata['title'] = title
        jobject.metadata['keep'] = '0'
        jobject.metadata['mime_type'] = 'audio/ogg'
        jobject.file_path = self._ogg_tempfile.name
        datastore.write(jobject)

        self._wav_tempfile.close()
        self._ogg_tempfile.close()

        alert = NotifyAlert(10)
        alert.props.title = _('Audio recorded')
        alert.props.msg = _('The audio file was saved in the Journal')
        alert.connect('response', self.__alert_response_cb)
        self.add_alert(alert)

        return False

    def __alert_response_cb(self, alert, result):
        self.remove_alert(alert)

    def __record_button_click_cb(self, button):
        if not self.recording:
            self.play_recording_button.set_sensitive(False)
            self._save_as_audio_bt.set_sensitive(False)
            self.recorded_keys = []
            self.recording = True
            icon = Icon(icon_name='media-record', fill_color='#ff0000')
            icon.show()
            self.record_button.set_icon_widget(icon)
        else:
            self.recording = False
            icon = Icon(icon_name='media-record', fill_color='#ffffff')
            icon.show()
            self.record_button.set_icon_widget(icon)
            if len(self.recorded_keys) != 0:
                self.play_recording_button.set_sensitive(True)
                self._save_as_audio_bt.set_sensitive(True)

    def tempoSliderChange(self, widget, event):
        self._updateTempo(self.tempo_button.get_value())
        img = int(
            self.scale(self.tempo, PLAYER_TEMPO_LOWER, PLAYER_TEMPO_UPPER, 1,
                       9))
        self.tempo_button.set_image(imagefile('tempo' + str(img) + '.png'))

    def _updateTempo(self, val):
        self.tempo = val
        self.beatDuration = 60.0 / self.tempo
        self.ticksPerSecond = Config.TICKS_PER_BEAT * self.tempo / 60.0
        self.csnd.setTempo(self.tempo)
        self.sequencer.tempo = self.tempo
        self.drumFillin.setTempo(self.tempo)

    def handlePlayButton(self, val):
        if not self.playing:
            if not self.firstTime:
                self.regenerate()
                self.firstTime = True
            self.drumFillin.play()
            self.csnd.loopSetTick(0)
            self.csnd.loopStart()
            self.playing = True
            self._play_percussion_btn.props.icon_name = 'media-playback-stop'
        else:
            self.drumFillin.stop()
            self.sequencer.stopPlayback()
            self.csnd.loopPause()
            self.playing = False
            self._play_percussion_btn.props.icon_name = 'media-playback-start'

    def scale(self, input, input_min, input_max, output_min, output_max):
        range_input = input_max - input_min
        range_output = output_max - output_min
        result = (input - input_min) * range_output / range_input + output_min

        if (input_min > input_max and output_min > output_max) or \
           (output_min > output_max and input_min < input_max):
            if result > output_min:
                return output_min
            elif result < output_max:
                return output_max
            else:
                return result

        if (input_min < input_max and output_min < output_max) or \
           (output_min < output_max and input_min > input_max):
            if result > output_max:
                return output_max
            elif result < output_min:
                return output_min
            else:
                return result

    def handleComplexityChange(self, widget, event):
        self.regularity = self.complexity_button.get_value()
        img = int(self.complexity_button.get_value() * 7) + 1
        self.complexity_button.set_image(
            imagefile('complex' + str(img) + '.svg'))
        self.beatPickup = False
        self.regenerate()
        self.beatPickup = True

    """
    def handleBalanceSlider(self, adj):
        self.instVolume = int(adj.get_value())
        self.drumVolume = sqrt( (100-self.instVolume)*0.01 )
        self.adjustDrumVolume()
        self.drumFillin.setVolume(self.drumVolume)
        instrumentVolume = sqrt( self.instVolume*0.01 )
        self.loop.adjustLoopVolume(instrumentVolume)
        self.sequencer.adjustSequencerVolume(instrumentVolume)
        img = int(self.scale(self.instVolume,100,0,0,4.9))
        self._playToolbar.balanceSliderImgLeft.set_from_file(
                imagefile('dru' + str(img) + '.png'))
        img2 = int(self.scale(self.instVolume,0,100,0,4.9))
        self._playToolbar.balanceSliderImgRight.set_from_file(
                imagefile('instr' + str(img2) + '.png'))

    def handleReverbSlider(self, adj):
        self.reverb = adj.get_value()
        self.drumFillin.setReverb( self.reverb )
        img = int(self.scale(self.reverb,0,1,0,4))
        self._playToolbar.reverbSliderImgRight.set_from_file(
                imagefile('reverb' + str(img) + '.png'))
        self.keyboardStandAlone.setReverb(self.reverb)
    """

    def set_keyboard_no_labels_cb(self, widget):
        self.piano.font_size = 25
        self.piano.set_labels(None)

    def enableKeyboard(self):
        self.keyboardStandAlone = KeyboardStandAlone(
            self.sequencer.recording, self.sequencer.adjustDuration,
            self.csnd.loopGetTick, self.sequencer.getPlayState, self.loop)
        self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)

    def setInstrument(self, instrument):
        logging.debug("Set Instrument: %s" % instrument)
        self.instrument = instrument
        self.keyboardStandAlone.setInstrument(instrument)
        self.csnd.load_instrument(instrument)

    def recordStateButton(self, button, state):
        pass
#        if button == 1:
#            self._recordToolbar.keyboardRecButton.set_active( state )
#        else:
#            self._recordToolbar.keyboardRecOverButton.set_active( state )

    def recordOverSensitivity(self, state):
        pass
        # self._recordToolbar.keyboardRecOverButton.set_sensitive( state )

    def _play_recorded_keys(self, end_cb=None):
        GLib.source_remove(self.play_recording_thread)
        letter = self.recorded_keys[self.play_index]
        time_difference = 0
        if self.play_index == len(self.recorded_keys) - 1:
            time_difference = \
                self.recorded_keys[self.play_index][0] - \
                self.recorded_keys[self.play_index - 1][0]
        else:
            next_time = self.recorded_keys[self.play_index + 1][0]
            time_difference = next_time - letter[0]

        if not self.playing_recording:
            self.play_recording_button.props.icon_name = 'media-playback-start'
            return

        if letter[-1] == 1:
            self.keyboardStandAlone.do_key_release(
                LETTERS_TO_KEY_CODES[letter[3]])
            GLib.idle_add(self.piano.physical_key_changed,
                          LETTERS_TO_KEY_CODES[letter[3]], False)
        else:
            self.keyboardStandAlone.do_key_press(
                LETTERS_TO_KEY_CODES[letter[3]], None,
                math.sqrt(self.instVolume * 0.01))
            GLib.idle_add(self.piano.physical_key_changed,
                          LETTERS_TO_KEY_CODES[letter[3]], True)

        if self.play_index == len(self.recorded_keys) - 1:
            self.play_index = 0
            self.play_recording_button.props.icon_name = 'media-playback-start'
            self.playing_recording = False
            if end_cb is not None:
                end_cb()
        else:
            self.play_index += 1
            self.play_recording_thread = \
                GLib.timeout_add(int((time_difference) * 1000),
                                 self._play_recorded_keys, end_cb)

    def __key_pressed_cb(self, widget, octave_clicked, key_clicked, letter,
                         physicallKey):
        logging.debug('Pressed Octave: %d Key: %d Letter: %s' %
                      (octave_clicked, key_clicked, letter))
        if letter in LETTERS_TO_KEY_CODES.keys():
            if self.recording:
                self.recorded_keys.append(
                    [time.time(), octave_clicked, key_clicked, letter])
            if not physicallKey:
                self.keyboardStandAlone.do_key_press(
                    LETTERS_TO_KEY_CODES[letter], None,
                    math.sqrt(self.instVolume * 0.01))

    def __key_released_cb(self, widget, octave_clicked, key_clicked, letter,
                          physicallKey):
        if self.recording:
            self.recorded_keys.append(
                [time.time(), octave_clicked, key_clicked, letter, 1])
        if not physicallKey:
            if letter in LETTERS_TO_KEY_CODES.keys():
                self.keyboardStandAlone.do_key_release(
                    LETTERS_TO_KEY_CODES[letter])

    def onKeyPress(self, widget, event):
        if event.state & Gdk.ModifierType.CONTROL_MASK:
            return
        if event.hardware_keycode == 37:
            if self.muteInst:
                self.muteInst = False
            else:
                self.muteInst = True
        self.piano.physical_key_changed(event.hardware_keycode, True)
        self.keyboardStandAlone.onKeyPress(widget, event,
                                           math.sqrt(self.instVolume * 0.01))

    def onKeyRelease(self, widget, event):
        self.keyboardStandAlone.onKeyRelease(widget, event)
        self.piano.physical_key_changed(event.hardware_keycode, False)

    def write_file(self, file_path):
        f = open(file_path, 'w')
        # substract the initial time to all the saved values
        if len(self.recorded_keys) > 0:
            initial_time = self.recorded_keys[0][0]
            for key in self.recorded_keys:
                key[0] = key[0] - initial_time

        f.write(json.dumps(self.recorded_keys))
        f.close()

    def read_file(self, file_path):
        f = open(file_path, 'r')
        contents = f.read().strip()

        self.recorded_keys = json.loads(contents)
        if len(self.recorded_keys) != 0:
            self.play_recording_button.set_sensitive(True)
            self._save_as_audio_bt.set_sensitive(True)
        f.close()

    def close(self, skip_save=False):
        self.csnd.stop()  # without which Csound will segfault
        activity.Activity.close(self, skip_save=skip_save)
Ejemplo n.º 44
0
class SpeechToolbar(Gtk.Toolbar):
    def __init__(self, activity):
        GObject.GObject.__init__(self)
        self._activity = activity
        if not speech.supported:
            return
        self.is_paused = False
        self.load_speech_parameters()

        self.sorted_voices = [i for i in speech.voices()]
        self.sorted_voices.sort(self.compare_voices)
        default = 0
        for voice in self.sorted_voices:
            if voice[0] == speech.voice[0]:
                break
            default = default + 1

        # Play button
        self.play_btn = ToggleToolButton('media-playback-start')
        self.play_btn.show()
        self.play_toggled_handler = self.play_btn.connect(
            'toggled', self.play_cb)
        self.insert(self.play_btn, -1)
        self.play_btn.set_tooltip(_('Play / Pause'))

        # Stop button
        self.stop_btn = ToolButton('media-playback-stop')
        self.stop_btn.show()
        self.stop_btn.connect('clicked', self.stop_cb)
        self.stop_btn.set_sensitive(False)
        self.insert(self.stop_btn, -1)
        self.stop_btn.set_tooltip(_('Stop'))

        self.voice_combo = ComboBox()
        for voice in self.sorted_voices:
            self.voice_combo.append_item(voice, voice[0])
        self.voice_combo.set_active(default)

        self.voice_combo.connect('changed', self.voice_changed_cb)
        combotool = ToolComboBox(self.voice_combo)
        self.insert(combotool, -1)
        combotool.show()
        speech.reset_cb = self.reset_buttons_cb
        speech.end_text_cb = self.reset_buttons_cb

    def compare_voices(self, a, b):
        if a[0].lower() == b[0].lower():
            return 0
        if a[0].lower() < b[0].lower():
            return -1
        if a[0].lower() > b[0].lower():
            return 1

    def voice_changed_cb(self, combo):
        speech.voice = combo.props.value
        speech.say(speech.voice[0])
        self.save_speech_parameters()

    def load_speech_parameters(self):
        speech_parameters = {}
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        if os.path.exists(data_file_name):
            f = open(data_file_name, 'r')
            try:
                speech_parameters = json.load(f)
                speech.voice = speech_parameters['voice']
            finally:
                f.close()

    def save_speech_parameters(self):
        speech_parameters = {}
        speech_parameters['voice'] = speech.voice
        data_path = os.path.join(self._activity.get_activity_root(), 'data')
        data_file_name = os.path.join(data_path, 'speech_params.json')
        f = open(data_file_name, 'w')
        try:
            json.dump(speech_parameters, f)
        finally:
            f.close()

    def reset_buttons_cb(self):
        logging.error('reset buttons')
        self.play_btn.set_icon_name('media-playback-start')
        self.stop_btn.set_sensitive(False)
        self.play_btn.handler_block(self.play_toggled_handler)
        self.play_btn.set_active(False)
        self.play_btn.handler_unblock(self.play_toggled_handler)
        self.is_paused = False

    def play_cb(self, widget):
        self.stop_btn.set_sensitive(True)
        if widget.get_active():
            self.play_btn.set_icon_name('media-playback-pause')
            logging.error('Paused %s', self.is_paused)
            if not self.is_paused:
                # get the text to speech, if there are a selection,
                # play selected text, if not, play all
                abi = self._activity.abiword_canvas
                selection = abi.get_selection('text/plain')
                if not selection or selection[0] is None or selection[1] == 0:
                    # nothing selected
                    abi.select_all()
                    text = abi.get_selection('text/plain')[0]
                    abi.moveto_bod()
                else:
                    text = selection[0]
                speech.play(text)
            else:
                logging.error('Continue play')
                speech.continue_play()
        else:
            self.play_btn.set_icon_name('media-playback-start')
            self.is_paused = True
            speech.pause()

    def stop_cb(self, widget):
        self.stop_btn.set_sensitive(False)
        self.play_btn.set_icon_name('media-playback-start')
        self.play_btn.set_active(False)
        self.is_paused = False
        speech.stop()
Ejemplo n.º 45
0
class ViewToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ViewToolbar'

    __gsignals__ = {
        'go-fullscreen':
        (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([])),
        'toggle-index-show':
        (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([bool])),
        'toggle-tray-show':
        (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([bool])),
    }

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

        self._view = None

        self._navigator_button = ToggleToolButton('view-list')
        self._navigator_button.set_tooltip(_('Table of contents'))
        self._navigator_button.connect('toggled', self.__navigator_toggled_cb)
        self.insert(self._navigator_button, -1)

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

        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-to-width')
        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()

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

        self._zoom_to_original = ToolButton('zoom-original')
        self._zoom_to_original.set_tooltip(_('Actual size'))
        self._zoom_to_original.connect('clicked', self._actual_size_cb)
        self.insert(self._zoom_to_original, -1)
        self._zoom_to_original.show()

        spacer = Gtk.SeparatorToolItem()
        spacer.props.draw = True
        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.traybutton = ToggleToolButton('tray-show')
        self.traybutton.set_icon_name('tray-favourite')
        self.traybutton.connect('toggled', self.__tray_toggled_cb)
        self.traybutton.props.active = False
        self.insert(self.traybutton, -1)
        self.traybutton.show()

        self._view_notify_zoom_handler = None

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

        self._rotate_left = ToolButton('rotate_anticlockwise')
        self._rotate_left.set_tooltip(_('Rotate left'))
        self._rotate_left.connect('clicked', self._rotate_left_cb)
        self.insert(self._rotate_left, -1)
        self._rotate_left.show()

        self._rotate_right = ToolButton('rotate_clockwise')
        self._rotate_right.set_tooltip(_('Rotate right'))
        self._rotate_right.connect('clicked', self._rotate_right_cb)
        self.insert(self._rotate_right, -1)
        self._rotate_right.show()

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

    def show_nav_button(self):
        self._navigator_button.show()
        self._spacer_navigator.show()

    def zoom_in(self):
        self._view.zoom_in()
        self._update_zoom_buttons()

    def _zoom_in_cb(self, button):
        self.zoom_in()

    def _rotate_left_cb(self, button):
        self._view.rotate_left()

    def _rotate_right_cb(self, button):
        self._view.rotate_right()

    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 __navigator_toggled_cb(self, button):
        self.emit('toggle-index-show', button.get_active())

    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()
        self._zoom_to_fit.props.sensitive = self._view.can_zoom_to_width()
        self._zoom_to_original.props.sensitive = self._view.can_zoom_to_width()
        self._rotate_left.props.sensitive = self._view.can_rotate()
        self._rotate_right.props.sensitive = self._view.can_rotate()

    def _zoom_to_fit_cb(self, menu_item):
        self._view.zoom_to_best_fit()
        self._update_zoom_buttons()

    def _actual_size_cb(self, menu_item):
        self._view.zoom_to_actual_size()
        self._update_zoom_buttons()

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

    def __tray_toggled_cb(self, button):
        self.emit('toggle-tray-show', button.get_active())
        if button.props.active:
            self.traybutton.set_tooltip(_('Show Tray'))
        else:
            self.traybutton.set_tooltip(_('Hide Tray'))
Ejemplo n.º 46
0
class MemorizeActivity(Activity):

    def __init__(self, handle):
        Activity.__init__(self, handle)

        self.play_mode = None

        toolbar_box = ToolbarBox()
        self.set_toolbar_box(toolbar_box)

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

        self._memorizeToolbarBuilder = \
            memorizetoolbar.MemorizeToolbarBuilder(self)

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

        self._edit_button = ToggleToolButton('view-source')
        self._edit_button.set_tooltip(_('Edit game'))
        self._edit_button.set_active(False)
        toolbar_box.toolbar.insert(self._edit_button, -1)

        self._createToolbarBuilder = \
            createtoolbar.CreateToolbarBuilder(self)

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

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

        self.game = game.MemorizeGame()
        # Play game mode
        self.table = cardtable.CardTable()
        self.scoreboard = scoreboard.Scoreboard()
        self.cardlist = cardlist.CardList()
        self.createcardpanel = createcardpanel.CreateCardPanel(self.game)
        self.cardlist.connect('pair-selected',
                              self.createcardpanel.pair_selected)
        self.cardlist.connect(
            'update-create-toolbar',
            self._createToolbarBuilder.update_create_toolbar)
        self.createcardpanel.connect('add-pair',
                                     self.cardlist.add_pair)
        self.createcardpanel.connect('update-pair',
                                     self.cardlist.update_selected)
        self.createcardpanel.connect('change-font',
                                     self.cardlist.change_font)
        self.createcardpanel.connect('pair-closed',
                                     self.cardlist.rem_current_pair)

        self._createToolbarBuilder.connect('create_new_game',
                                           self.cardlist.clean_list)
        self._createToolbarBuilder.connect('create_new_game',
                                           self.createcardpanel.clean)
        self._createToolbarBuilder.connect(
            'create_new_game',
            self._memorizeToolbarBuilder.reset)
        self._createToolbarBuilder.connect('create_equal_pairs',
                                           self.change_equal_pairs)

        self._edit_button.connect('toggled', self._change_mode_bt)

        self.connect('key-press-event', self.table.key_press_event)
        self.table.connect('card-flipped', self.game.card_flipped)
        self.table.connect('card-highlighted', self.game.card_highlighted)

        self.game.connect('set-border', self.table.set_border)
        self.game.connect('flop-card', self.table.flop_card)
        self.game.connect('flip-card', self.table.flip_card)
        self.game.connect('cement-card', self.table.cement_card)
        self.game.connect('highlight-card', self.table.highlight_card)
        self.game.connect('load_mode', self.table.load_msg)

        self.game.connect('msg_buddy', self.scoreboard.set_buddy_message)
        self.game.connect('add_buddy', self.scoreboard.add_buddy)
        self.game.connect('rem_buddy', self.scoreboard.rem_buddy)
        self.game.connect('increase-score', self.scoreboard.increase_score)
        self.game.connect('wait_mode_buddy', self.scoreboard.set_wait_mode)
        self.game.connect('change-turn', self.scoreboard.set_selected)
        self.game.connect('change_game', self.scoreboard.change_game)

        self.game.connect('reset_scoreboard', self.scoreboard.reset)
        self.game.connect('reset_table', self.table.reset)

        self.game.connect('load_game', self.table.load_game)
        self.game.connect('change_game', self.table.change_game)
        self.game.connect('load_game',
                          self._memorizeToolbarBuilder.update_toolbar)
        self.game.connect('change_game',
                          self._memorizeToolbarBuilder.update_toolbar)
        self.game.connect('change_game',
                          self.createcardpanel.update_font_combos)

        self._memorizeToolbarBuilder.connect('game_changed',
                                             self.change_game)

        self.box = Gtk.HBox(orientation=Gtk.Orientation.VERTICAL,
                            homogeneous=False)

        width = Gdk.Screen.width()
        height = Gdk.Screen.height() - style.GRID_CELL_SIZE
        self.table.resize(width, height - style.GRID_CELL_SIZE)
        self.scoreboard.set_size_request(-1, style.GRID_CELL_SIZE)
        self.box.pack_start(self.table, True, True, 0)
        self.box.pack_start(self.scoreboard, False, False, 0)
        self.set_canvas(self.box)

        # connect to the in/out events of the memorize activity
        self.connect('focus_in_event', self._focus_in)
        self.connect('focus_out_event', self._focus_out)
        self.connect('destroy', self._cleanup_cb)

        self.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
        self.connect('motion_notify_event',
                     lambda widget, event: face.look_at())

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

        # start on the game toolbar, might change this
        # to the create toolbar later
        self._change_mode(_MODE_PLAY)

        # Get the Presence Service
        self.pservice = presenceservice.get_instance()
        self.initiating = None

        # Buddy object for you
        owner = self.pservice.get_owner()
        self.owner = owner
        self.current = 0

        self.game.set_myself(self.owner)
        self.connect('shared', self._shared_cb)

        # Owner.props.key
        if self.get_shared_activity():
            # We are joining the activity
            self.connect('joined', self._joined_cb)
            if self.get_shared():
                # We've already joined
                self._joined_cb(self)
        elif not self._jobject.file_path:
            logging.debug('buddy joined - __init__: %s', self.owner.props.nick)
            game_file = os.path.join(os.path.dirname(__file__), 'demos',
                                     'addition.zip')
            self.game.load_game(game_file, 4, 'demo')
            logging.debug('loading conventional')
            self.game.add_buddy(self.owner)
        else:
            self.game.add_buddy(self.owner)
        self.show_all()

    def __configure_cb(self, event):
        ''' Screen size has changed '''
        width = Gdk.Screen.width()
        height = Gdk.Screen.height() - style.GRID_CELL_SIZE
        self.box.set_size_request(width, height)
        self.scoreboard.set_size_request(-1, style.GRID_CELL_SIZE)
        self.table.resize(width, height - style.GRID_CELL_SIZE)
        self.show_all()

    def _change_mode_bt(self, button):
        if button.get_active():
            self._change_mode(_MODE_CREATE)
            button.set_icon_name('player_play')
            button.set_tooltip(_('Play game'))
        else:
            self._change_mode(_MODE_PLAY)
            button.set_icon_name('view-source')
            button.set_tooltip(_('Edit game'))

    def read_file(self, file_path):
        if 'icon-color' in self.metadata:
            color = self.metadata['icon-color']
        else:
            color = profile.get_color().to_string()
        self.change_game(None, file_path, 4, 'file',
                         self.metadata['title'], color)

    def write_file(self, file_path):
        logging.debug('WRITE_FILE is_demo %s', self.game.model.is_demo)
        if self.game.model.is_demo:
            # if is a demo game only want keep the metadata
            self._jobject.set_file_path(None)
            raise NotImplementedError
            return
        if self.cardlist.pair_list_modified:
            self.cardlist.update_model(self.game.model)

        temp_img_folder = self.game.model.data['pathimg']
        temp_snd_folder = self.game.model.data['pathsnd']
        self.game.model.create_temp_directories()
        game_zip = zipfile.ZipFile(file_path, 'w')
        save_image_and_sound = True
        if 'origin' in self.game.model.data:
            if self.game.model.data['origin'] == 'art4apps':
                # we don't need save images and audio files
                # for art4apps games
                save_image_and_sound = False

        if save_image_and_sound:
            for pair in self.game.model.pairs:
                # aimg
                aimg = self.game.model.pairs[pair].get_property('aimg')
                logging.error('saving image a %s', aimg)
                if aimg is not None:
                    game_zip.write(os.path.join(temp_img_folder, aimg),
                                   os.path.join('images', aimg))

                # bimg
                bimg = self.game.model.pairs[pair].get_property('bimg')
                logging.error('saving image b %s', bimg)
                if bimg is not None:
                    game_zip.write(os.path.join(temp_img_folder, bimg),
                                   os.path.join('images', bimg))

                # asnd
                asnd = self.game.model.pairs[pair].get_property('asnd')
                if asnd is not None:
                    if os.path.exists(os.path.join(temp_snd_folder, asnd)):
                        game_zip.write(os.path.join(temp_snd_folder, asnd),
                                       os.path.join('sounds', asnd))

                # bsnd
                bsnd = self.game.model.pairs[pair].get_property('bsnd')
                if bsnd is not None:
                    if os.path.exists(os.path.join(temp_snd_folder, bsnd)):
                        game_zip.write(os.path.join(temp_snd_folder, bsnd),
                                       os.path.join('sounds', bsnd))

        self.game.model.game_path = self.game.model.temp_folder
        self.game.model.data['name'] = str(self.get_title())
        self.game.model.write()
        game_zip.write(os.path.join(self.game.model.temp_folder, 'game.xml'),
                       'game.xml')
        game_zip.close()
        self.metadata['mime_type'] = 'application/x-memorize-project'

    def _complete_close(self):
        self._remove_temp_files()
        Activity._complete_close(self)

    def _remove_temp_files(self):
        tmp_root = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'], 'instance')
        for root, dirs, files in os.walk(tmp_root, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))

    def _change_mode(self, mode):
        logging.debug("Change mode %s" % mode)
        if mode == _MODE_CREATE:
            if self.play_mode:

                self.box.remove(self.scoreboard)
                self.box.remove(self.table)
                self.createcardpanel.update_orientation()
                self.box.pack_start(self.createcardpanel, True, True, 0)
                self.box.pack_start(self.cardlist, False, False, 0)
                self.cardlist.load_game(self.game)
                self.game.model.create_temp_directories()
                self.createcardpanel.set_temp_folder(
                    self.game.model.temp_folder)
            self.play_mode = False
        else:
            if self.game.model.modified:
                self.cardlist.update_model(self.game.model)
                self.save()
                self.game.reset_game()
                self.table.change_game(None, self.game.model.data,
                                       self.game.model.grid)
                self.game.model.modified = False

            if not self.play_mode:
                self.box.remove(self.createcardpanel)
                self.box.remove(self.cardlist)

            if self.play_mode in (False, None):
                self.box.pack_start(self.table, True, True, 0)
                self.box.pack_start(self.scoreboard, False, False, 0)
            self.play_mode = True
        self._memorizeToolbarBuilder.update_controls(mode == _MODE_PLAY)
        self._createToolbarBuilder.update_controls(mode == _MODE_CREATE)

    def change_game(self, widget, game_name, size, mode,
                    title=None, color=None):
        logging.debug('Change game %s', game_name)
        self.game.change_game(widget, game_name, size, mode, title, color)
        self.cardlist.game_loaded = False

    def change_equal_pairs(self, widget, state):
        self.cardlist.update_model(self.game.model)
        self.createcardpanel.change_equal_pairs(widget, state)

    def _shared_cb(self, activity):
        logging.debug('My activity was shared')
        self.initiating = True
        self._sharing_setup()

        logging.debug('This is my activity: making a tube...')
        self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube(
            SERVICE, {})

    def _sharing_setup(self):
        if self.get_shared_activity() is None:
            logging.error('Failed to share or join activity')
            return
        shared_activity = self.get_shared_activity()
        self.conn = shared_activity.telepathy_conn
        self.tubes_chan = shared_activity.telepathy_tubes_chan
        self.text_chan = shared_activity.telepathy_text_chan

        self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal(
            'NewTube', self._new_tube_cb)

        shared_activity.connect('buddy-joined', self._buddy_joined_cb)
        shared_activity.connect('buddy-left', self._buddy_left_cb)

    def _list_tubes_reply_cb(self, tubes):
        for tube_info in tubes:
            self._new_tube_cb(*tube_info)

    def _list_tubes_error_cb(self, e):
        logging.error('ListTubes() failed: %s', e)

    def _joined_cb(self, activity):
        if not self.get_shared_activity():
            return

        logging.debug('Joined an existing shared activity')

        for buddy in self.get_shared_activity().get_joined_buddies():
            if buddy != self.owner:
                logging.debug("buddy joined - _joined_cb: %s  "
                              "(get buddies and add them to my list)",
                              buddy.props.nick)
                self.game.add_buddy(buddy)

        self.game.add_buddy(self.owner)
        self.initiating = False
        self._sharing_setup()

        logging.debug('This is not my activity: waiting for a tube...')
        self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes(
            reply_handler=self._list_tubes_reply_cb,
            error_handler=self._list_tubes_error_cb)

    def _new_tube_cb(self, identifier, initiator, tube_type, service,
                     params, state):
        logging.debug('New tube: ID=%d initator=%d type=%d service=%s '
                      'params=%r state=%d', identifier, initiator, tube_type,
                      service, params, state)

        if (tube_type == telepathy.TUBE_TYPE_DBUS and
                service == SERVICE):
            if state == telepathy.TUBE_STATE_LOCAL_PENDING:
                self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(
                    identifier)

            self.tube_conn = TubeConnection(
                self.conn,
                self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES], identifier,
                group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP])

            self.messenger = messenger.Messenger(self.tube_conn,
                                                 self.initiating,
                                                 self._get_buddy, self.game)
            self.game.connect('flip-card-signal', self.messenger.flip_sender)
            self.game.connect('change_game_signal', self.messenger.change_game)

    def _get_buddy(self, cs_handle):
        """Get a Buddy from a channel specific handle."""
        group = self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]
        my_csh = group.GetSelfHandle()
        if my_csh == cs_handle:
            handle = self.conn.GetSelfHandle()
        else:
            handle = group.GetHandleOwners([cs_handle])[0]
            assert handle != 0
        return self.pservice.get_buddy_by_telepathy_handle(
            self.tp_conn_name, self.tp_conn_path, handle)

    def _buddy_joined_cb(self, activity, buddy):
        if buddy != self.owner:
            if buddy.props.nick == '':
                logging.debug("buddy joined: empty nick=%s. Will not add.",
                              buddy.props.nick)
            else:
                logging.debug("buddy joined: %s", buddy.props.nick)
                self.game.add_buddy(buddy)

    def _buddy_left_cb(self, activity, buddy):
        if buddy.props.nick == '':
            logging.debug("buddy joined: empty nick=%s. Will not remove",
                          buddy.props.nick)
        else:
            logging.debug("buddy left: %s", buddy.props.nick)
            self.game.rem_buddy(buddy)

    def _focus_in(self, event, data=None):
        self.game.audio.play()

    def _focus_out(self, event, data=None):
        self.game.audio.pause()

    def _cleanup_cb(self, data=None):
        self.game.audio.stop()
Ejemplo n.º 47
0
class MainToolbox(ToolbarBox):

    __gsignals__ = {
        'query-changed': (GObject.SignalFlags.RUN_FIRST, None,
                          ([object])),
    }

    def __init__(self):
        ToolbarBox.__init__(self)

        self._mount_point = None
        self._filter_type = None
        self._what_filter = None

        self.search_entry = iconentry.IconEntry()
        self.search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                             'entry-search')
        text = _('Search in %s') % _('Journal')
        self.search_entry.set_placeholder_text(text)
        self.search_entry.connect('activate', self._search_entry_activated_cb)
        self.search_entry.connect('changed', self._search_entry_changed_cb)
        self.search_entry.add_clear_button()
        self._autosearch_timer = None
        self._add_widget(self.search_entry, expand=True)

        self._favorite_button = ToggleToolButton('emblem-favorite')
        self._favorite_button.set_tooltip(_('Favorite entries'))
        self._favorite_button.connect('toggled',
                                      self.__favorite_button_toggled_cb)
        self.toolbar.insert(self._favorite_button, -1)
        self._favorite_button.show()

        self._what_search_combo = ComboBox()
        self._what_combo_changed_sid = self._what_search_combo.connect(
            'changed', self._combo_changed_cb)
        tool_item = ToolComboBox(self._what_search_combo)
        self.toolbar.insert(tool_item, -1)
        tool_item.show()

        self._when_search_combo = self._get_when_search_combo()
        tool_item = ToolComboBox(self._when_search_combo)
        self.toolbar.insert(tool_item, -1)
        tool_item.show()

        self._sorting_button = SortingButton()
        self.toolbar.insert(self._sorting_button, -1)
        self._sorting_button.connect('sort-property-changed',
                                     self.__sort_changed_cb)
        self._sorting_button.show()

        # TODO: enable it when the DS supports saving the buddies.
        # self._with_search_combo = self._get_with_search_combo()
        # tool_item = ToolComboBox(self._with_search_combo)
        # self.insert(tool_item, -1)
        # tool_item.show()

        self._query = self._build_query()

        self.refresh_filters()

    def _get_when_search_combo(self):
        when_search = ComboBox()
        when_search.append_item(_ACTION_ANYTIME, _('Anytime'))
        when_search.append_separator()
        when_search.append_item(_ACTION_TODAY, _('Today'))
        when_search.append_item(_ACTION_SINCE_YESTERDAY,
                                _('Since yesterday'))
        # TRANS: Filter entries modified during the last 7 days.
        when_search.append_item(_ACTION_PAST_WEEK, _('Past week'))
        # TRANS: Filter entries modified during the last 30 days.
        when_search.append_item(_ACTION_PAST_MONTH, _('Past month'))
        # TRANS: Filter entries modified during the last 356 days.
        when_search.append_item(_ACTION_PAST_YEAR, _('Past year'))
        when_search.set_active(0)
        when_search.connect('changed', self._combo_changed_cb)
        return when_search

    def _get_with_search_combo(self):
        with_search = ComboBox()
        with_search.append_item(_ACTION_EVERYBODY, _('Anyone'))
        with_search.append_separator()
        with_search.append_item(_ACTION_MY_FRIENDS, _('My friends'))
        with_search.append_item(_ACTION_MY_CLASS, _('My class'))
        with_search.append_separator()

        # TODO: Ask the model for buddies.
        with_search.append_item(3, 'Dan', 'theme:xo')

        with_search.set_active(0)
        with_search.connect('changed', self._combo_changed_cb)
        return with_search

    def _add_widget(self, widget, expand=False):
        tool_item = Gtk.ToolItem()
        tool_item.set_expand(expand)

        tool_item.add(widget)
        widget.show()

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

    def _build_query(self):
        query = {}

        if self._mount_point:
            query['mountpoints'] = [self._mount_point]

        if self._favorite_button.props.active:
            query['keep'] = 1

        if self._what_search_combo.props.value:
            value = self._what_search_combo.props.value
            filter_type = self._filter_type
            if self._filter_type is None:
                # for backward compatibility, try to guess the filter
                generic_type = mime.get_generic_type(value)
                if generic_type:
                    filter_type = FILTER_TYPE_GENERIC_MIME
                else:
                    filter_type = FILTER_TYPE_ACTIVITY
                logging.error('DEPRECATED: sety the filter_type parameter')

            if filter_type == FILTER_TYPE_GENERIC_MIME:
                generic_type = mime.get_generic_type(value)
                if generic_type:
                    mime_types = generic_type.mime_types
                    query['mime_type'] = mime_types
                else:
                    logging.error('filter_type="generic_mime", '
                                  'but "%s" is not a generic mime' % value)

            elif filter_type == FILTER_TYPE_ACTIVITY:
                query['activity'] = value

            elif self._filter_type == FILTER_TYPE_MIME_BY_ACTIVITY:
                registry = bundleregistry.get_registry()
                bundle = \
                    registry.get_bundle(value)
                if bundle is not None:
                    query['mime_type'] = bundle.get_mime_types()
                else:
                    logging.error('Trying to filter using activity mimetype '
                                  'but bundle id is wrong %s' % value)

        if self._when_search_combo.props.value:
            date_from, date_to = self._get_date_range()
            query['timestamp'] = {'start': date_from, 'end': date_to}

        if self.search_entry.props.text:
            text = self.search_entry.props.text.strip()
            if text:
                query['query'] = text

        property_, order = self._sorting_button.get_current_sort()

        if order == Gtk.SortType.ASCENDING:
            sign = '+'
        else:
            sign = '-'
        query['order_by'] = [sign + property_]

        return query

    def _get_date_range(self):
        today_start = datetime.today().replace(hour=0, minute=0, second=0)
        right_now = datetime.today()
        if self._when_search_combo.props.value == _ACTION_TODAY:
            date_range = (today_start, right_now)
        elif self._when_search_combo.props.value == _ACTION_SINCE_YESTERDAY:
            date_range = (today_start - timedelta(1), right_now)
        elif self._when_search_combo.props.value == _ACTION_PAST_WEEK:
            date_range = (today_start - timedelta(7), right_now)
        elif self._when_search_combo.props.value == _ACTION_PAST_MONTH:
            date_range = (today_start - timedelta(30), right_now)
        elif self._when_search_combo.props.value == _ACTION_PAST_YEAR:
            date_range = (today_start - timedelta(356), right_now)

        return (time.mktime(date_range[0].timetuple()),
                time.mktime(date_range[1].timetuple()))

    def _combo_changed_cb(self, combo):
        self._update_if_needed()

    def __sort_changed_cb(self, button):
        self._update_if_needed()

    def _update_if_needed(self):
        # check if the what_search combo should be visible
        self._what_search_combo.set_visible(
            self._filter_type != FILTER_TYPE_MIME_BY_ACTIVITY)

        new_query = self._build_query()
        if self._query != new_query:
            self._query = new_query
            self.emit('query-changed', self._query)

    def _search_entry_activated_cb(self, search_entry):
        if self._autosearch_timer:
            GObject.source_remove(self._autosearch_timer)
        self._update_if_needed()

    def _search_entry_changed_cb(self, search_entry):
        if not search_entry.props.text:
            search_entry.activate()
            return

        if self._autosearch_timer:
            GObject.source_remove(self._autosearch_timer)
        self._autosearch_timer = GObject.timeout_add(_AUTOSEARCH_TIMEOUT,
                                                     self._autosearch_timer_cb)

    def _autosearch_timer_cb(self):
        logging.debug('_autosearch_timer_cb')
        self._autosearch_timer = None
        self.search_entry.activate()
        return False

    def set_mount_point(self, mount_point):
        self._mount_point = mount_point
        self._update_if_needed()

    def set_what_filter(self, what_filter):
        combo_model = self._what_search_combo.get_model()
        what_filter_index = -1
        for i in range(0, len(combo_model) - 1):
            if combo_model[i][0] == what_filter:
                what_filter_index = i
                break

        if what_filter_index == -1:
            logging.warning('what_filter %r not known', what_filter)
        else:
            self._what_search_combo.set_active(what_filter_index)

    def update_filters(self, mount_point, what_filter, filter_type=None):
        self._mount_point = mount_point
        self._filter_type = filter_type
        self._what_filter = what_filter
        self.set_what_filter(what_filter)
        self._update_if_needed()

    def set_filter_type(self, filter_type):
        self._filter_type = filter_type
        self._update_if_needed()

    def refresh_filters(self):
        current_value = self._what_search_combo.props.value
        current_value_index = 0

        self._what_search_combo.handler_block(self._what_combo_changed_sid)
        try:
            self._what_search_combo.remove_all()
            # TRANS: Item in a combo box that filters by entry type.
            self._what_search_combo.append_item(_ACTION_ANYTHING,
                                                _('Anything'))

            registry = bundleregistry.get_registry()
            appended_separator = False

            types = mime.get_all_generic_types()
            for generic_type in types:
                if not appended_separator:
                    self._what_search_combo.append_separator()
                    appended_separator = True
                self._what_search_combo.append_item(
                    generic_type.type_id, generic_type.name, generic_type.icon)
                if generic_type.type_id == current_value:
                    current_value_index = \
                        len(self._what_search_combo.get_model()) - 1

                self._what_search_combo.set_active(current_value_index)

            self._what_search_combo.append_separator()

            for service_name in model.get_unique_values('activity'):
                activity_info = registry.get_bundle(service_name)
                if activity_info is None:
                    continue

                if service_name == current_value:
                    combo_model = self._what_search_combo.get_model()
                    current_value_index = len(combo_model)

                # try activity-provided icon
                if os.path.exists(activity_info.get_icon()):
                    try:
                        self._what_search_combo.append_item(
                            service_name,
                            activity_info.get_name(),
                            file_name=activity_info.get_icon())
                    except GObject.GError, exception:
                        logging.warning('Falling back to default icon for'
                                        ' "what" filter because %r (%r) has an'
                                        ' invalid icon: %s',
                                        activity_info.get_name(),
                                        str(service_name), exception)
                    else:
                        continue

                # fall back to generic icon
                self._what_search_combo.append_item(
                    service_name,
                    activity_info.get_name(),
                    icon_name='application-octet-stream')

        finally:
            self._what_search_combo.handler_unblock(
                self._what_combo_changed_sid)

    def __favorite_button_toggled_cb(self, favorite_button):
        self._update_if_needed()

    def clear_query(self):
        self.search_entry.props.text = ''
        if self._what_filter is None:
            self._what_search_combo.set_active(0)
        else:
            self.set_what_filter(self._what_filter)
        self._when_search_combo.set_active(0)
        self._favorite_button.props.active = False
Ejemplo n.º 48
0
class SimplePianoActivity(activity.Activity):
    """SimplePianoActivity class as specified in activity.info"""

    def __init__(self, handle):
        activity.Activity.__init__(self, handle)
        GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.close)
        Gst.init(None)

        self._what_list = []

        self.play_recording_thread = None

        self.playing_recording = False
        self.firstTime = False
        self.playing = False
        self.regularity = 0.7
        self._drums_store = []
        self.recording = False
        self.recorded_keys = []
        self.is_valid_recording = False

        # we do not have collaboration features
        # make the share option insensitive
        self.max_participants = 1
        self.csnd = new_csound_client()
        self.rythmInstrument = 'drum1kick'
        # toolbar with the new toolbar redesign
        toolbar_box = ToolbarBox()
        activity_button = ActivityToolbarButton(self)
        toolbar_box.toolbar.insert(activity_button, 0)
        toolbar_box.toolbar.set_style(Gtk.ToolbarStyle.BOTH_HORIZ)

        self.play_index = 0

        self.play_recording_button = ToolButton(
            icon_name='media-playback-start')
        self.play_recording_button.set_property('can-default', True)
        self.play_recording_button.show()
        self.record_button = ToggleToolButton(icon_name='media-record')
        self.record_button.set_property('can-default', True)
        self.record_button.show()
        self.play_recording_button.set_sensitive(False)

        self.record_button.connect('clicked', self.__record_button_click_cb)

        self.play_recording_button.connect('clicked',
                                           self.handlePlayRecordingButton)

        toolbar_box.toolbar.set_style(Gtk.ToolbarStyle.BOTH_HORIZ)

        # TODO: disabe until is implemented with csnd6
        # self.createPercussionToolbar(toolbar_box)

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

        keybord_labels = RadioToolButton()
        keybord_labels.props.icon_name = 'q_key'
        keybord_labels.props.group = keybord_labels
        keybord_labels.connect('clicked', self.set_keyboard_labels_cb)
        toolbar_box.toolbar.insert(keybord_labels, -1)

        notes_labels = RadioToolButton()
        notes_labels.props.icon_name = 'do_key'
        notes_labels.props.group = keybord_labels
        notes_labels.connect('clicked', self.set_notes_labels_cb)
        toolbar_box.toolbar.insert(notes_labels, -1)

        ti_notes_labels = RadioToolButton()
        ti_notes_labels.props.icon_name = 'ti_key'
        ti_notes_labels.props.group = keybord_labels
        ti_notes_labels.connect('clicked', self.set_ti_notes_labels_cb)
        toolbar_box.toolbar.insert(ti_notes_labels, -1)

        german_labels = RadioToolButton()
        german_labels.props.icon_name = 'c_key'
        german_labels.props.group = keybord_labels
        german_labels.connect('clicked', self.set_german_labels_cb)
        toolbar_box.toolbar.insert(german_labels, -1)

        no_labels = RadioToolButton()
        no_labels.props.icon_name = 'edit-clear'
        no_labels.props.group = keybord_labels
        no_labels.connect('clicked', self.set_keyboard_no_labels_cb)
        toolbar_box.toolbar.insert(no_labels, -1)
        self._what_widget = Gtk.ToolItem()
        self._what_search_button = FilterToolItem(_('Select Instrument'),
                                                  'view-type',
                                                  _('Piano'),
                                                  self._what_widget)
        self._what_widget.show()
        toolbar_box.toolbar.insert(Gtk.SeparatorToolItem(), -1)
        toolbar_box.toolbar.insert(self._what_search_button, -1)
        self._what_search_button.show()
        self._what_search_button.set_is_important(True)
        self._what_widget_contents = None
        self._what_drum_widget_contents = None

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

        toolbar_box.toolbar.insert(self.record_button, -1)
        toolbar_box.toolbar.insert(self.play_recording_button, -1)

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

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

        self._save_as_audio_bt = ToolButton(icon_name='save-as-audio')
        self._save_as_audio_bt.props.tooltip = _('Save as audio')
        self._save_as_audio_bt.connect('clicked', self._save_ogg_cb)
        self._save_as_audio_bt.show()
        self._save_as_audio_bt.set_sensitive(False)
        activity_button.page.insert(self._save_as_audio_bt, -1)

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show_all()

        self.keyboard_letters = ['ZSXDCVGBHNJM', 'Q2W3ER5T6Y7U', 'I']

        notes = ['DO', ['DO#', 'REb'], 'RE', ['RE#', 'MIb'], 'MI', 'FA',
                 ['FA#', 'SOLb'], 'SOL',
                 ['SOL#', 'LAb'], 'LA', ['LA#', 'SIb'], 'SI']
        self.notes_labels = [notes, notes, ['DO']]

        # some countries use TI instead of SI
        ti_notes = ['DO', ['DO#', 'REb'], 'RE', ['RE#', 'MIb'], 'MI', 'FA',
                    ['FA#', 'SOLb'], 'SOL',
                    ['SOL#', 'LAb'], 'LA', ['LA#', 'TIb'], 'TI']
        self.ti_notes_labels = [ti_notes, ti_notes, ['DO']]

        german_notes = ['C', ['C#', 'Db'], 'D', ['D#', 'Eb'], 'E', 'F',
                        ['F#', 'Gb'], 'G',
                        ['G#', 'Ab'], 'A', ['A#', 'Bb'], 'B']

        self.german_labels = [german_notes, german_notes, ['C']]

        self.piano = PianoKeyboard(octaves=2, add_c=True,
                                   labels=self.keyboard_letters)

        # init csound
        self.instrumentDB = InstrumentDB.getRef()
        self.timeout_ms = 50
        self.instVolume = 50
        self.drumVolume = 0.5
        self.instrument = 'piano'
        self.beat = 4
        self.reverb = 0.1
        self.tempo = PLAYER_TEMPO
        self.beatDuration = 60.0 / self.tempo
        self.ticksPerSecond = Config.TICKS_PER_BEAT * self.tempo / 60.0

        self.sequencer = MiniSequencer(self.recordStateButton,
                                       self.recordOverSensitivity)
        self.loop = Loop(self.beat, math.sqrt(self.instVolume * 0.01))

        self.drumFillin = Fillin(self.beat,
                                 self.tempo,
                                 self.rythmInstrument,
                                 self.reverb,
                                 self.drumVolume)

        self.muteInst = False
        self.csnd.setTempo(self.tempo)
        self.noteList = []
        for i in range(21):
            self.csnd.setTrackVolume(100, i)

        # TODO commented because apparently are not used in the activity
        # for i in range(10):
        #     self.csnd.load_instrument('guidice' + str(i + 1))

        self.volume = 100
        self.csnd.setMasterVolume(self.volume)

        self.enableKeyboard()
        self.setInstrument(self.instrument)

        self.connect('key-press-event', self.onKeyPress)
        self.connect('key-release-event', self.onKeyRelease)

        self.piano.connect('key_pressed', self.__key_pressed_cb)
        self.piano.connect('key_released', self.__key_released_cb)
        vbox = Gtk.VBox()
        vbox.set_homogeneous(False)
        self.load_instruments()
        self._event_box = Gtk.EventBox()
        self._event_box.modify_bg(
            Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color())
        vbox.pack_start(self._event_box, False, False, 0)
        vbox.pack_end(self.piano, True, True, 0)
        vbox.show_all()
        self.set_canvas(vbox)
        piano_height = Gdk.Screen.width() / 2
        self._event_box.set_size_request(
            -1, Gdk.Screen.height() - piano_height - style.GRID_CELL_SIZE)
        self.connect('size-allocate', self.__allocate_cb)

        # TODO: disabe until is implemented with csnd6
        # GLib.idle_add(self.initializePercussion)

    def createPercussionToolbar(self, toolbar_box):

        self.beats_pm_button = IntensitySelector(range(2, 13),
                                                 4,
                                                 imagefile('beat3.svg'))
        self.tempo_button = \
            IntensitySelector(range(PLAYER_TEMPO_LOWER,
                                    PLAYER_TEMPO_UPPER + 1, PLAYER_TEMPO_STEP),
                              PLAYER_TEMPO, imagefile('tempo5.png'))

        self.complexity_button = IntensitySelector(xfrange(0, 1, 0.1),
                                                   self.regularity,
                                                   imagefile('complex6.svg'))

        self._play_percussion_btn = ToolButton(
            icon_name='media-playback-start')
        self._play_percussion_btn.set_property('can-default', True)
        self._play_percussion_btn.show()
        self._play_percussion_btn.connect('clicked', self.handlePlayButton)

        beats_toolbar = ToolbarBox()
        beats_toolbar.toolbar.insert(self._play_percussion_btn, -1)

        self._what_drum_widget = Gtk.ToolItem()
        self._what_drum_search_button = FilterToolItem(
            _('Select Drum'), 'view-type', _('Jazz / Rock Kit'),
            self._what_drum_widget)
        self._what_drum_search_button.set_widget_icon(
            file_name=imagefile("drum1kit.svg"))

        self._what_drum_widget.show()
        beats_toolbar.toolbar.insert(self._what_drum_search_button, -1)
        self._what_drum_search_button.show()
        self._what_drum_search_button.set_is_important(True)

        beats_toolbar.toolbar.insert(Gtk.SeparatorToolItem(), -1)
        beats_toolbar.toolbar.insert(self.complexity_button, -1)
        beats_toolbar.toolbar.insert(self.beats_pm_button, -1)
        beats_toolbar.toolbar.insert(self.tempo_button, -1)

        beats_toolbar_button = ToolbarButton(icon_name='toolbar-drums',
                                             page=beats_toolbar)
        beats_toolbar_button.show()

        toolbar_box.toolbar.insert(beats_toolbar_button, 1)

        self.beats_pm_button.set_tooltip(_("Beats per bar"))
        self.beats_pm_button.show()
        self.beats_pm_button.connect('changed', self.beatSliderChange, True)
        self.tempo_button.connect('changed', self.tempoSliderChange, True)
        self.complexity_button.connect('changed',
                                       self.handleComplexityChange,
                                       True)
        self.complexity_button.set_tooltip(_("Beat complexity"))
        self.tempo_button.show()
        self.tempo_button.set_tooltip(_('Tempo'))
        self.complexity_button.show()

    def initializePercussion(self):
        self.rythmInstrument = 'drum1kit'
        self.csnd.load_drumkit(self.rythmInstrument)
        self.csnd.setTempo(self.tempo)
        self.beatPickup = False

        def flatten(ll):
            rval = []
            for l in ll:
                rval += l
            return rval

        noteOnsets = []
        notePitchs = []

        i = 0
        self.noteList = []
        self.csnd.loopClear()
        for x in flatten(
            generator(self.rythmInstrument, self.beat,
                      0.8, self.regularity, self.reverb)):
            x.amplitude = x.amplitude * self.drumVolume
            noteOnsets.append(x.onset)
            notePitchs.append(x.pitch)
            n = Note(0, x.trackId, i, x)
            self.noteList.append((x.onset, n))
            i = i + 1
            self.csnd.loopPlay(n, 1)                    # add as active

        self.csnd.loopSetNumTicks(self.beat * Config.TICKS_PER_BEAT)
        self.drumFillin.unavailable(noteOnsets, notePitchs)

        if self.playing:
            self.csnd.loopStart()

    def __allocate_cb(self, widget, rect):
        GLib.idle_add(self.resize, rect.width, rect.height)
        return False

    def resize(self, width, height):
        logging.debug('activity.py resize......')
        piano_height = width / 2
        self._event_box.set_size_request(
            -1, Gdk.Screen.height() - piano_height - style.GRID_CELL_SIZE)
        return False

    def load_instruments(self):
        self._instruments_store = []

        # load the images
        images_path = os.path.join(activity.get_bundle_path(),
                                   'instruments')
        logging.debug('Loading instrument images from %s', images_path)
        for file_name in os.listdir(images_path):
            image_file_name = os.path.join(images_path, file_name)
            pxb = GdkPixbuf.Pixbuf.new_from_file_at_size(
                image_file_name, 75, 75)
            # instrument_name = image_file_name[image_file_name.rfind('/'):]
            instrument_name = image_file_name[image_file_name.rfind('/') + 1:]
            instrument_name = instrument_name[:instrument_name.find('.')]
            instrument_desc = \
                self.instrumentDB.instNamed[instrument_name].nameTooltip

            file_path = os.path.join(images_path, file_name)

            # set the default icon
            if (instrument_name == 'piano'):
                self._what_search_button.set_widget_icon(
                    file_name=file_path)

            self._instruments_store.append(
                {"instrument_name": instrument_name,
                 "pxb": pxb,
                 "instrument_desc": instrument_desc,
                 "file_name": file_path,
                 "callback": self.__instrument_iconview_activated_cb})

        self._what_widget_contents = set_palette_list(self._instruments_store)
        self._what_widget.add(self._what_widget_contents)
        self._what_widget_contents.show()

        # TODO: disabe until is implemented with csnd6
        """
        for drum_number in range(0, DRUMCOUNT):
            drum_name = 'drum%dkit' % (drum_number + 1)
            self._drums_store.append({
                "instrument_name": drum_name,
                "file_name": imagefile(drum_name + '.svg'),
                "instrument_desc":
                    self.instrumentDB.instNamed[drum_name].nameTooltip,
                "callback": self.__drum_iconview_activated_cb
            })

        self._what_drum_widget_contents = set_palette_list(self._drums_store)
        self._what_drum_widget.add(self._what_drum_widget_contents)
        self._what_drum_widget_contents.show()
        """

    def __drum_iconview_activated_cb(self, widget, event, item):
        data = item['instrument_name']
        self.rythmInstrument = data
        self.csnd.load_drumkit(data)
        instrumentId = self.instrumentDB.instNamed[data].instrumentId
        for (o, n) in self.noteList:
            self.csnd.loopUpdate(n, NoteDB.PARAMETER.INSTRUMENT,
                                 instrumentId, -1)
        self.drumFillin.setInstrument(self.rythmInstrument)
        self._what_drum_search_button.set_widget_label(
            label=item['instrument_desc'])
        self._what_drum_search_button.set_widget_icon(
            file_name=item['file_name'])

    def __instrument_iconview_activated_cb(self, widget, event, item):
        self.setInstrument(item['instrument_name'])
        self._what_search_button.set_widget_icon(file_name=item['file_name'])
        self._what_search_button.set_widget_label(
            label=item['instrument_desc'])

    def set_notes_labels_cb(self, widget):
        self.piano.font_size = 16
        self.piano.set_labels(self.notes_labels)

    def set_ti_notes_labels_cb(self, widget):
        self.piano.font_size = 16
        self.piano.set_labels(self.ti_notes_labels)

    def set_keyboard_labels_cb(self, widget):
        self.piano.font_size = 25
        self.piano.set_labels(self.keyboard_letters)

    def set_german_labels_cb(self, widget):
        self.piano.font_size = 25
        self.piano.set_labels(self.german_labels)

    def beatSliderChange(self, widget, event):
        self.beat = int(self.beats_pm_button.get_value())
        self.sequencer.beat = self.beat
        self.loop.beat = self.beat
        self.drumFillin.setBeats(self.beat)
        img = int(self.scale(self.beat, 2, 12, 1, 11))
        self.beats_pm_button.set_image(imagefile('beat' + str(img) + '.svg'))
        self.beatPickup = False
        self.regenerate()
        self.beatPickup = True

    def regenerate(self):
        def flatten(ll):
            rval = []
            for l in ll:
                rval += l
            return rval
        noteOnsets = []
        notePitchs = []
        i = 0
        self.noteList = []
        self.csnd.loopClear()
        for x in flatten(
            generator(self.rythmInstrument,
                      self.beat, 0.8, self.regularity,
                      self.reverb)):
            x.amplitude = x.amplitude * self.drumVolume
            noteOnsets.append(x.onset)
            notePitchs.append(x.pitch)
            n = Note(0, x.trackId, i, x)
            self.noteList.append((x.onset, n))
            i = i + 1
            self.csnd.loopPlay(n, 1)                    # add as active
        self.csnd.loopSetNumTicks(self.beat * Config.TICKS_PER_BEAT)
        self.drumFillin.unavailable(noteOnsets, notePitchs)
        self.recordOverSensitivity(False)
        if self.playing:
            self.csnd.loopStart()

    def handlePlayRecordingButton(self, val):
        if not self.playing_recording:
            self.playing_recording = True
            self.play_recording_button.props.icon_name = 'media-playback-stop'
            self.play_recording_thread = \
                GLib.timeout_add(100, self._play_recorded_keys)
        else:
            self.playing_recording = False
            self.play_recording_button.props.icon_name = 'media-playback-start'

    def _save_ogg_cb(self, widget):
        self._wav_tempfile = tempfile.NamedTemporaryFile(
            mode='w+b', suffix='.wav', dir='/tmp/')
        self.csnd.inputMessage(Config.CSOUND_RECORD_PERF %
                               self._wav_tempfile.name)

        self.playing_recording = True
        self.play_recording_thread = \
            GLib.timeout_add(100, self._play_recorded_keys,
                             self._save_ogg_end_cb)

    def _save_ogg_end_cb(self):
        self.csnd.inputMessage(Config.CSOUND_STOP_RECORD_PERF %
                               self._wav_tempfile.name)

        self._ogg_tempfile = tempfile.NamedTemporaryFile(
            mode='w+b', suffix='.ogg', dir='/tmp/')

        line = 'filesrc location=%s ! ' \
            'wavparse ! audioconvert ! vorbisenc ! oggmux ! ' \
            'filesink location=%s' % (self._wav_tempfile.name,
                                      self._ogg_tempfile.name)
        pipe = Gst.parse_launch(line)
        pipe.get_bus().add_signal_watch()
        pipe.get_bus().connect('message::eos', self._save_ogg_eos_cb, pipe)
        pipe.set_state(Gst.State.PLAYING)

    def _save_ogg_eos_cb(self, bus, message, pipe):
        bus.remove_signal_watch()
        pipe.set_state(Gst.State.NULL)

        title = '%s saved as audio' % self.metadata['title']

        jobject = datastore.create()
        jobject.metadata['title'] = title
        jobject.metadata['keep'] = '0'
        jobject.metadata['mime_type'] = 'audio/ogg'
        jobject.file_path = self._ogg_tempfile.name
        datastore.write(jobject)

        self._wav_tempfile.close()
        self._ogg_tempfile.close()

        alert = NotifyAlert(10)
        alert.props.title = _('Audio recorded')
        alert.props.msg = _('The audio file was saved in the Journal')
        alert.connect('response', self.__alert_response_cb)
        self.add_alert(alert)

        return False

    def __alert_response_cb(self, alert, result):
        self.remove_alert(alert)

    def __record_button_click_cb(self, button):
        if not self.recording:
            self.play_recording_button.set_sensitive(False)
            self._save_as_audio_bt.set_sensitive(False)
            self.recorded_keys = []
            self.recording = True
            icon = Icon(icon_name='media-record', fill_color='#ff0000')
            icon.show()
            self.record_button.set_icon_widget(icon)
        else:
            self.recording = False
            icon = Icon(icon_name='media-record', fill_color='#ffffff')
            icon.show()
            self.record_button.set_icon_widget(icon)
            if len(self.recorded_keys) != 0:
                self.play_recording_button.set_sensitive(True)
                self._save_as_audio_bt.set_sensitive(True)

    def tempoSliderChange(self, widget, event):
        self._updateTempo(self.tempo_button.get_value())
        img = int(self.scale(self.tempo, PLAYER_TEMPO_LOWER,
                             PLAYER_TEMPO_UPPER, 1, 9))
        self.tempo_button.set_image(imagefile('tempo' + str(img) + '.png'))

    def _updateTempo(self, val):
        self.tempo = val
        self.beatDuration = 60.0 / self.tempo
        self.ticksPerSecond = Config.TICKS_PER_BEAT * self.tempo / 60.0
        self.csnd.setTempo(self.tempo)
        self.sequencer.tempo = self.tempo
        self.drumFillin.setTempo(self.tempo)

    def handlePlayButton(self, val):
        if not self.playing:
            if not self.firstTime:
                self.regenerate()
                self.firstTime = True
            self.drumFillin.play()
            self.csnd.loopSetTick(0)
            self.csnd.loopStart()
            self.playing = True
            self._play_percussion_btn.props.icon_name = 'media-playback-stop'
        else:
            self.drumFillin.stop()
            self.sequencer.stopPlayback()
            self.csnd.loopPause()
            self.playing = False
            self._play_percussion_btn.props.icon_name = 'media-playback-start'

    def scale(self, input, input_min, input_max,
              output_min, output_max):
        range_input = input_max - input_min
        range_output = output_max - output_min
        result = (input - input_min) * range_output / range_input + output_min

        if (input_min > input_max and output_min > output_max) or \
           (output_min > output_max and input_min < input_max):
            if result > output_min:
                return output_min
            elif result < output_max:
                return output_max
            else:
                return result

        if (input_min < input_max and output_min < output_max) or \
           (output_min < output_max and input_min > input_max):
            if result > output_max:
                return output_max
            elif result < output_min:
                return output_min
            else:
                return result

    def handleComplexityChange(self, widget, event):
        self.regularity = self.complexity_button.get_value()
        img = int(self.complexity_button.get_value() * 7) + 1
        self.complexity_button.set_image(
            imagefile('complex' + str(img) + '.svg'))
        self.beatPickup = False
        self.regenerate()
        self.beatPickup = True

    """
    def handleBalanceSlider(self, adj):
        self.instVolume = int(adj.get_value())
        self.drumVolume = sqrt( (100-self.instVolume)*0.01 )
        self.adjustDrumVolume()
        self.drumFillin.setVolume(self.drumVolume)
        instrumentVolume = sqrt( self.instVolume*0.01 )
        self.loop.adjustLoopVolume(instrumentVolume)
        self.sequencer.adjustSequencerVolume(instrumentVolume)
        img = int(self.scale(self.instVolume,100,0,0,4.9))
        self._playToolbar.balanceSliderImgLeft.set_from_file(
                imagefile('dru' + str(img) + '.png'))
        img2 = int(self.scale(self.instVolume,0,100,0,4.9))
        self._playToolbar.balanceSliderImgRight.set_from_file(
                imagefile('instr' + str(img2) + '.png'))

    def handleReverbSlider(self, adj):
        self.reverb = adj.get_value()
        self.drumFillin.setReverb( self.reverb )
        img = int(self.scale(self.reverb,0,1,0,4))
        self._playToolbar.reverbSliderImgRight.set_from_file(
                imagefile('reverb' + str(img) + '.png'))
        self.keyboardStandAlone.setReverb(self.reverb)
    """
    def set_keyboard_no_labels_cb(self, widget):
        self.piano.font_size = 25
        self.piano.set_labels(None)

    def enableKeyboard(self):
        self.keyboardStandAlone = KeyboardStandAlone(
            self.sequencer.recording, self.sequencer.adjustDuration,
            self.csnd.loopGetTick, self.sequencer.getPlayState, self.loop)
        self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)

    def setInstrument(self, instrument):
        logging.debug("Set Instrument: %s" % instrument)
        self.instrument = instrument
        self.keyboardStandAlone.setInstrument(instrument)
        self.csnd.load_instrument(instrument)

    def recordStateButton(self, button, state):
        pass
#        if button == 1:
#            self._recordToolbar.keyboardRecButton.set_active( state )
#        else:
#            self._recordToolbar.keyboardRecOverButton.set_active( state )

    def recordOverSensitivity(self, state):
        pass
        # self._recordToolbar.keyboardRecOverButton.set_sensitive( state )

    def _play_recorded_keys(self, end_cb=None):
        GLib.source_remove(self.play_recording_thread)
        letter = self.recorded_keys[self.play_index]
        time_difference = 0
        if self.play_index == len(self.recorded_keys) - 1:
            time_difference = \
                self.recorded_keys[self.play_index][0] - \
                self.recorded_keys[self.play_index - 1][0]
        else:
            next_time = self.recorded_keys[self.play_index + 1][0]
            time_difference = next_time - letter[0]

        if not self.playing_recording:
            self.play_recording_button.props.icon_name = 'media-playback-start'
            return

        if letter[-1] == 1:
            self.keyboardStandAlone.do_key_release(
                LETTERS_TO_KEY_CODES[letter[3]])
            GLib.idle_add(self.piano.physical_key_changed,
                          LETTERS_TO_KEY_CODES[letter[3]], False)
        else:
            self.keyboardStandAlone.do_key_press(
                LETTERS_TO_KEY_CODES[letter[3]], None,
                math.sqrt(self.instVolume * 0.01))
            GLib.idle_add(self.piano.physical_key_changed,
                          LETTERS_TO_KEY_CODES[letter[3]], True)

        if self.play_index == len(self.recorded_keys) - 1:
            self.play_index = 0
            self.play_recording_button.props.icon_name = 'media-playback-start'
            self.playing_recording = False
            if end_cb is not None:
                end_cb()
        else:
            self.play_index += 1
            self.play_recording_thread = \
                GLib.timeout_add(int((time_difference) * 1000),
                                 self._play_recorded_keys, end_cb)

    def __key_pressed_cb(self, widget, octave_clicked, key_clicked, letter,
                         physicallKey):
        logging.debug(
            'Pressed Octave: %d Key: %d Letter: %s' %
            (octave_clicked, key_clicked, letter))
        if letter in LETTERS_TO_KEY_CODES.keys():
            if self.recording:
                self.recorded_keys.append(
                    [time.time(), octave_clicked, key_clicked, letter])
            if not physicallKey:
                self.keyboardStandAlone.do_key_press(
                    LETTERS_TO_KEY_CODES[letter], None,
                    math.sqrt(self.instVolume * 0.01))

    def __key_released_cb(self, widget, octave_clicked, key_clicked, letter,
                          physicallKey):
        if self.recording:
            self.recorded_keys.append(
                [time.time(), octave_clicked, key_clicked, letter, 1])
        if not physicallKey:
            if letter in LETTERS_TO_KEY_CODES.keys():
                self.keyboardStandAlone.do_key_release(
                    LETTERS_TO_KEY_CODES[letter])

    def onKeyPress(self, widget, event):
        if event.state & Gdk.ModifierType.CONTROL_MASK:
            return
        if event.hardware_keycode == 37:
            if self.muteInst:
                self.muteInst = False
            else:
                self.muteInst = True
        self.piano.physical_key_changed(event.hardware_keycode, True)
        self.keyboardStandAlone.onKeyPress(
            widget, event, math.sqrt(self.instVolume * 0.01))

    def onKeyRelease(self, widget, event):
        self.keyboardStandAlone.onKeyRelease(widget, event)
        self.piano.physical_key_changed(event.hardware_keycode, False)

    def write_file(self, file_path):
        f = open(file_path, 'w')
        # substract the initial time to all the saved values
        if len(self.recorded_keys) > 0:
            initial_time = self.recorded_keys[0][0]
            for key in self.recorded_keys:
                key[0] = key[0] - initial_time

        f.write(json.dumps(self.recorded_keys))
        f.close()

    def read_file(self, file_path):
        f = open(file_path, 'r')
        contents = f.read().strip()

        self.recorded_keys = json.loads(contents)
        if len(self.recorded_keys) != 0:
            self.play_recording_button.set_sensitive(True)
            self._save_as_audio_bt.set_sensitive(True)
        f.close()

    def close(self, skip_save=False):
        self.csnd.stop()  # without which Csound will segfault
        activity.Activity.close(self, skip_save=skip_save)
Ejemplo n.º 49
0
class SpeechToolbar(Gtk.Toolbar):
    def __init__(self):
        Gtk.Toolbar.__init__(self)
        self.activity = None
        self._speech = SpeechManager()
        self._voices = self._speech.get_all_voices()  # a dictionary

        locale = os.environ.get('LANG', '')
        language_location = locale.split('.', 1)[0].lower()
        language = language_location.split('_')[0]
        # if the language is es but not es_es default to es_la (latin voice)
        if language == 'es' and language_location != 'es_es':
            language_location = 'es_la'

        self._voice = 'en_us'
        if language_location in self._voices:
            self._voice = language_location
        elif language in self._voices:
            self._voice = language

        voice_names = []
        for language, name in self._voices.items():
            voice_names.append((language, name))
        voice_names.sort()

        # Play button Image
        play_img = Gtk.Image()
        play_img.show()
        play_img.set_from_icon_name('media-playback-start',
                                    Gtk.IconSize.LARGE_TOOLBAR)

        # Pause button Image
        pause_img = Gtk.Image()
        pause_img.show()
        pause_img.set_from_icon_name('media-playback-pause',
                                     Gtk.IconSize.LARGE_TOOLBAR)

        # Play button
        self.play_button = ToggleToolButton('media-playback-start')
        self.play_button.show()
        self.play_button.connect('toggled', self._play_toggled_cb,
                                 [play_img, pause_img])
        self.insert(self.play_button, -1)
        self.play_button.set_tooltip(_('Play / Pause'))

        combo = ComboBox()
        which = 0
        for pair in voice_names:
            language, name = pair
            combo.append_item(language, name)
            if language == self._voice:
                combo.set_active(which)
            which += 1

        combo.connect('changed', self._voice_changed_cb)
        combotool = ToolComboBox(combo)
        self.insert(combotool, -1)
        combotool.show()

        self.pitchadj = Gtk.Adjustment(0, -100, 100, 1, 10, 0)
        pitchbar = Gtk.HScale()
        pitchbar.set_adjustment(self.pitchadj)
        pitchbar.set_draw_value(False)
        # pitchbar.set_update_policy(Gtk.UpdatePolicy.ALWAYS)
        pitchbar.set_size_request(150, 15)
        pitchtool = Gtk.ToolItem()
        pitchtool.add(pitchbar)
        pitchtool.show()
        self.insert(pitchtool, -1)
        pitchbar.show()

        self.rateadj = Gtk.Adjustment(0, -100, 100, 1, 10, 0)
        ratebar = Gtk.HScale()
        ratebar.set_adjustment(self.rateadj)
        ratebar.set_draw_value(False)
        # ratebar.set_update_policy(Gtk.UpdatePolicy.ALWAYS)
        ratebar.set_size_request(150, 15)
        ratetool = Gtk.ToolItem()
        ratetool.add(ratebar)
        ratetool.show()
        self.insert(ratetool, -1)
        ratebar.show()

    def _compare_voices(self, a, b):
        if a[1].lower() == b[1].lower():
            return 0
        if a[1].lower() < b[1].lower():
            return -1
        if a[1].lower() > b[1].lower():
            return 1

    def _voice_changed_cb(self, combo):
        self._voice = combo.props.value
        self._speech.say_text(self._voices[self._voice])

    def pitch_adjusted_cb(self, get):
        self._speech.set_pitch(int(get.get_value()))
        self._speech.say_text(_("pitch adjusted"))
        f = open(
            os.path.join(self.activity.get_activity_root(), 'instance',
                         'pitch.txt'), 'w')
        try:
            f.write(str(self._speech.get_pitch()))
        finally:
            f.close()

    def rate_adjusted_cb(self, get):
        self._speech.set_rate(int(get.get_value()))
        self._speech.say_text(_("rate adjusted"))
        f = open(
            os.path.join(self.activity.get_activity_root(), 'instance',
                         'rate.txt'), 'w')
        try:
            f.write(str(self._speech.get_rate()))
        finally:
            f.close()

    def set_activity(self, activity):
        self.activity = activity
        if os.path.exists(
                os.path.join(activity.get_activity_root(), 'instance',
                             'pitch.txt')):
            f = open(
                os.path.join(activity.get_activity_root(), 'instance',
                             'pitch.txt'), 'r')
            line = f.readline()
            pitch = int(line.strip())
            self.pitchadj.set_value(pitch)
            self._speech.set_pitch(pitch)
            f.close()
        if os.path.exists(
                os.path.join(activity.get_activity_root(), 'instance',
                             'rate.txt')):
            f = open(
                os.path.join(activity.get_activity_root(), 'instance',
                             'rate.txt'), 'r')
            line = f.readline()
            rate = int(line.strip())
            self.rateadj.set_value(rate)
            self._speech.set_rate(rate)
            f.close()
        self.pitchadj.connect("value_changed", self.pitch_adjusted_cb)
        self.rateadj.connect("value_changed", self.rate_adjusted_cb)

    def _play_toggled_cb(self, widget, images):
        widget.set_icon_widget(images[int(widget.get_active())])

        if widget.get_active():
            self.play_button.set_icon_name('media-playback-pause')
            self._speech.say_text(self.activity.add_word_marks(),
                                  lang_code=self._voice)
        else:
            self.play_button.set_icon_name('media-playback-start')
            self._speech.pause()

    def is_playing(self):
        self._speech.get_is_playing()

    def stop(self):
        self._speech.stop()
Ejemplo n.º 50
0
class MainToolbox(ToolbarBox):

    query_changed_signal = GObject.Signal('query-changed',
                                          arg_types=([object]))

    def __init__(self, default_what_filter=None, default_filter_type=None):
        ToolbarBox.__init__(self)
        self._mount_point = None
        self._filter_type = default_filter_type
        self._what_filter = default_what_filter
        self._when_filter = None

        self._default_what_filter = default_what_filter
        self._default_filter_type = default_filter_type

        self.search_entry = iconentry.IconEntry()
        self.search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                             'entry-search')
        text = _('Search in %s') % _('Journal')
        self.search_entry.set_placeholder_text(text)
        self.search_entry.connect('activate', self._search_entry_activated_cb)
        self.search_entry.connect('changed', self._search_entry_changed_cb)
        self.search_entry.add_clear_button()
        self._autosearch_timer = None
        self._add_widget(self.search_entry, expand=True)

        self._favorite_button = ToggleToolButton('emblem-favorite')
        self._favorite_button.set_tooltip(_('Favorite entries'))
        self._favorite_button.connect('toggled',
                                      self.__favorite_button_toggled_cb)
        self.toolbar.insert(self._favorite_button, -1)
        self._favorite_button.show()

        self._proj_list_button = ToggleToolButton('project-box')
        self._proj_list_button.set_tooltip(_('Projects'))
        self._proj_list_button.connect('toggled',
                                       self._proj_list_button_clicked_cb)
        self.toolbar.insert(self._proj_list_button, -1)
        self._proj_list_button.show()

        if not self._proj_list_button.props.active:
            self._what_widget_contents = None
            self._what_widget = Gtk.ToolItem()
            self._what_search_button = FilterToolItem(
                'view-type', _('Anything'), self._what_widget)
            self._what_widget.show()
            self.toolbar.insert(self._what_search_button, -1)
            self._what_search_button.show()

        self._when_search_button = FilterToolItem(
            'view-created', _('Anytime'), self._get_when_search_items())
        self.toolbar.insert(self._when_search_button, -1)
        self._when_search_button.show()

        self._sorting_button = SortingButton()
        self.toolbar.insert(self._sorting_button, -1)
        self._sorting_button.connect('sort-property-changed',
                                     self.__sort_changed_cb)
        self._sorting_button.show()

        '''
        # TODO: enable it when the DS supports saving the buddies.
        self._with_widget = Gtk.ToolItem()
        self._with_search_button = FilterToolItem(
            'view-who', _('Anyone'), self._with_widget)
        self._with_widget.show()
        self.toolbar.insert(self._with_search_button, -1)
        self._with_search_button.show()
        self._get_with_search_items()
        '''

        self._query = self._build_query()

        self.refresh_filters()

        self.connect('size_allocate', self.__size_allocate_cb)

    def __size_allocate_cb(self, widget, allocation):
        GObject.idle_add(self._update_buttons, allocation.width)

    def _update_buttons(self, toolbar_width):
        # Show the label next to the button icon if there is room on
        # the toolbar.
        important = toolbar_width > 13 * style.GRID_CELL_SIZE

        if not important:
            self.search_entry.set_size_request(
                toolbar_width - style.GRID_CELL_SIZE * 7, 0)

        self._what_search_button.set_is_important(important)
        self._when_search_button.set_is_important(important)
        # self._with_search_button.set_is_important(important)

        return False

    def _get_when_search_items(self):
        when_list = []
        when_list.append({'label': _('Anytime'),
                          'callback': self._when_palette_cb,
                          'id': _ACTION_ANYTIME})
        when_list.append({'separator': True})
        when_list.append({'label': _('Today'),
                          'callback': self._when_palette_cb,
                          'id': _ACTION_TODAY})
        when_list.append({'label': _('Since yesterday'),
                          'callback': self._when_palette_cb,
                          'id': _ACTION_SINCE_YESTERDAY})
        when_list.append({'label': _('Past week'),
                          'callback': self._when_palette_cb,
                          'id': _ACTION_PAST_WEEK})
        when_list.append({'label': _('Past month'),
                          'callback': self._when_palette_cb,
                          'id': _ACTION_PAST_MONTH})
        when_list.append({'label': _('Past year'),
                          'callback': self._when_palette_cb,
                          'id': _ACTION_PAST_YEAR})

        return set_palette_list(when_list)

    '''
    def _get_with_search_items(self):
        with_list = []
        with_list.append({'label':_('Anyone'),
                          'callback': self._with_palette_cb,
                          'id': _ACTION_EVERYBODY})
        with_list.append({'separator': True})
        with_list.append({'label':_('My friends'),
                          'callback': self._with_palette_cb,
                          'id': _ACTION_MY_FRIENDS})
        with_list.append({'label':_('My class'),
                          'callback': self._with_palette_cb,
                          'id': _ACTION_MY_CLASS})
        with_list.append({'separator': True})
        # TODO: Ask the model for buddies.
        for i, buddy in enumerate(model.get_buddies()):
            nick, color = buddy
            with_list.append({'label': nick,
                              'callback': self._with_palette_cb,
                              'icon': 'computer-xo',
                              'xocolors': XOColor(color),
                              'id': i + _ACTION_MY_CLASS + 1})

        widget = set_palette_list(with_list)
        self._with_widget.add(widget)
        widget.show()
    '''

    def _add_widget(self, widget, expand=False):
        tool_item = Gtk.ToolItem()
        tool_item.set_expand(expand)

        tool_item.add(widget)
        widget.show()

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

    def _build_query(self):
        query = {}

        if self._mount_point:
            query['mountpoints'] = [self._mount_point]

        if self._favorite_button.props.active:
            query['keep'] = 1

        if self._proj_list_button.props.active:
            query['activity'] = 'org.sugarlabs.Project'

        elif self._what_filter:
            filter_type = self._filter_type
            value = self._what_filter

            if filter_type == FILTER_TYPE_GENERIC_MIME:
                generic_type = mime.get_generic_type(value)
                if generic_type:
                    mime_types = generic_type.mime_types
                    query['mime_type'] = mime_types
                else:
                    logging.error('filter_type="generic_mime", '
                                  'but "%s" is not a generic mime' % value)

            elif filter_type == FILTER_TYPE_ACTIVITY:
                query['activity'] = value

            elif self._filter_type == FILTER_TYPE_MIME_BY_ACTIVITY:
                registry = bundleregistry.get_registry()
                bundle = \
                    registry.get_bundle(value)
                if bundle is not None:
                    query['mime_type'] = bundle.get_mime_types()
                else:
                    logging.error('Trying to filter using activity mimetype '
                                  'but bundle id is wrong %s' % value)

        if self._when_filter:
            date_from, date_to = self._get_date_range()
            query['timestamp'] = {'start': date_from, 'end': date_to}

        if self.search_entry.props.text:
            text = self.search_entry.props.text.strip()
            if text:
                query['query'] = text

        property_, order = self._sorting_button.get_current_sort()

        if order == Gtk.SortType.ASCENDING:
            sign = '+'
        else:
            sign = '-'
        query['order_by'] = [sign + property_]

        return query

    def _get_date_range(self):
        today_start = datetime.today().replace(hour=0, minute=0, second=0)
        right_now = datetime.today()

        if self._when_filter == _ACTION_TODAY:
            date_range = (today_start, right_now)
        elif self._when_filter == _ACTION_SINCE_YESTERDAY:
            date_range = (today_start - timedelta(1), right_now)
        elif self._when_filter == _ACTION_PAST_WEEK:
            date_range = (today_start - timedelta(7), right_now)
        elif self._when_filter == _ACTION_PAST_MONTH:
            date_range = (today_start - timedelta(30), right_now)
        elif self._when_filter == _ACTION_PAST_YEAR:
            date_range = (today_start - timedelta(356), right_now)

        return (time.mktime(date_range[0].timetuple()),
                time.mktime(date_range[1].timetuple()))

    def __sort_changed_cb(self, button):
        self._update_if_needed()

    def _update_if_needed(self):
        new_query = self._build_query()
        if self._query != new_query:
            self._query = new_query
            self.query_changed_signal.emit(self._query)

    def _search_entry_activated_cb(self, search_entry):
        if self._autosearch_timer:
            GObject.source_remove(self._autosearch_timer)
        self._update_if_needed()

    def _search_entry_changed_cb(self, search_entry):
        if not search_entry.props.text:
            search_entry.activate()
            return

        if self._autosearch_timer:
            GObject.source_remove(self._autosearch_timer)
        self._autosearch_timer = GObject.timeout_add(_AUTOSEARCH_TIMEOUT,
                                                     self._autosearch_timer_cb)

    def _autosearch_timer_cb(self):
        logging.debug('_autosearch_timer_cb')
        self._autosearch_timer = None
        self.search_entry.activate()
        return False

    def set_mount_point(self, mount_point):
        self._mount_point = mount_point
        self._update_if_needed()

    def set_what_filter(self, what_filter):
        for item in self._what_list:
            if 'id' in item and item['id'] == what_filter:
                self._what_search_button.set_widget_label(item['label'])

                if item['id'] == 0:
                    self._what_search_button.set_widget_icon(
                        icon_name='view-type')
                elif 'icon' in item:
                    self._what_search_button.set_widget_icon(
                        icon_name=item['icon'])
                    self._filter_type = FILTER_TYPE_GENERIC_MIME
                elif 'file' in item:
                    self._what_search_button.set_widget_icon(
                        file_name=item['file'])
                    if self._default_filter_type is not None:
                        self._filter_type = self._default_filter_type
                    else:
                        self._filter_type = FILTER_TYPE_ACTIVITY
                self._what_filter = what_filter
                break

    def update_filters(self, mount_point, what_filter, filter_type=None):
        self._mount_point = mount_point
        self._filter_type = filter_type
        self._what_filter = what_filter
        self.set_what_filter(what_filter)
        self._update_if_needed()

    def set_filter_type(self, filter_type):
        self._filter_type = filter_type
        self._update_if_needed()

    def _what_palette_cb(self, widget, event, item):
        self._what_search_button.set_widget_label(item['label'])

        if item['id'] == 0:
            self._what_search_button.set_widget_icon(icon_name='view-type')
        elif 'icon' in item:
            self._what_search_button.set_widget_icon(icon_name=item['icon'])
            self._filter_type = FILTER_TYPE_GENERIC_MIME
        elif 'file' in item:
            self._what_search_button.set_widget_icon(file_name=item['file'])
            if self._default_filter_type is not None:
                self._filter_type = self._default_filter_type
            else:
                self._filter_type = FILTER_TYPE_ACTIVITY

        self._what_filter = item['id']

        new_query = self._build_query()
        if self._query != new_query:
            self._query = new_query
            self.query_changed_signal.emit(self._query)

    def _when_palette_cb(self, widget, event, item):
        self._when_search_button.set_widget_label(item['label'])

        self._when_filter = item['id']

        new_query = self._build_query()
        if self._query != new_query:
            self._query = new_query
            self.query_changed_signal.emit(self._query)

    def refresh_filters(self):
        # refresh_what_filters
        self._what_list = []
        what_list_activities = []

        try:
            # TRANS: Item on a palette that filters by entry type.
            self._what_list.append({'label': _('Anything'),
                                    'icon': 'application-octet-stream',
                                    'callback': self._what_palette_cb,
                                    'id': _ACTION_ANYTHING})

            registry = bundleregistry.get_registry()
            appended_separator = False

            types = mime.get_all_generic_types()
            for generic_type in types:
                if not appended_separator:
                    self._what_list.append({'separator': True})
                    appended_separator = True
                self._what_list.append({'label': generic_type.name,
                                        'icon': generic_type.icon,
                                        'callback': self._what_palette_cb,
                                        'id': generic_type.type_id})

            self._what_list.append({'separator': True})

            for bundle_id in model.get_unique_values('activity'):
                activity_info = registry.get_bundle(bundle_id)
                if activity_info is None:
                    continue

                # try activity-provided icon
                if os.path.exists(activity_info.get_icon()):
                    try:
                        what_list_activities.append(
                            {'label': activity_info.get_name(),
                             'file': activity_info.get_icon(),
                             'callback': self._what_palette_cb,
                             'id': bundle_id})
                    except GObject.GError as exception:
                        # fall back to generic icon
                        logging.warning('Falling back to default icon for'
                                        ' "what" filter because %r (%r) has an'
                                        ' invalid icon: %s',
                                        activity_info.get_name(),
                                        str(bundle_id), exception)
                        what_list_activities.append(
                            {'label': activity_info.get_name(),
                             'icon': 'application-octet-stream',
                             'callback': self._what_palette_cb,
                             'id': bundle_id})
        finally:
            def _cmp(a, b):
                if a['label'] < b['label']:
                    return -1
                else:
                    return 1

            for item in sorted(what_list_activities, _cmp):
                self._what_list.append(item)

            if self._what_widget_contents is not None:
                self._what_widget.remove(self._what_widget_contents)
            self._what_widget_contents = set_palette_list(self._what_list)
            self._what_widget.add(self._what_widget_contents)
            self._what_widget_contents.show()

    def _proj_list_button_clicked_cb(self, proj_list_button):
        if self._proj_list_button.props.active:
            self._what_widget.hide()
            self._what_search_button.hide()
        else:
            self._what_widget.show()
            self._what_search_button.show()
        self._update_if_needed()

    def __favorite_button_toggled_cb(self, favorite_button):
        self._update_if_needed()

    def is_filter_changed(self):
        return not (self._filter_type == self._default_filter_type and
                    self._what_filter == self._default_what_filter and
                    self._when_filter is None and
                    self._favorite_button.props.active is False and
                    self.search_entry.props.text == '')

    def clear_query(self):
        self.search_entry.props.text = ''
        self._filter_type = self._default_filter_type

        self._what_search_button.set_widget_icon(icon_name='view-type')
        self._what_search_button.set_widget_label(_('Anything'))
        self.set_what_filter(self._default_what_filter)

        self._when_search_button.set_widget_icon(icon_name='view-created')
        self._when_search_button.set_widget_label(_('Anytime'))
        self._when_filter = None

        '''
        self._with_search_button.set_widget_icon(icon_name='view-who')
        self._with_search_button.set_widget_label(_('Anyone'))
        self._with_filter = None
        '''

        self._favorite_button.props.active = False

        if self._proj_list_button.props.active:
            self._what_widget.show()
            self._what_search_button.show()
            self._proj_list_button.props.active = False

        self._update_if_needed()
Ejemplo n.º 51
0
class CreateToolbarBuilder(GObject.GObject):

    __gtype_name__ = 'CreateToolbar'

    __gsignals__ = {
        'create_new_game': (GObject.SignalFlags.RUN_FIRST, None, []),
        'create_equal_pairs': (GObject.SignalFlags.RUN_FIRST,
                               None, [GObject.TYPE_PYOBJECT]),
    }

    def __init__(self, activity):
        GObject.GObject.__init__(self)
        self.activity = activity
        self.toolbar = self.activity.get_toolbar_box().toolbar

        self._equal_pairs = ToggleToolButton('pair-non-equals')
        self._equal_pairs.set_tooltip(_('Match different tiles'))
        self._equal_pairs.connect('toggled', self._emit_equal_pairs)
        self.toolbar.insert(self._equal_pairs, -1)

        self._grouped = ToggleToolButton('grouped_game1')
        self._grouped.set_tooltip(_('Mixed tiles game'))
        self._grouped.connect('toggled', self._grouped_cb)
        self.toolbar.insert(self._grouped, -1)

        self._clear_button = ToolButton('edit-clear')
        self._clear_button.set_tooltip(_('Clear all tiles'))
        self._clear_button.connect('clicked', self._clear_game_bt)
        self.toolbar.insert(self._clear_button, -1)

        self.toolbar.show_all()

    def _add_widget(self, widget, expand=False):
        tool_item = Gtk.ToolItem()
        tool_item.set_expand(expand)
        tool_item.add(widget)
        widget.show()
        self.toolbar.insert(tool_item, -1)
        tool_item.show()

    def _clear_game_bt(self, button):
        if self.activity.game.model.is_demo or \
                len(self.activity.cardlist.pairs) == 0:
            self.clear_game()
        else:
            alert = Alert()
            alert.props.title = _('Clear all the tiles from the game?')
            icon = Icon(icon_name='dialog-ok')
            alert.add_button(1, _('Clear'), icon)
            icon = Icon(icon_name='dialog-cancel')
            alert.add_button(0, _('Do not clear'), icon)
            alert.connect('response', self._clear_game_alert_cb)
            self.activity.add_alert(alert)

    def _clear_game_alert_cb(self, alert, response_id):
        self.activity.remove_alert(alert)
        if response_id == 1:
            self.clear_game()

    def clear_game(self):
            self._equal_pairs.set_active(False)
            self._grouped.set_active(False)
            self.emit('create_new_game')

    def update_controls(self, active):
        self._equal_pairs.set_sensitive(active)
        self._grouped.set_sensitive(active)
        self._clear_button.set_sensitive(active)

    def _emit_equal_pairs(self, widget):
        if self._equal_pairs.get_active():
            self._equal_pairs.set_icon_name('pair-equals')
            self._equal_pairs.set_tooltip(_('Match identical tiles'))
            equal_pairs = '1'
        else:
            self._equal_pairs.set_icon_name('pair-non-equals')
            self._equal_pairs.set_tooltip(_('Match different tiles'))
            equal_pairs = '0'
        self.emit('create_equal_pairs', self._equal_pairs.get_active())
        logging.debug('createtoolbar._emit_equal_pairs')

        if self.activity.game.model.data['equal_pairs'] != equal_pairs:
            self.activity.game.model.data['equal_pairs'] = equal_pairs
            self.activity.game.model.mark_modified()

    def _grouped_cb(self, widget):
        if self._grouped.get_active():
            self._grouped.set_icon_name('grouped_game2')
            self._grouped.set_tooltip(_('Grouped tiles game'))
            divided = '1'
        else:
            self._grouped.set_icon_name('grouped_game1')
            self._grouped.set_tooltip(_('Mixed tiles game'))
            divided = '0'
        logging.debug('createtoolbar._grouped_cb')

        if self.activity.game.model.data['divided'] != divided:
            self.activity.game.model.data['divided'] = divided
            self.activity.game.model.mark_modified()

    def update_create_toolbar(self, widget, game_name, equal_pairs, grouped):
        self._equal_pairs.set_active(equal_pairs == '1')
        self._grouped.set_active(grouped == '1')
Ejemplo n.º 52
0
class   SpeechToolbar(Gtk.Toolbar):
    def __init__(self):
        Gtk.Toolbar.__init__(self)
        voicebar = Gtk.Toolbar()
        self.activity = None
        self.sorted_voices = [i for i in speech.voices()]
        self.sorted_voices.sort(self.compare_voices)
        default = 0
        for voice in self.sorted_voices:
            if voice[0] == 'default':
                break
            default = default + 1

        # Play button Image
        play_img = Gtk.Image()
        play_img.show()
        play_img.set_from_icon_name('media-playback-start',
                Gtk.IconSize.LARGE_TOOLBAR)

        # Pause button Image
        pause_img = Gtk.Image()
        pause_img.show()
        pause_img.set_from_icon_name('media-playback-pause',
                Gtk.IconSize.LARGE_TOOLBAR)

        # Play button
        self.play_btn = ToggleToolButton('media-playback-start')
        self.play_btn.show()
        self.play_btn.connect('toggled', self.play_cb, [play_img, pause_img])
        self.insert(self.play_btn, -1)
        self.play_btn.set_tooltip(_('Play / Pause'))

        self.voice_combo = ComboBox()
        self.voice_combo.connect('changed', self.voice_changed_cb)
        for voice in self.sorted_voices:
            self.voice_combo.append_item(voice, voice[0])
        self.voice_combo.set_active(default)
        combotool = ToolComboBox(self.voice_combo)
        self.insert(combotool, -1)
        combotool.show()

        self.pitchadj = Gtk.Adjustment(0, -100, 100, 1, 10, 0)
        pitchbar = Gtk.HScale()
        pitchbar.set_adjustment(self.pitchadj)
        pitchbar.set_draw_value(False)
        # pitchbar.set_update_policy(Gtk.UpdatePolicy.ALWAYS)
        pitchbar.set_size_request(150,15)
        pitchtool = Gtk.ToolItem()
        pitchtool.add(pitchbar)
        pitchtool.show()
        self.insert(pitchtool, -1)
        pitchbar.show()

        self.rateadj = Gtk.Adjustment(0, -100, 100, 1, 10, 0)
        ratebar = Gtk.HScale()
        ratebar.set_adjustment(self.rateadj)
        ratebar.set_draw_value(False)
        #ratebar.set_update_policy(Gtk.UpdatePolicy.ALWAYS)
        ratebar.set_size_request(150,15)
        ratetool = Gtk.ToolItem()
        ratetool.add(ratebar)
        ratetool.show()
        self.insert(ratetool, -1)
        ratebar.show()

    def compare_voices(self,  a,  b):
        if a[0].lower() == b[0].lower():
            return 0
        if a[0].lower() < b[0].lower():
            return -1
        if a[0].lower() > b[0].lower():
            return 1
        
    def voice_changed_cb(self, combo):
        speech.voice = combo.props.value
        if self.activity != None:
            speech.say(speech.voice[0])

    def pitch_adjusted_cb(self, get):
        speech.pitch = int(get.get_value())
        speech.say(_("pitch adjusted"))
        f = open(os.path.join(self.activity.get_activity_root(), 'instance',  'pitch.txt'),  'w')
        try:
            f.write(str(speech.pitch))
        finally:
            f.close()

    def rate_adjusted_cb(self, get):
        speech.rate = int(get.get_value())
        speech.say(_("rate adjusted"))
        f = open(os.path.join(self.activity.get_activity_root(), 'instance',  'rate.txt'),  'w')
        try:
            f.write(str(speech.rate))
        finally:
            f.close()
      
    def set_activity(self, activity):
        self.activity = activity
        if os.path.exists(os.path.join(activity.get_activity_root(), 'instance',  'pitch.txt')):
            f = open(os.path.join(activity.get_activity_root(), 'instance',  'pitch.txt'),  'r')
            line = f.readline()
            pitch = int(line.strip())
            self.pitchadj.set_value(pitch)
            speech.pitch = pitch
            f.close()
        if os.path.exists(os.path.join(activity.get_activity_root(), 'instance',  'rate.txt')):
            f = open(os.path.join(activity.get_activity_root(), 'instance',  'rate.txt'),  'r')
            line = f.readline()
            rate = int(line.strip())
            self.rateadj.set_value(rate)
            speech.rate = rate
            f.close()
        self.pitchadj.connect("value_changed", self.pitch_adjusted_cb)
        self.rateadj.connect("value_changed", self.rate_adjusted_cb)
    
    def play_cb(self, widget, images):
        widget.set_icon_widget(images[int(widget.get_active())])

        if widget.get_active():
            if speech.is_stopped():
                speech.play(self.activity.add_word_marks())
        else:
            speech.stop()
Ejemplo n.º 53
0
class TextToolbar(Gtk.Toolbar):

    _ACTION_TEXT_NAME = 'text'

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

        self._activity = activity
        self.properties = self._activity.area.tool

        self._text = DrawToolButton('text', activity.tool_group, _('Type'))
        self.insert(self._text, -1)
        self._text.connect('clicked', self.set_tool, self._ACTION_TEXT_NAME)

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

        self._bold = ToggleToolButton('format-text-bold')
        self.insert(self._bold, -1)
        self._bold.show()
        self._bold.connect('clicked', self.__bold_bt_cb)

        self._italic = ToggleToolButton('format-text-italic')
        self.insert(self._italic, -1)
        self._italic.show()
        self._italic.connect('clicked', self.__italic_bt_cb)

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

        self._font_size = FontSize()
        self.insert(self._font_size, -1)
        self._font_size_changed_id = self._font_size.connect(
            'changed', self.__font_size_changed_cb)

        self._font_combo = FontComboBox()
        self._fonts_changed_id = self._font_combo.connect(
            'changed', self.__font_changed_cb)

        fd = activity.area.get_font_description()
        font_name = fd.get_family()
        self._font_combo.set_font_name(font_name)
        self._font_size.set_font_size(int(fd.get_size() / Pango.SCALE))
        tool_item = ToolComboBox(self._font_combo)
        self.insert(tool_item, -1)
        self.show_all()

    def __bold_bt_cb(self, button):
        fd = self._activity.area.get_font_description()
        if button.get_active():
            fd.set_weight(Pango.Weight.BOLD)
        else:
            fd.set_weight(Pango.Weight.NORMAL)
        self._activity.area.set_font_description(fd)

    def __italic_bt_cb(self, button):
        fd = self._activity.area.get_font_description()
        if button.get_active():
            fd.set_style(Pango.Style.ITALIC)
        else:
            fd.set_style(Pango.Style.NORMAL)
        self._activity.area.set_font_description(fd)

    def __font_size_changed_cb(self, widget):
        fd = self._activity.area.get_font_description()
        value = widget.get_font_size()
        fd.set_size(int(value) * Pango.SCALE)
        self._activity.area.set_font_description(fd)

    def __font_changed_cb(self, combo):
        fd = self._activity.area.get_font_description()
        font_name = combo.get_font_name()
        fd.set_family(font_name)
        self._activity.area.set_font_description(fd)

    def get_active_text(self, combobox):
        model = combobox.get_model()
        active = combobox.get_active()
        if active < 0:
            return None
        return model[active][0]

    def set_tool(self, widget, tool_name):
        self.properties['name'] = tool_name
        self._activity.area.set_tool(self.properties)
Ejemplo n.º 54
0
    def __init__(self, handle):

        activity.Activity.__init__(self, handle)

        # avahi initialization
        self._service = None

        toolbar_box = ToolbarBox()

        self._vbox = Gtk.VBox()

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

        # get information from gconf
        client = GConf.Client.get_default()
        self._age = client.get_int('/desktop/sugar/user/age')
        self._gender = client.get_string('/desktop/sugar/user/gender')
        if self._gender is None:
            self._gender = 'male'
        teacher = (self._age >= 25)

        # if age is not configured age == 0

        if teacher or self._age == 0:
            teacher_button = ToggleToolButton('%s-7' % self._gender)
            teacher_button.set_tooltip(_('Teacher'))
            teacher_button.show()
            teacher_button.connect('toggled', self.__start_teacher_cb)
            toolbar_box.toolbar.insert(teacher_button, -1)
            if teacher:
                teacher_button.set_active(True)

        if not teacher or self._age == 0:
            student_button = ToggleToolButton('%s-2' % self._gender)
            student_button.set_tooltip(_('Student'))
            student_button.show()
            student_button.connect('toggled', self.__start_student_cb)
            toolbar_box.toolbar.insert(student_button, -1)
            if self._age > 0:
                # is a student
                student_button.set_active(True)

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

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

        self.set_toolbar_box(toolbar_box)
        toolbar_box.show()

        self.scrolled = Gtk.ScrolledWindow()
        self.scrolled.add_with_viewport(self._vbox)

        self.scrolled.show_all()
        self.set_canvas(self.scrolled)

        self._inhibit_suspend()
Ejemplo n.º 55
0
    def __init__(self, abiword_canvas):
        GObject.GObject.__init__(self)

        self.font_name_combo = FontComboBox()
        self.font_name_combo.set_font_name('Sans')
        self._fonts_changed_id = self.font_name_combo.connect(
            'changed', self._font_changed_cb, abiword_canvas)
        self._abi_handler = abiword_canvas.connect('font-family',
                                                   self._font_family_cb)
        self.insert(ToolComboBox(self.font_name_combo), -1)

        self.font_size = FontSize()
        self._abi_handler = abiword_canvas.connect('font-size',
                                                   self._font_size_cb)
        self._changed_id = self.font_size.connect(
            'changed', self._font_size_changed_cb, abiword_canvas)
        self.insert(self.font_size, -1)

        bold = ToggleToolButton('format-text-bold')
        bold.set_tooltip(_('Bold'))
        bold.props.accelerator = '<Ctrl>B'
        bold_id = bold.connect('clicked', lambda sender:
                               abiword_canvas.toggle_bold())
        abiword_canvas.connect('bold', lambda abi, b:
                               self._setToggleButtonState(bold, b, bold_id))
        self.insert(bold, -1)

        italic = ToggleToolButton('format-text-italic')
        italic.set_tooltip(_('Italic'))
        italic.props.accelerator = '<Ctrl>I'
        italic_id = italic.connect('clicked', lambda sender:
                                   abiword_canvas.toggle_italic())
        abiword_canvas.connect('italic', lambda abi, b:
                               self._setToggleButtonState(italic, b,
                                                          italic_id))
        self.insert(italic, -1)

        underline = ToggleToolButton('format-text-underline')
        underline.set_tooltip(_('Underline'))
        underline.props.accelerator = '<Ctrl>U'
        underline_id = underline.connect('clicked', lambda sender:
                                         abiword_canvas.toggle_underline())
        abiword_canvas.connect('underline', lambda abi, b:
                               self._setToggleButtonState(underline, b,
                                                          underline_id))
        self.insert(underline, -1)

        # for super/subscript, we're using the same keyboard shorcuts as
        # abiword: <C-^> and <C-_>
        super_btn = ToggleToolButton('format-text-super')
        super_btn.set_tooltip(_('Superscript'))
        # found with gtk.accelerator_name
        super_btn.props.accelerator = '<Ctrl>asciicircum'
        super_id = super_btn.connect('clicked', lambda sender:
                               abiword_canvas.toggle_super())
        # no, this isn't a mistake. The method is called `toggle_super()', but
        # the *signal* is called `superscript'. Same goes for sub{script,}.
        abiword_canvas.connect('superscript', lambda abi, b:
                               self._setToggleButtonState(super_btn, b,
                                                          super_id))
        self.insert(super_btn, -1)

        sub = ToggleToolButton('format-text-sub')
        sub.set_tooltip(_('Subscript'))
        sub.props.accelerator = '<Ctrl>underscore'
        sub_id = sub.connect('clicked', lambda sender:
                               abiword_canvas.toggle_sub())
        abiword_canvas.connect('subscript', lambda abi, b:
                               self._setToggleButtonState(sub, b, sub_id))
        self.insert(sub, -1)

        color = ColorToolButton()
        color.connect('notify::color', self._text_color_cb,
                      abiword_canvas)
        tool_item = Gtk.ToolItem()
        tool_item.add(color)
        self.insert(tool_item, -1)
        abiword_canvas.connect(
            'color', lambda abi, r, g, b:
            color.set_color(Gdk.Color(r * 256, g * 256, b * 256)))

        # MAGIC NUMBER WARNING: Secondary toolbars are not a standard height?
        self.set_size_request(-1, style.GRID_CELL_SIZE)

        def append_align(icon_name, tooltip, do_abi_cb, style_name, button,
                         menu_box):
            menu_item = AbiMenuItem(abiword_canvas, style_name, do_abi_cb,
                                    icon_name, tooltip, button)
            menu_box.append_item(menu_item)
            menu_item.show()

        self._aligment_btn = ToolButton(icon_name='format-justify-left')
        self._aligment_btn.props.tooltip = _('Choose alignment')
        self._aligment_btn.props.hide_tooltip_on_click = False
        self._aligment_btn.palette_invoker.props.toggle_palette = True

        menu_box = PaletteMenuBox()
        self._aligment_btn.props.palette.set_content(menu_box)
        menu_box.show()

        append_align('format-justify-left', _('Left justify'),
                     abiword_canvas.align_left, 'left-align',
                     self._aligment_btn, menu_box)

        append_align('format-justify-center', _('Center justify'),
                     abiword_canvas.align_center, 'center-align',
                     self._aligment_btn, menu_box)

        append_align('format-justify-right', _('Right justify'),
                     abiword_canvas.align_right, 'right-align',
                     self._aligment_btn, menu_box)

        append_align('format-justify-fill', _('Fill justify'),
                     abiword_canvas.align_justify, 'justify-align',
                     self._aligment_btn, menu_box)

        self.insert(self._aligment_btn, -1)

        self.show_all()
Ejemplo n.º 56
0
class ViewToolbar(Gtk.Toolbar):
    __gtype_name__ = 'ViewToolbar'

    __gsignals__ = {
        'go-fullscreen': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,
                          ([])),
        'toggle-index-show': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,
                              ([bool])),
        'toggle-tray-show': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE,
                             ([bool])), }

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

        self._view = None

        self._navigator_button = ToggleToolButton('view-list')
        self._navigator_button.set_tooltip(_('Table of contents'))
        self._navigator_button.connect('toggled', self.__navigator_toggled_cb)
        self.insert(self._navigator_button, -1)

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

        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-to-width')
        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()

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

        self._zoom_to_original = ToolButton('zoom-original')
        self._zoom_to_original.set_tooltip(_('Actual size'))
        self._zoom_to_original.connect('clicked', self._actual_size_cb)
        self.insert(self._zoom_to_original, -1)
        self._zoom_to_original.show()

        spacer = Gtk.SeparatorToolItem()
        spacer.props.draw = True
        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.traybutton = ToggleToolButton('tray-show')
        self.traybutton.set_icon_name('tray-favourite')
        self.traybutton.connect('toggled', self.__tray_toggled_cb)
        #self.traybutton.props.sensitive = False
        self.traybutton.props.active = False
        self.insert(self.traybutton, -1)
        self.traybutton.show()

        self._view_notify_zoom_handler = None

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

        self._rotate_left = ToolButton('rotate_anticlockwise')
        self._rotate_left.set_tooltip(_('Rotate left'))
        self._rotate_left.connect('clicked', self._rotate_left_cb)
        self.insert(self._rotate_left, -1)
        self._rotate_left.show()

        self._rotate_right = ToolButton('rotate_clockwise')
        self._rotate_right.set_tooltip(_('Rotate right'))
        self._rotate_right.connect('clicked', self._rotate_right_cb)
        self.insert(self._rotate_right, -1)
        self._rotate_right.show()

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

    def show_nav_button(self):
        self._navigator_button.show()
        self._spacer_navigator.show()

    def zoom_in(self):
        self._view.zoom_in()
        self._update_zoom_buttons()

    def _zoom_in_cb(self, button):
        self.zoom_in()

    def _rotate_left_cb(self, button):
        self._view.rotate_left()

    def _rotate_right_cb(self, button):
        self._view.rotate_right()

    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 __navigator_toggled_cb(self, button):
        self.emit('toggle-index-show', button.get_active())

    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()
        self._zoom_to_fit.props.sensitive = self._view.can_zoom_to_width()
        self._zoom_to_original.props.sensitive = self._view.can_zoom_to_width()
        self._rotate_left.props.sensitive = self._view.can_rotate()
        self._rotate_right.props.sensitive = self._view.can_rotate()

    def _zoom_to_fit_cb(self, menu_item):
        self._view.zoom_to_best_fit()
        self._update_zoom_buttons()

    def _actual_size_cb(self, menu_item):
        self._view.zoom_to_actual_size()
        self._update_zoom_buttons()

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

    def __tray_toggled_cb(self, button):
        self.emit('toggle-tray-show', button.get_active())
        if button.props.active:
            self.traybutton.set_tooltip(_('Show Tray'))
        else:
            self.traybutton.set_tooltip(_('Hide Tray'))
Ejemplo n.º 57
0
    def _build_toolbox(self):
        toolbar_box = ToolbarBox()

        self.max_participants = 1

        activity_button = ActivityToolbarButton(self)
        activity_toolbar = activity_button.page

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

        self._secondary_toolbar = Gtk.Toolbar()
        self._secondary_toolbar_button = ToolbarButton(
            page=self._secondary_toolbar,
            icon_name='system-search')
        self._secondary_toolbar.show()
        self._toolbar.insert(self._secondary_toolbar_button, -1)
        self._secondary_toolbar_button.hide()

        show_list = ToggleToolButton('view-list')
        show_list.set_active(True)
        show_list.set_tooltip(_('Show list of files'))
        show_list.connect('toggled', self._list_toggled_cb)
        self._toolbar.insert(show_list, -1)
        show_list.show()

        copy = CopyButton()
        copy.connect('clicked', self.__copy_clicked_cb)
        self._toolbar.insert(copy, -1)

        wrap_btn = ToggleToolButton("format-wrap")
        wrap_btn.set_tooltip(_('Word Wrap'))
        wrap_btn.connect('clicked', self._wrap_cb)
        self._toolbar.insert(wrap_btn, -1)

        self.search_entry = iconentry.IconEntry()
        self.search_entry.set_size_request(Gdk.Screen.width() / 3, -1)
        self.search_entry.set_icon_from_name(
            iconentry.ICON_ENTRY_PRIMARY, 'entry-search')
        self.search_entry.add_clear_button()
        self.search_entry.connect('activate', self._search_entry_activate_cb)
        self.search_entry.connect('changed', self._search_entry_changed_cb)
        self._search_item = Gtk.ToolItem()
        self._search_item.add(self.search_entry)
        self._toolbar.insert(self._search_item, -1)

        self._search_prev = ToolButton('go-previous-paired')
        self._search_prev.set_tooltip(_('Previous'))
        self._search_prev.connect('clicked', self._search_prev_cb)
        self._toolbar.insert(self._search_prev, -1)

        self._search_next = ToolButton('go-next-paired')
        self._search_next.set_tooltip(_('Next'))
        self._search_next.connect('clicked', self._search_next_cb)
        self._toolbar.insert(self._search_next, -1)

        self._update_search_buttons()

        self.collector_palette = CollectorPalette(self)
        collector_btn = ToolButton('log-export')
        collector_btn.set_palette(self.collector_palette)
        collector_btn.connect('clicked', self._logviewer_cb)
        collector_btn.show()
        activity_toolbar.insert(collector_btn, -1)

        self._delete_btn = ToolButton('list-remove')
        self._delete_btn.set_tooltip(_('Delete Log File'))
        self._delete_btn.connect('clicked', self._delete_log_cb)
        self._toolbar.insert(self._delete_btn, -1)

        self._separator = Gtk.SeparatorToolItem()
        self._separator.set_expand(True)
        self._separator.set_draw(False)
        self._toolbar.insert(self._separator, -1)

        self._stop_btn = StopButton(self)
        self._toolbar.insert(self._stop_btn, -1)

        toolbar_box.show_all()
        self.set_toolbar_box(toolbar_box)
Ejemplo n.º 58
0
class ViewToolbar(Gtk.Toolbar):
    def __init__(self, activity):
        GObject.GObject.__init__(self)

        self._browser = None

        self._activity = activity

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

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

        self.zoom_original = ToolButton('zoom-original')
        self.zoom_original.set_tooltip(_('Actual size'))
        self.zoom_original.connect('clicked', self.__zoom_original_clicked_cb)
        self.insert(self.zoom_original, -1)
        self.zoom_original.show()

        self.separator = Gtk.SeparatorToolItem()
        self.separator.set_draw(True)
        self.insert(self.separator, -1)
        self.separator.show()

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

        self.traybutton = ToggleToolButton('tray-show')
        self.traybutton.set_icon_name('tray-favourite')
        self.traybutton.connect('toggled', self.__tray_toggled_cb)
        self.traybutton.props.sensitive = False
        self.traybutton.props.active = False
        self.insert(self.traybutton, -1)
        self.traybutton.show()

        tabbed_view = self._activity.get_canvas()

        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):
        self._connect_to_browser(tabbed_view.props.current_browser)

    def _connect_to_browser(self, browser):
        self._browser = browser
        self._update_zoom_buttons()

    def _update_zoom_buttons(self):
        is_webkit_browser = isinstance(self._browser, Browser)
        self.zoomin.set_sensitive(is_webkit_browser)
        self.zoomout.set_sensitive(is_webkit_browser)
        self.zoom_original.set_sensitive(is_webkit_browser)

    def __zoom_original_clicked_cb(self, button):
        tabbed_view = self._activity.get_canvas()
        tabbed_view.props.current_browser.set_zoom_level(ZOOM_ORIGINAL)

    def __zoomin_clicked_cb(self, button):
        tabbed_view = self._activity.get_canvas()
        tabbed_view.props.current_browser.zoom_in()

    def __zoomout_clicked_cb(self, button):
        tabbed_view = self._activity.get_canvas()
        tabbed_view.props.current_browser.zoom_out()

    def __fullscreen_clicked_cb(self, button):
        self._activity.fullscreen()

    def __tray_toggled_cb(self, button):
        if button.props.active:
            self._activity.tray.show()
        else:
            self._activity.tray.hide()
        self.update_traybutton_tooltip()

    def update_traybutton_tooltip(self):
        if not self.traybutton.props.active:
            self.traybutton.set_tooltip(_('Show Tray'))
        else:
            self.traybutton.set_tooltip(_('Hide Tray'))