Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/about.py
diff options
context:
space:
mode:
Diffstat (limited to 'about.py')
-rw-r--r--about.py314
1 files changed, 314 insertions, 0 deletions
diff --git a/about.py b/about.py
new file mode 100644
index 0000000..6dd47a8
--- /dev/null
+++ b/about.py
@@ -0,0 +1,314 @@
+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 = '<Ctrl>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')
+
+