from gettext import gettext as _ import gtk import gobject from sugar.graphics.toolbutton import ToolButton from sugar.graphics import style from sugar.graphics.icon import Icon from sugar.bundle.activitybundle import ActivityBundle from sugar.activity.activity import get_bundle_path from sugar.graphics.toolbutton import ToolButton from sugar.graphics.toolcombobox import ToolComboBox from sugar.graphics.combobox import ComboBox import os def get_info(): return { 10: { 'title':_('About this activity'), 'widget':AboutThis}, 20: { 'title':_('How to contribute'), 'widget':AboutHacking}, 30: { 'title':_('License'), 'widget':AboutLicense}, 40: { 'title':_('Credits'), 'widget':AboutCredits}, } class AboutPanel(gtk.EventBox): exists = False def __init__(self, *args, **kwargs): super(AboutPanel, self).__init__(*args, **kwargs) self.scrollwindow = gtk.ScrolledWindow() self.scrollwindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) self.add(self.scrollwindow) self.scrollwindow.show() self.content_vbox = gtk.VBox() self.viewport = gtk.Viewport() self.viewport.add(self.content_vbox) self.viewport.modify_bg(gtk.STATE_NORMAL, style.COLOR_WHITE.get_gdk_color()) self.scrollwindow.add(self.viewport) self.show_all() def add_section_from_file(self, filename, title=None): text = None filename = os.path.join(get_bundle_path(), filename) lang = os.environ['LANG'] if lang.endswith("UTF-8"): lang = lang[:-6] try_file = filename + "." + lang if os.path.isfile(try_file): filename = try_file else: try_file = filename + "." + lang.split("_")[0] if os.path.isfile(try_file): filename = try_file try: fd = open(filename) # remove 0x0c page breaks which can't be rendered in text views text = fd.read().replace('\x0c', '') fd.close() except IOError: return False if text: self.add_section(text, title) return True def add_section(self, text, title=None): if title: vbox = gtk.VBox() separator = gtk.HSeparator() vbox.pack_start(separator, expand=False) separator.show() label= gtk.Label(title) label.set_alignment(0, 0) vbox.pack_start(label, expand=False) label.show() self.content_vbox.pack_start(vbox, expand=False) vbox = gtk.VBox() vbox.set_border_width(style.DEFAULT_SPACING * 2) # This is a workaround in sweets #view = gtk.Label(text) #view.set_line_wrap(True) #view.set_alignment(0, 0) # FIXME: This is the prefered method, scrolling goes crazy in sweets view = gtk.TextView() view.unset_flags(gtk.CAN_FOCUS) view.set_cursor_visible(False) view.set_editable(False) view.get_buffer().set_text(text) view.set_wrap_mode(gtk.WRAP_WORD) vbox.pack_start(view) self.content_vbox.pack_start(vbox, expand=False, fill=False) view.show() class AboutThis(AboutPanel): def __init__(self, *args, **kwargs): super(AboutThis, self).__init__(*args, **kwargs) bundle_name = ActivityBundle(get_bundle_path()).get_bundle_name() title = _("About %s Activity" % bundle_name) self.exists += self.add_section_from_file("ABOUT", title) title = _('News') self.exists += self.add_section_from_file("NEWS", title) title = _('Read me') self.exists += self.add_section_from_file("README", title) if not self.exists: self.add_section(_("There is currently no ABOUT file for this activity."), title) class AboutLicense(AboutPanel): def __init__(self, *args, **kwargs): super(AboutLicense, self).__init__(*args, **kwargs) title = _("Know your rights") self.exists += self.add_section_from_file("COPYING", title) class AboutCredits(AboutPanel): def __init__(self, *args, **kwargs): super(AboutCredits, self).__init__(*args, **kwargs) title = _("Authors") self.exists += self.add_section_from_file("AUTHORS", title) title = _("Mantainers") self.exists += self.add_section_from_file("MANTAINERS", title) class AboutHacking(AboutPanel): def __init__(self, *args, **kwargs): super(AboutHacking, self).__init__(*args, **kwargs) title = _("Contributing code") self.exists += self.add_section_from_file("HACKING", title) self.exists += self.add_section_from_file("DEVELOPING", title) title = _("Pending development tasks") self.exists += self.add_section_from_file("TODO", title) class AboutButton(ToolButton): def __init__(self, activity, **kwargs): ToolButton.__init__(self, 'activity-about', **kwargs) self.props.tooltip = _('About this activity') self.props.accelerator = 'H' self.connect('clicked', self.__about_button_clicked_cb, activity) def __about_button_clicked_cb(self, button, activity): about_dialog = _AboutDialog() about_dialog.set_transient_for(self.get_toplevel()) about_dialog.show_all() class _AboutDialog(gtk.Window): def __init__(self): super(_AboutDialog, self).__init__() offset = style.GRID_CELL_SIZE width = gtk.gdk.screen_width() - offset * 2 height = gtk.gdk.screen_height() - offset * 2 self.set_size_request(width, height) self.set_border_width(style.LINE_WIDTH) self.modify_bg(gtk.STATE_NORMAL, style.COLOR_WHITE.get_gdk_color()) vbox = gtk.VBox() self.add(vbox) vbox.show() self.set_position(gtk.WIN_POS_CENTER_ALWAYS) self.set_decorated(False) self.set_resizable(False) self.set_modal(True) self.toolbar = _DialogToolbar() self.toolbar.connect('stop-clicked', self._stop_clicked_cb) self.toolbar.connect('infopanel-changed', self._info_changed_cb) vbox.pack_start(self.toolbar, False) bundle = ActivityBundle(get_bundle_path()) icon = Icon(pixel_size=style.XLARGE_ICON_SIZE*2, file=bundle.get_icon()) icon_button = gtk.Button() icon_button.set_image(icon) icon_button.unset_flags(gtk.CAN_FOCUS) container = gtk.VButtonBox() container.add(icon_button) container.set_layout(gtk.BUTTONBOX_START) hbox = gtk.HBox() hbox.set_border_width(style.DEFAULT_SPACING * 2) hbox.set_spacing(style.DEFAULT_SPACING) hbox.pack_start(container, expand=False, fill=False) vbox.pack_start(hbox, expand=True, fill=True) self.content_vbox = gtk.VBox() self.content_vbox.set_border_width(style.DEFAULT_SPACING) hbox.pack_start(self.content_vbox, expand=True, fill=True) self._notebook = gtk.Notebook() self._notebook.set_show_tabs(False) self.panel = get_info() for key in sorted(self.panel.keys()): if self.panel[key]['widget']: page = self.panel[key]['widget']() if page.exists: self._notebook.append_page(page) self.toolbar.info_combo.append_item(key, self.panel[key]['title']) self.toolbar.panel[key]=self.panel[key] self.content_vbox.pack_start(self._notebook) self.toolbar.info_combo.set_active(0) self.connect('realize', self._realize_cb) def _stop_clicked_cb(self, source): self.destroy() def _info_changed_cb(self, source): active = self.toolbar.info_combo.get_active() self._notebook.set_current_page(active) def _realize_cb(self, source): self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) self.window.set_accept_focus(True) class _DialogToolbar(gtk.Toolbar): panel = {} __gsignals__ = { 'stop-clicked' : (gobject.SIGNAL_RUN_LAST, None, ()), 'infopanel-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), } def __init__(self): super(_DialogToolbar, self).__init__() self._add_separator() icon_button = Icon(pixel_size=style.STANDARD_ICON_SIZE, icon_name='activity-about') #icon_button.connect('clicked', self._icon_button_clicked_cb) self._add_widget(icon_button) icon_button.unset_flags(gtk.CAN_FOCUS) self._add_separator() self.info_combo = ComboBox() self.info_combo.props.sensitive = True self._info_changed_cb_id = self.info_combo.connect('changed', self._info_changed_cb) combotool = ToolComboBox(self.info_combo) self.insert(combotool, -1) combotool.show() #self.panel = get_info() #for key in sorted(self.panel.keys()): # self.info_combo.append_item(key, self.panel[key]['title']) #self.info_combo.set_active(0) self._back = ToolButton('go-previous-paired') self._back.props.sensitive = False self._back.connect('clicked', self.__go_back_cb) self.insert(self._back, -1) self._back.show() self._forward = ToolButton('go-next-paired') #self._forward.props.sensitive = False self._forward.connect('clicked', self.__go_forward_cb) self.insert(self._forward, -1) self._forward.show() self._add_separator(expand=True) stop = ToolButton(icon_name='dialog-cancel') stop.set_tooltip(_('Done')) stop.connect('clicked', self._stop_clicked_cb) self.add(stop) def __go_back_cb(self, widget): active = max(0, self.info_combo.get_active() - 1) self.info_combo.set_active(active) self._info_changed_cb(widget) self.__set_nav_buttons(active) def __go_forward_cb(self, widget): active = min(len(self.panel.keys())-1, self.info_combo.get_active() + 1) self.info_combo.set_active(active) self._info_changed_cb(widget) self.__set_nav_buttons(active) def __set_nav_buttons(self,active): if active==0: self._back.props.sensitive = False else: self._back.props.sensitive = True if active==len(self.panel.keys())-1: self._forward.props.sensitive = False else: self._forward.props.sensitive = True def _info_changed_cb(self, widget): self.__set_nav_buttons(widget.get_active()) self.emit('infopanel-changed') def _add_separator(self, expand=False): separator = gtk.SeparatorToolItem() separator.set_expand(expand) separator.set_draw(False) self.add(separator) def _add_widget(self, widget): tool_item = gtk.ToolItem() tool_item.add(widget) self.add(tool_item) def _stop_clicked_cb(self, button): self.emit('stop-clicked')