class ToggleItem(Item):
    __gsignals__ = {
        'toggled':
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN, ))
    }

    def __init__(self, default_value=True, stock_id=None, important=False):
        Item.__init__(self, stock_id, important)
        self.default_value = default_value
        self.active = default_value

    def get_menu_item(self):
        return None

    def toggled_cb(self, widget):
        active = widget.get_active()
        self.toolitem.set_active(active)
        self.active = active
        self.emit('toggled', active)

    def get_tool_item(self):
        self.toolitem = ToggleToolButton()
        self.toolitem.set_named_icon(
            stock.icons[self._stock_id] if self._stock_id in
            stock.icons else self._stock_id)
        self.toolitem.set_active(self.default_value)
        self.toolitem.connect('toggled', self.toggled_cb)
        self.setup_tooltip()
        return self.toolitem
Example #2
0
class ToolbarBuilder():
    def __init__(self, edit, toolbar):
        self.edit = edit

        self.txt_toggle = ToggleToolButton('ascii')
        self.img_toggle = ToggleToolButton('image')

        self.txt_toggle.set_tooltip(_('Text'))
        self.txt_toggle.connect('toggled', self._toggle_cb,
                                [self.txt_toggle, self.img_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])
        toolbar.insert(self.img_toggle, -1)

        self.separator = gtk.SeparatorToolItem()
        toolbar.insert(self.separator, -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)

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

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

        if not widget.get_active():
            index = 2
        else:
            another = toggles[0] == widget and 1 or 0
            toggles[another].set_active(False)
            index = int(not another)

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

        if book.wiki.article:
            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)
Example #3
0
File: geo.py Project: 52North/glaps
    def enable_toggle_crosslines(self, view):
        """
        Enables tool to toggle crosslines.

        @param view: The view for which the crosslines shall be displayed.
        """
        toggle_crossline_btn = ToggleToolButton('toggle-crosslines')
        toggle_crossline_btn.set_tooltip(_('Show crossline.'))
        toggle_crossline_btn.set_active(GeoCanvas._CROSSLINES)
        toggle_crossline_btn.connect('clicked', view.toggle_crossline_cb)
        toggle_crossline_btn.show()
        self.insert(toggle_crossline_btn, -1)
Example #4
0
File: geo.py Project: 52North/glaps
    def enable_center_current_position(self, on_center_on_current_position):
        """
        Enables tool to set the map center to current lon/lat position.

        @param on_goto_current_position: The callback function to be called when
        user wants to center the map to current position.
        """
        goto_current_pos_btn = ToggleToolButton('goto-current-pos')
        goto_current_pos_btn.set_tooltip(_('Center map on my position.'))
        goto_current_pos_btn.connect('clicked', on_center_on_current_position)
        goto_current_pos_btn.set_active(GeoCanvas._CENTER_MAP)
        goto_current_pos_btn.show()
        self.insert(goto_current_pos_btn, -1)
Example #5
0
class AbominadeActivity(activity.Activity):
  """Abominade Monolith"""

  def __init__(self, handle):
    """Set up the activity."""
    activity.Activity.__init__(self, handle)

    """Create the user interface."""
    self.stack = gtk.VBox()
    self.add(self.stack)
    self.hpaned = gtk.HPaned()
    self.stack.pack_end(self.hpaned)
    self.vpaned = gtk.VPaned()
    self.hpaned.pack2(self.vpaned, shrink=False)
    self.hpaned.set_position(200)
    self.plugins = window.PluginTabs()
    self.hpaned.pack1(self.plugins.widget, shrink=False)

    self.model = Abominade(self)

    self.plugins.add_main(self.model.buffers)
    self.plugins.add_tab(self.model.files)
    self.plugins.add_tab(self.model.bookmarks)
    self.plugins.add_tab(self.model.terminals)
    self.vpaned.pack1(self.model.vim.widget, resize=True, shrink=False)
    self.vpaned.pack2(self.model.terminals.book, resize=False, shrink=False)
    # make sure buffers list isn't zero-height
    if self.plugins.stack.get_position() < 200:
      self.plugins.stack.set_position(200)
    
    self.stack.show_all()
    self.set_canvas(self.stack)

    self.init_interpreter()
    label = gtk.Label("Consola")
    self.model.terminals.book.prepend_page(self.interpreter, tab_label=label)

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

    # toolbar with the new toolbar redesign
    toolbar_box = ToolbarBox()

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

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

    self.sidebar_button = ToggleToolButton('folder')
    self.sidebar_button.set_active(True)
    self.sidebar_button.set_tooltip('Consola')
    self.sidebar_button.accelerator = "<Ctrl>grave"
    self.sidebar_button.connect('clicked', self.toggle_sidebar)
    toolbar_box.toolbar.insert(self.sidebar_button, -1)
    self.sidebar_button.show()

    self.bottom_button = ToggleToolButton('tray-show')
    self.bottom_button.set_active(True)
    self.bottom_button.set_tooltip('Consola')
    self.bottom_button.accelerator = "<Ctrl>grave"
    self.bottom_button.connect('clicked', self.toggle_bottom)
    toolbar_box.toolbar.insert(self.bottom_button, -1)
    self.bottom_button.show()

    share_button = ShareButton(self)
    toolbar_box.toolbar.insert(share_button, -1)
    share_button.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()

    self.model.start()

  def on_widget__delete_event(self, window, event):
    self.stop()
    return True

  def focus_files(self):
    self.plugins.focus_delegate(self.model.files)

  def focus_bookmarks(self):
    self.plugins.focus_delegate(self.model.bookmarks)

  def focus_terminals(self):
    self.plugins.focus_delegate(self.model.terminals)

  def focus_buffers(self):
    self.buffers.items.grab_focus()

  def focus_interpreter(self, widget, event):
    self.interpreter.text.grab_focus()
    return True

  def toggle_bottom(self, e):
    bottom = self.vpaned.get_child2()
    if bottom.props.visible:
      bottom.hide()
    else:
      bottom.show()

  def toggle_sidebar(self, e):
    sidebar = self.hpaned.get_child1()
    if sidebar.props.visible:
      sidebar.hide()
    else:
      sidebar.show()

  def init_interpreter(self):
    # diferido unos segundos para evitar ver errores superfluos al iniciar
    try:
        raise None
    except:
        frame = sys.exc_info()[2].tb_frame
    self.interpreter = GTKInterpreterConsole(frame)
    self.interpreter.text.connect('button-press-event', self.focus_interpreter)
    self.interpreter.show()
    return False
class CreateToolbar(gtk.Toolbar):
    __gtype_name__ = 'CreateToolbar'

    __gsignals__ = {
        'create_new_game': (SIGNAL_RUN_FIRST, None, []), 
        'create_load_game': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]), 
        'create_save_game': (SIGNAL_RUN_FIRST, None, 3 * [TYPE_PYOBJECT]), 
        'create_equal_pairs': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT]), 
    }
    
    def __init__(self, activity):
        gtk.Toolbar.__init__(self)
        self.activity = activity
        self._lock = True
        
        # New Button
        new_icon = join(dirname(__file__), 'images', 'game-new.svg')
        new_image = gtk.Image()
        new_image.set_from_file(new_icon)
        self._new_button = ToolButton()
        self._new_button.set_icon_widget(new_image)
        self._new_button.set_tooltip(_('New game'))
        self._new_button.connect('clicked', self._new_game_bt)
        self._add_widget(self._new_button)
        
        # Load Button
        load_icon = join(dirname(__file__), 'images', 'game-load.svg')
        load_image = gtk.Image()
        load_image.set_from_file(load_icon)
        self._load_button = ToolButton()
        self._load_button.set_icon_widget(load_image)
        self._load_button.set_tooltip(_('Load game'))
        self._load_button.connect('clicked', self._load_game)
        self._add_widget(self._load_button)
            
        # Save Button
        save_icon = join(dirname(__file__), 'images', 'game-save.svg')
        save_image = gtk.Image()
        save_image.set_from_file(save_icon)
        self._save_button = ToolButton()
        self._save_button.set_icon_widget(save_image)
        self._save_button.set_tooltip(_('Save game'))
        self._save_button.connect('clicked', self._save_game_bt)
        self._save_button.set_sensitive(False)
        self._add_widget(self._save_button)
    
        # Separator
        separator2 = gtk.SeparatorToolItem()
        separator2.set_draw(True)
        self.insert(separator2, -1)
        
        self._add_widget(gtk.Label(_('Game name') + ': '))
        self.game_name_entry = gtk.Entry()
        self._add_widget(self.game_name_entry) 
        
        self._equal_pairs = gtk.CheckButton(_('Equal pairs'))   
        self._add_widget(self._equal_pairs)
        self._equal_pairs.connect('toggled', self._emit_equal_pairs)
                
        self._grouped_icon1 = join(dirname(__file__), 'images', 'equal_pairs1.svg')
        self._grouped_icon2 = join(dirname(__file__), 'images', 'equal_pairs2.svg')
        self._grouped_image1 = gtk.Image()
        self._grouped_image2 = gtk.Image()
        self._grouped_image1.set_from_file(self._grouped_icon1)
        self._grouped_image2.set_from_file(self._grouped_icon2)
        self._grouped = ToggleToolButton()
        self._grouped.set_icon_widget(self._grouped_image1)
        self._grouped.set_tooltip(_('Click for grouped game'))
        self._grouped.connect('toggled', self._grouped_cb)
        self._add_widget(self._grouped)
        
    def _add_widget(self, widget, expand=False):
        tool_item = gtk.ToolItem()
        tool_item.set_expand(expand)
        tool_item.add(widget)
        widget.show()
        self.insert(tool_item, -1)
        tool_item.show()
        
    def _game_changed_cb(self, combobox, game_name):
        self.game_name_entry.set_text(game_name)
        self.emit('create_load_game', game_name)
  
    def _load_game(self, button):
        chooser = ObjectChooser(_('Choose memorize game'),
                parent=self.activity,
                flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
        jobject = ''
        try:
            result = chooser.run()
            if result == gtk.RESPONSE_ACCEPT:
                logging.debug('ObjectChooser: %r' % chooser.get_selected_object())
                jobject = chooser.get_selected_object()
                if not jobject or  not jobject.file_path:
                    return
        finally:
            chooser.destroy()
            del chooser
            
        if jobject and jobject.file_path:    
            self.emit('create_load_game', jobject.file_path)
            self._save_button.set_sensitive(False)
        
    def _new_game_bt(self, button):
        self.game_name_entry.set_text('')
        self._equal_pairs.set_active(False)
        self._grouped.set_active(False)
        self.emit('create_new_game')
        self._new_button.set_sensitive(False)
        self._save_button.set_sensitive(False)

    def _save_game_bt(self, button):
        self.emit('create_save_game', self.game_name_entry.get_text(), self._equal_pairs.get_active(), self._grouped.get_active())
        self._save_button.set_sensitive(False)
        
    def _emit_equal_pairs(self, checkbutton):
        self.emit('create_equal_pairs', checkbutton.get_active())
        self._save_button.set_sensitive(True)
        
    def _grouped_cb(self, widget):
        self._save_button.set_sensitive(True)
        if self._grouped.get_active():
            self._grouped.set_icon_widget(self._grouped_image2)
            self._grouped_image2.show()
            self._grouped.set_tooltip(_('Click for ungrouped game'))
        else:
            self._grouped.set_icon_widget(self._grouped_image1)
            self._grouped_image1.show()
            self._grouped.set_tooltip(_('Click for grouped game'))
    
    def update_create_toolbar(self, widget, game_name, equal_pairs, grouped):        
        self.game_name_entry.set_text(game_name)
        self._equal_pairs.set_active(equal_pairs == 'True')
        self._grouped.set_active(grouped == '1')
        
    def update_buttons_status(self, widget, new, save):
        self._new_button.set_sensitive(new)
        self._save_button.set_sensitive(save)
    def __init__(self, handle):
        activity.Activity.__init__(self, handle, True)

        self.max_participants = 1

        # ****** Editor ******

        self.editor = Editor(self)
        self.editor.set_size_request(800, 790)
        scroll = gtk.ScrolledWindow()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scroll.add(self.editor)
        scroll.show_all()

        vbox = gtk.VBox()
        vbox.pack_start(scroll, True, True, 0)
        vbox.show_all()

        self.set_canvas(vbox)

        # ****** Toolbars ******

        self.toolbar_box = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        activity_toolbar = activity_button.page

        # Abrir objeto / Open object
        open_obj_btn = ToolButton("open-from-journal")
        open_obj_btn.connect("clicked", file_choosers.open_from_journal, None,
                             self)
        open_obj_btn.set_tooltip(_("Open object from journal"))
        activity_toolbar.insert(open_obj_btn, -1)

        # Separador / Separator
        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        activity_toolbar.insert(separator, -1)

        # ****** Open File button ******
        open_btn = ToolButton("fileopen")
        open_btn.set_tooltip(_("Open File"))
        open_btn.set_accelerator('<ctrl>o')
        open_btn.connect("clicked", self.open_file)
        activity_toolbar.insert(open_btn, -1)

        # ****** Save File button ******
        save_btn = ToolButton("stock_save")
        save_btn.set_tooltip(_("Save this file"))
        save_btn.set_accelerator('<ctrl>s')
        save_btn.connect("clicked", self.save_file)
        activity_toolbar.insert(save_btn, -1)

        activity_toolbar.show_all()
        activity_toolbar.stop.hide()

        # Guardar como / Save As
        save_as = gtk.MenuItem(_("Save on the file system."))
        activity_toolbar.keep.props.palette.menu.append(save_as)
        save_as.connect("activate", self.save_file_as)
        save_as.show()

        # Nuevo / New
        new = ToolButton("new")
        new.set_tooltip(_("New file"))
        new.set_accelerator('<ctrl>n')
        new.connect("clicked", self.new)
        activity_toolbar.insert(new, 6)
        new.show()

        activity_toolbar.keep.show()

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

        # Edicion / Edit Toolbar

        edit_toolbar = EditToolbar()
        edit_toolbar_button = ToolbarButton(label=_("Edit"),
                                            page=edit_toolbar,
                                            icon_name='toolbar-edit')

        edit_toolbar.cut = ToolButton("cut")
        edit_toolbar.cut.set_tooltip(_("Cut"))
        edit_toolbar.cut.set_accelerator('<ctrl>x')
        edit_toolbar.insert(edit_toolbar.cut, 4)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        edit_toolbar.insert(separator, -1)

        edit_toolbar.pep8_btn = ToolButton('pep8')
        edit_toolbar.pep8_btn.set_tooltip(_("PEP 8 Check"))
        edit_toolbar.pep8_btn.connect("clicked", self.pep8_check)
        edit_toolbar.insert(edit_toolbar.pep8_btn, -1)

        edit_toolbar.pep8_datetime_separator = gtk.SeparatorToolItem()
        edit_toolbar.pep8_datetime_separator.set_draw(True)
        edit_toolbar.insert(edit_toolbar.pep8_datetime_separator, -1)

        insert_datetime = ToolButton("insert-datetime")
        insert_datetime.connect("clicked", self.editor._insert_date_time)
        insert_datetime.set_tooltip(_("Insert date and time"))
        edit_toolbar.insert(insert_datetime, -1)
        insert_datetime.show_all()

        edit_toolbar.copy.connect("clicked", self.editor._copy_cb)
        edit_toolbar.paste.connect("clicked", self.editor._paste_cb)
        edit_toolbar.undo.connect("clicked", self.editor._undo_cb)
        edit_toolbar.redo.connect("clicked", self.editor._redo_cb)
        edit_toolbar.cut.connect("clicked", self.editor._cut_cb)

        edit_toolbar.show_all()
        edit_toolbar.pep8_btn.hide()
        edit_toolbar.pep8_datetime_separator.set_draw(False)

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

        self.edit_toolbar = edit_toolbar

        # Separador / Separator
        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        self.toolbar_box.toolbar.insert(separator, -1)

        # Buscar / Search
        search_entry = iconentry.IconEntry()
        search_entry.set_size_request(gtk.gdk.screen_width() / 3, -1)
        search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                        'system-search')
        search_entry.add_clear_button()
        search_entry.connect('activate', self.editor._search_entry_activate_cb)
        search_entry.connect('changed', self.editor._search_entry_changed_cb)
        search_item = gtk.ToolItem()
        search_item.add(search_entry)
        self.toolbox.toolbar.insert(search_item, -1)

        self._search_prev = ToolButton('go-previous-paired')
        self._search_prev.set_tooltip(_('Previous'))
        self._search_prev.connect('clicked', self.editor._search_prev_cb)
        self.toolbox.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.editor._search_next_cb)
        self.toolbox.toolbar.insert(self._search_next, -1)

        # Preferencias / preferences

        preferences_toolbar = gtk.Toolbar()

        show_line_numbers = ToggleToolButton('show-numbers')
        show_line_numbers.set_tooltip(_("Show line numbers"))

        show_line_numbers.set_active(True)
        show_line_numbers.connect("clicked", \
                             self.editor._set_show_line_numbers)
        show_line_numbers.show()
        preferences_toolbar.insert(show_line_numbers, -1)

        self.editor._make_languages_combo(preferences_toolbar)
        self.editor.make_style_combo(preferences_toolbar)

        preferences = ToolbarButton()
        preferences.props.page = preferences_toolbar
        preferences.props.icon_name = 'preferences-system'
        preferences.show_all()

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

        font_options = FontToolbarButton()
        font_options.connect("load-pango-context", self.load_pango_context)
        font_options.load_toolbar()
        font_options.connect("font-changed", self.change_font)
        self.toolbar_box.toolbar.insert(font_options, -1)
        font_options.show()

        # Separador / Separator

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        self.toolbar_box.toolbar.insert(separator, -1)

        # Boton salir / Stop Button

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

        self.toolbar_box.show_all()

        self.set_toolbar_box(self.toolbar_box)

        # Barra de estado de PEP8 / PEP8 status bar
        self.pep8_bar = gtk.Statusbar()
        self.pep8_bar.label = gtk.Label()
        self.pep8_bar.add(self.pep8_bar.label)
        vbox.pack_end(self.pep8_bar, False, True, 0)
Example #8
0
class GeoCacheToolbar(gtk.Toolbar):
    """
    Contains tools for geocaching.
    """

    show_cache = None

    def __init__(self, view, activity, model):
        gtk.Toolbar.__init__(self)
        self._logger = logging.getLogger('GeocachingToolbar')
        self._logger.setLevel(constants.LOG_LEVEL)

        self.view = view
        self.model = model
        self.activity = activity

#        #########################################################
#        # XXX create a geocache (hardcoded for usability testing)
#        # XXX put XO name with coordinate into "caches" file
#        self.cache = Point()
#        file_ = None
#        try:
#            file_ = open(os.path.join(constants.BUNDLE_PATH, 'caches'))
#            from sugar import profile
#            nick = profile.get_nick_name()
#            lines = file_.readlines()
#            for line in lines:
#                entries = line.split(',')
#                if nick == entries[0]:
#                    lon = float(entries[1])
#                    lat = float(entries[2])
#                    self.cache.coords = (lon,lat)
#        finally:
#            if file_ is not None:
#                file_.close()
#        self._logger.debug('cache: %s', self.cache.wkt)
#        #########################################################

        # individualize cache symbol and enable cache button
        img_name = os.path.join(GeoCache.ICONS_PATH, 'show-cache.svg')
        color_stroke = profile.get_color().get_stroke_color()
        color_fill = profile.get_color().get_fill_color()
        self._cache_overlay = utils.load_svg_image(img_name,
                                                   color_stroke,
                                                   color_fill,
                                                   size=(40,40))

        if not activity.get_shared() or (activity.get_shared() and activity.initiating):
            # only initiating activity creates "place-cache" button
            place_cache = ToolButton('place-cache')
            place_cache.set_tooltip(_('Place treasure.'))
            place_cache.connect('clicked', self._on_place_cache)
            place_cache.show()
            self.insert(place_cache, -1)

        self.show_cache = ToggleToolButton('show-cache')
        self.show_cache.set_tooltip(_('Show treasure.'))
        self.show_cache.set_active(INIT_SHOW_CACHE)
        self.show_cache.connect('clicked', self._on_show_cache)
        self.show_cache.show()
        self.insert(self.show_cache, -1)

        self.export_csv = ToolButton('csv-export')
        self.export_csv.set_tooltip(_('Export to CSV.'))
        self.export_csv.connect('clicked', self.model.export_to_csv)
        self.export_csv.show()
        self.insert(self.export_csv, -1)

        self.show()

    def _on_show_cache(self, button):
        if button.get_active():
            factory = lambda ob: geojson.GeoJSON.to_instance(ob)
            cache = self.activity.cloud.treasure.get_value()
            if cache is not None:
                position_dump = geojson.loads(cache, object_hook=factory)
                position = shape(position_dump)
                self._logger.debug("type of position: %s", type(position))
                self.view.drawable.draw_overlay(self._cache_overlay, position)
        else:
            self.view.drawable.remove_overlay(self._cache_overlay)

    def _on_place_cache(self, button):
        pos = geojson.dumps(self.activity.gps_position)
        if pos is not None:
            self.activity.cloud.treasure.set_value(pos)
            self._CACHE_PLACED = True
            self._logger.debug('cache placed')
            self.show_cache.set_active(True)
            self._on_show_cache(self.show_cache)
Example #9
0
class MoonActivity(activity.Activity):
    """Moon phase activity.
    """
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)
        self._name = handle
        self.set_title(_("Moon"))
        
        # Defaults (Resume priority, persistent file secondary, fall-back hardcoded)
        if handle.object_id == None:
            print "Launched from home."
        else:
            print "Journal resume."
        self.hemisphere_view = 'north'
        self.show_grid = False
        self.activity_state = {}
        self.activity_state['hemisphereView'] = self.hemisphere_view
        self.activity_state['showGrid'] = self.show_grid
        self.read_and_parse_prefs(os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults')
                
        # Toolbox
        try:
            # Use new >= 0.86 toolbar design
            self.max_participants = 1
            toolbar_box = ToolbarBox()
            activity_button = ActivityToolbarButton(self)
            toolbar_box.toolbar.insert(activity_button, 0)
            separator = gtk.SeparatorToolItem()
            toolbar_box.toolbar.insert(separator, -1)
            self.toggle_grid_button = ToggleToolButton('grid-icon')
            self.toggle_grid_button.set_tooltip(_("Toggle Grid View"))
            self.toggle_grid_button.set_active(self.show_grid)
            self.toggle_grid_handler_id = self.toggle_grid_button.connect('clicked', self.toggle_grid_clicked)
            toolbar_box.toolbar.insert(self.toggle_grid_button, -1)
            self.toggle_grid_button.show()
            self.toggle_hemisphere_button = ToggleToolButton('hemi-icon')
            self.toggle_hemisphere_button.set_tooltip(_("Toggle Hemisphere View"))
            self.toggle_hemisphere_button.set_active(self.hemisphere_view == 'south')
            self.toggle_hemisphere_handler_id = self.toggle_hemisphere_button.connect('clicked', self.toggle_hemisphere_clicked)
            toolbar_box.toolbar.insert(self.toggle_hemisphere_button, -1)
            self.toggle_hemisphere_button.show()

            self.image_button = ToolButton('save-image')
            self.image_button.set_tooltip(_("Save As Image"))
            self.image_button.connect('clicked', self.save_image)
            toolbar_box.toolbar.insert(self.image_button, -1)
            self.image_button.show()

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

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

        except NameError:
            # Use old <= 0.84 toolbar design
            toolbox = activity.ActivityToolbox(self)
            view_tool_bar = gtk.Toolbar()
            self.toggle_grid_button = ToggleToolButton('grid-icon')
            self.toggle_grid_button.set_tooltip(_("Toggle Grid View"))
            self.toggle_grid_button.set_active(self.show_grid)
            self.toggle_grid_handler_id = self.toggle_grid_button.connect('clicked', self.toggle_grid_clicked)
            view_tool_bar.insert(self.toggle_grid_button, -1)
            self.toggle_grid_button.show()
            self.toggle_hemisphere_button = ToggleToolButton('hemi-icon')
            self.toggle_hemisphere_button.set_tooltip(_("Toggle Hemisphere View"))
            self.toggle_hemisphere_button.set_active(self.hemisphere_view == 'south')
            self.toggle_hemisphere_handler_id = self.toggle_hemisphere_button.connect('clicked', self.toggle_hemisphere_clicked)
            view_tool_bar.insert(self.toggle_hemisphere_button, -1)
            self.toggle_hemisphere_button.show()

            self.image_button = ToolButton('save-image')
            self.image_button.set_tooltip(_("Save As Image"))
            self.image_button.connect('clicked', self.save_image)
            toolbar_box.toolbar.insert(self.image_button, -1)
            self.image_button.show()

            view_tool_bar.show()
            toolbox.add_toolbar(_('View'), view_tool_bar)
            self.set_toolbox(toolbox)
            toolbox.show()
            activity_toolbar = toolbox.get_activity_toolbar()
            activity_toolbar.share.props.visible = False

        # Items we don't have to do every redraw
        colormap = gtk.gdk.colormap_get_system()
        self.black_alloc_color = colormap.alloc_color('black')
        self.white_alloc_color = colormap.alloc_color('white')
        self.blue_green_mask_alloc_color = colormap.alloc_color('#F00')
        self.red_alloc_color = colormap.alloc_color('#F20')
        self.blue_alloc_color = colormap.alloc_color('#04F')
        self.moon_stamp = gtk.gdk.pixbuf_new_from_file("moon.jpg")
        self.image_size_cache = -1

        # Build main layout manually for the first pass
        self.build_main_layout_cb()

        # Watch for signal that the screen changed size (landscape vs. portrait)
        gtk.gdk.screen_get_default().connect('size-changed', self.build_main_layout_cb)

    def build_main_layout_cb(self, widget=None, data=None):
        """Create main layout respecting landscape or portrait orientation.
        """

        # Create event box to hold Moon image (so I can set background color)
        info_scroll = gtk.ScrolledWindow()
        self.event_box = gtk.EventBox()

        # Create the main activity layout
        if self.is_landscape_orientation():
            self.main_view = gtk.HBox()
            self.info_panel = gtk.VBox()
            self.event_box.set_size_request(int(gtk.gdk.screen_width() / 1.70), -1)
            self.main_view.pack_end(self.event_box, False)
            self.main_view.pack_start(info_scroll, True)
        else:
            self.main_view = gtk.VBox()
            self.info_panel = gtk.HBox()
            self.event_box.set_size_request(-1, int(gtk.gdk.screen_height() / 1.60))
            self.main_view.pack_start(self.event_box, False)
            self.main_view.pack_start(info_scroll, True)

        # Create the Moon image widget
        self.image = gtk.Image()
        self.event_box.add(self.image)
        self.event_box.modify_bg(gtk.STATE_NORMAL, self.black_alloc_color)
        self.event_box.connect('size-allocate', self._moon_size_allocate_cb)

        # Create scrolling Moon information panel
        info_scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
        info_scroll.set_size_request(-1, -1)

        self.info_panel.set_border_width(10)
        self.info = gtk.Label()
        self.info.set_justify(gtk.JUSTIFY_LEFT)
        self.info.set_alignment(0.0, 0.0)
        self.info_panel.pack_start(self.info, False)
        self.info2 = gtk.Label()
        self.info2.set_justify(gtk.JUSTIFY_LEFT)
        self.info2.set_alignment(0.0, 0.0)
        self.info_panel.pack_start(self.info2, True, True, 10)
        info_scroll.add_with_viewport(self.info_panel)

        # Create Moon data model
        self.data_model = DataModel()

        # Generate first view for text and kick off image update timer
        self.update_text_information_view()
        self.update_moon_image_view()

        # Display everything
        self.info.show()
        self.info_panel.show()
        self.image.show()
        self.event_box.show()
        self.main_view.show()
        self.set_canvas(self.main_view)
        self.show_all()

    def is_landscape_orientation(self):
        """Return True of in landscape, False for portrait orientation.
        """
        if gtk.gdk.screen_width() > gtk.gdk.screen_height():
            return True
        return False

    def read_and_parse_prefs(self, file_path):
        """Parse and set preference data from a given file.
        """
        try:
            read_file = open(file_path, 'r')
            self.activity_state = json.loads(read_file.read())
            if self.activity_state.has_key('hemisphereView'):
                self.hemisphere_view = self.activity_state['hemisphereView']
            if self.activity_state.has_key('showGrid'):
                self.show_grid = self.activity_state['showGrid']
            read_file.close()
        except:
            pass

    def read_file(self, file_path):
        """Read state from datastore.
        """
        self.read_and_parse_prefs(file_path)
        
    def write_file(self, file_path):
        """Write state to journal datastore and to persistent file system.
        """
        self.activity_state['hemisphereView'] = self.hemisphere_view
        self.activity_state['showGrid'] = self.show_grid
        serialised_data = json.dumps(self.activity_state)
        
        to_journal = file(file_path, 'w')
        try:
            to_journal.write(serialised_data)
        finally:
            to_journal.close()
            
        to_persistent_fs = file(os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults', 'w')
        try:
            to_persistent_fs.write(serialised_data)
        finally:
            to_persistent_fs.close()
    
    def toggle_grid_clicked(self, widget):
        """Respond to toolbar button to hide/show grid lines.
        """
        if self.show_grid == True:
            self.show_grid = False
        else:
            self.show_grid = True
        gobject.source_remove(self.update_moon_image_timeout)
        self.update_moon_image_view()

    def toggle_hemisphere_clicked(self, widget):
        """Respond to toolbar button to change viewing hemisphere.
        """
        if self.hemisphere_view == 'north':
            self.hemisphere_view = 'south'
        else:
            self.hemisphere_view = 'north'
        gobject.source_remove(self.update_moon_image_timeout)
        self.update_moon_image_view()

    def update_text_information_view(self):
        """Generate Moon data and update text based information view.
        """
        self.data_model.update_moon_calculations(time.time())
        information_string = _("Today's Moon Information\n\n")[:-2]
        information_string += ":\n%s\n\n" % (time.strftime(LOCALE_DATE_FORMAT))
        information_string += (_("Phase:\n%s\n\n") % (self.data_model.moon_phase_name(self.data_model.phase_of_moon))).replace("\n", " ", 1)
        information_string += _("Julian Date:\n%.2f (astronomical)\n\n") % (self.data_model.julian_date)
        information_string += (_("Age:\n%(days).0f days, %(hours).0f hours, %(minutes).0f minutes\n\n") % {'days':self.data_model.days_old, 'hours':self.data_model.hours_old, 'minutes':self.data_model.minutes_old}).replace("\n", " ", 1)
        information_string += _("Lunation:\n%(phase).2f%% through lunation %(lunation)d\n\n") % {'phase':self.data_model.phase_of_moon * 100, 'lunation':self.data_model.lunation}
        information_string += (_("Surface Visibility:\n%.0f%% (estimated)\n\n")[:-2] % (self.data_model.percent_of_full_moon * 100)).replace("\n", " ", 1)
        self.info.set_markup(information_string)

        information_string = _(u"Selenographic Terminator Longitude:\n%(deg).1f\u00b0%(westOrEast)s (%(riseOrSet)s)\n\n") % {'deg':self.data_model.selenographic_deg, 'westOrEast':self.data_model.west_or_east, 'riseOrSet':self.data_model.rise_or_set}
        information_string += _("Next Full Moon:\n%(date)s in %(days).0f days\n\n") % {'date':time.strftime(LOCALE_DATE_FORMAT, time.localtime(self.data_model.next_full_moon_date)), 'days':self.data_model.days_until_full_moon}
        information_string += _("Next New Moon:\n%(date)s in %(days).0f days\n\n") % {'date':time.strftime(LOCALE_DATE_FORMAT, time.localtime(self.data_model.next_new_moon_date)), 'days':self.data_model.days_until_new_moon}
        information_string += _("Next Lunar eclipse:\n%(date)s in %(days).0f days\n\n") % {'date':time.strftime(LOCALE_DATE_FORMAT, time.localtime(self.data_model.next_lunar_eclipse_date)), 'days':self.data_model.days_until_lunar_eclipse}
        information_string += _("Next Solar eclipse:\n%(date)s in %(days).0f days\n\n")[:-2] % {'date':time.strftime(LOCALE_DATE_FORMAT, time.localtime(self.data_model.next_solar_eclipse_date)), 'days':self.data_model.days_until_solar_eclipse}
        self.info2.set_markup(information_string)

        # Calculate time to next minute cusp and set a new timer
        ms_to_next_min_cusp = (60 - time.gmtime()[5]) * 1000
        gobject.timeout_add(ms_to_next_min_cusp, self.update_text_information_view)

        # Stop this timer running
        return False

    def update_moon_image_view(self):
        """Update Moon image view using last cached Moon data.
        """
        self.image_pixmap = gtk.gdk.Pixmap(self.window, IMAGE_SIZE, IMAGE_SIZE)
        self.gc = self.image_pixmap.new_gc(foreground=self.black_alloc_color)
        self.image.set_from_pixmap(self.image_pixmap, None)

        # Erase last Moon rendering
        self.image_pixmap.draw_rectangle(self.gc, True, 0, 0, IMAGE_SIZE, IMAGE_SIZE)
                
        # Create a 1bit shadow mask
        mask_pixmap = gtk.gdk.Pixmap(None, IMAGE_SIZE, IMAGE_SIZE, depth=1)
        kgc = mask_pixmap.new_gc(foreground=self.black_alloc_color)
        wgc = mask_pixmap.new_gc(foreground=self.white_alloc_color)
        mask_pixmap.draw_rectangle(kgc, True, 0, 0, IMAGE_SIZE, IMAGE_SIZE)
        if self.data_model.phase_of_moon <= .25:
            # New Moon to First Quarter
            phase_shadow_adjust = self.data_model.phase_of_moon - abs(math.sin(self.data_model.phase_of_moon * math.pi * 4) / 18.0)
            arc_scale = int(IMAGE_SIZE * (1 - (phase_shadow_adjust * 4)))
            mask_pixmap.draw_rectangle(wgc, True, HALF_SIZE + 1, 0, HALF_SIZE, IMAGE_SIZE - 1)
            mask_pixmap.draw_arc(kgc, True, HALF_SIZE - int(arc_scale / 2), 0, arc_scale, IMAGE_SIZE, 17280, 11520)
        elif self.data_model.phase_of_moon <= .5:
            # First Quarter to Full Moon
            phase_shadow_adjust = self.data_model.phase_of_moon + abs(math.sin(self.data_model.phase_of_moon * math.pi * 4) / 18.0)
            arc_scale = int(IMAGE_SIZE * ((phase_shadow_adjust - .25) * 4))
            mask_pixmap.draw_rectangle(wgc, True, HALF_SIZE, 0, HALF_SIZE, IMAGE_SIZE)
            mask_pixmap.draw_arc(wgc, True, HALF_SIZE - int(arc_scale / 2), 0, arc_scale, IMAGE_SIZE, 5760, 11520)
        elif self.data_model.phase_of_moon <= .75:
            # Full Moon to Last Quarter
            phase_shadow_adjust = self.data_model.phase_of_moon - abs(math.sin(self.data_model.phase_of_moon * math.pi * 4) / 18.0)
            arc_scale = int(IMAGE_SIZE * (1 - ((phase_shadow_adjust - .5) * 4)))
            mask_pixmap.draw_rectangle(wgc, True, 0, 0, HALF_SIZE + 1, IMAGE_SIZE)
            mask_pixmap.draw_arc(wgc, True, HALF_SIZE - int(arc_scale / 2), 0, arc_scale, IMAGE_SIZE, 17280, 11520)
        else:
            # Last Quarter to New Moon
            phase_shadow_adjust = self.data_model.phase_of_moon + abs(math.sin(self.data_model.phase_of_moon * math.pi * 4) / 18.0)
            arc_scale = int(IMAGE_SIZE * ((phase_shadow_adjust - .75) * 4))
            mask_pixmap.draw_rectangle(wgc, True, 0, 0, HALF_SIZE, IMAGE_SIZE)
            mask_pixmap.draw_arc(kgc, True, HALF_SIZE - int(arc_scale / 2), 0, arc_scale, IMAGE_SIZE, 5760, 11520)
        maskgc = self.image_pixmap.new_gc(clip_mask=mask_pixmap)
        
        # Modified image based on public domain photo by John MacCooey
        moon_pixbuf = self.moon_stamp.scale_simple(IMAGE_SIZE, IMAGE_SIZE,
                gtk.gdk.INTERP_BILINEAR)

        # Composite bright Moon image and semi-transparant Moon for shadow detail
        dark_pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, IMAGE_SIZE, IMAGE_SIZE)
        dark_pixbuf.fill(0x00000000)
        if (self.data_model.next_lunar_eclipse_sec == -1 and self.data_model.last_lunar_eclipse_sec > 7200) or (self.data_model.next_lunar_eclipse_sec > 7200 and self.data_model.last_lunar_eclipse_sec == -1) or min(self.data_model.next_lunar_eclipse_sec, self.data_model.last_lunar_eclipse_sec) > 7200:
            # Normal Moon phase render
            moon_pixbuf.composite(dark_pixbuf, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, 127)
            self.image_pixmap.draw_pixbuf(self.gc, dark_pixbuf, 0, 0, 0, 0)
            self.image_pixmap.draw_pixbuf(maskgc, moon_pixbuf, 0, 0, 0, 0)

        else:
            # Reddening eclipse effect, 2hrs (7200sec) before and after (by masking out green & blue)
            if self.data_model.next_lunar_eclipse_sec == -1:
                eclipse_alpha = self.data_model.last_lunar_eclipse_sec / 7200.0 * 256
            elif self.data_model.last_lunar_eclipse_sec == -1:
                eclipse_alpha = self.data_model.next_lunar_eclipse_sec / 7200.0 * 256
            else:
                eclipse_alpha = min(self.data_model.next_lunar_eclipse_sec, self.data_model.last_lunar_eclipse_sec) / 7200.0 * 256
            moon_pixbuf.composite(dark_pixbuf, 0, 0, IMAGE_SIZE, IMAGE_SIZE,
                                  0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR,
                                  int(196 - eclipse_alpha / 2))
            self.image_pixmap.draw_pixbuf(self.gc, dark_pixbuf, 0, 0, 0, 0)
            del dark_pixbuf
            dark_pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, IMAGE_SIZE, IMAGE_SIZE)
            moon_pixbuf.composite(dark_pixbuf, 0, 0, IMAGE_SIZE, IMAGE_SIZE,
                                  0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR,
                                  int(eclipse_alpha))
            rgc = self.image_pixmap.new_gc(foreground=self.blue_green_mask_alloc_color, function=gtk.gdk.AND)
            self.image_pixmap.draw_rectangle(rgc, True, 0, 0, IMAGE_SIZE, IMAGE_SIZE)
            self.image_pixmap.draw_pixbuf(self.gc, dark_pixbuf, 0, 0, 0, 0)

        if self.hemisphere_view == 'south':
            # Rotate final image for a view from north or south hemisphere
            rot_pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, IMAGE_SIZE, IMAGE_SIZE)
            rot_pixbuf.get_from_drawable(self.image_pixmap, self.image_pixmap.get_colormap(), 0, 0, 0, 0, -1, -1)
            rot_pixbuf = rot_pixbuf.rotate_simple(gtk.gdk.PIXBUF_ROTATE_UPSIDEDOWN)
            self.image_pixmap.draw_pixbuf(self.gc, rot_pixbuf, 0, 0, 0, 0)
            if self.show_grid:
                # Draw grid rotated for south hemi
                self.draw_grid(_("SNWE"))
        elif self.show_grid:
            # Draw grid for north hemi
            self.draw_grid(_("NSEW"))

        self.image.queue_draw()

        # Update the Moon image in another 5min
        self.update_moon_image_timeout = gobject.timeout_add(300000, self.update_moon_image_view)
        
        # Stop this timer running
        return False

    def draw_grid(self, compass_text):
        """Draw Selenographic grid line data.
        """
        rgc = self.image_pixmap.new_gc(foreground=self.red_alloc_color)
        bgc = self.image_pixmap.new_gc(foreground=self.blue_alloc_color)
        wgc = self.image_pixmap.new_gc(foreground=self.white_alloc_color)
        pango_layout = self.image.create_pango_layout("")
        pango_layout.set_text("0°")
        self.image_pixmap.draw_rectangle(bgc, True, HALF_SIZE + 2, HALF_SIZE, 24, 22)            
        self.image_pixmap.draw_layout(wgc, HALF_SIZE + 2, HALF_SIZE, pango_layout)            
        pango_layout.set_text("30°")
        self.image_pixmap.draw_rectangle(bgc, True, HALF_SIZE + 2, int(HALF_SIZE * 0.5), 36, 22)            
        self.image_pixmap.draw_rectangle(bgc, True, HALF_SIZE + 2, int(HALF_SIZE * 1.5), 36, 22)            
        self.image_pixmap.draw_layout(wgc, HALF_SIZE + 2, int(HALF_SIZE * 0.5), pango_layout)            
        self.image_pixmap.draw_layout(wgc, HALF_SIZE + 2, int(HALF_SIZE * 1.5), pango_layout)            
        pango_layout.set_text("60°")
        self.image_pixmap.draw_rectangle(bgc, True, HALF_SIZE + 2, int(HALF_SIZE * 0.15), 36, 22)            
        self.image_pixmap.draw_rectangle(bgc, True, HALF_SIZE + 2, int(HALF_SIZE * 1.85), 36, 22)            
        self.image_pixmap.draw_layout(wgc, HALF_SIZE + 2, int(HALF_SIZE * 0.15), pango_layout)            
        self.image_pixmap.draw_layout(wgc, HALF_SIZE + 2, int(HALF_SIZE * 1.85), pango_layout)            
        pango_layout.set_text("30°")
        self.image_pixmap.draw_rectangle(rgc, True, int(HALF_SIZE * 0.48) + 2, HALF_SIZE, 36, 22)            
        self.image_pixmap.draw_rectangle(rgc, True, int(HALF_SIZE * 1.52) + 2, HALF_SIZE, 36, 22)            
        self.image_pixmap.draw_layout(wgc, int(HALF_SIZE * 0.48) + 2, HALF_SIZE, pango_layout)            
        self.image_pixmap.draw_layout(wgc, int(HALF_SIZE * 1.52) + 2, HALF_SIZE, pango_layout)            
        pango_layout.set_text("60°")
        self.image_pixmap.draw_rectangle(rgc, True, int(HALF_SIZE * 0.15) + 2, HALF_SIZE, 36, 22)            
        self.image_pixmap.draw_rectangle(rgc, True, int(HALF_SIZE * 1.85) + 2, HALF_SIZE, 36, 22)            
        self.image_pixmap.draw_layout(wgc, int(HALF_SIZE * 0.15) + 2, HALF_SIZE, pango_layout)            
        self.image_pixmap.draw_layout(wgc, int(HALF_SIZE * 1.85) + 2, HALF_SIZE, pango_layout)            
        for i in (-1, 0, 1):
            self.image_pixmap.draw_line(rgc, HALF_SIZE + i, 0, HALF_SIZE + i, IMAGE_SIZE)
            self.image_pixmap.draw_arc(rgc, False, int(HALF_SIZE * 0.15) + i, 0, IMAGE_SIZE - int(IMAGE_SIZE * 0.15), IMAGE_SIZE, 0, 360*64)
            self.image_pixmap.draw_arc(rgc, False, int(HALF_SIZE * 0.48) + i, 0, IMAGE_SIZE - int(IMAGE_SIZE * 0.48) , IMAGE_SIZE, 0, 360*64)
        for i in (-1, 0, 1):
            self.image_pixmap.draw_line(bgc, 0, HALF_SIZE + i, IMAGE_SIZE, HALF_SIZE + i)
            self.image_pixmap.draw_line(bgc, int(HALF_SIZE * 0.15), int(HALF_SIZE * 0.5) + i, IMAGE_SIZE - int(HALF_SIZE * 0.15), int(HALF_SIZE * 0.5) + i)
            self.image_pixmap.draw_line(bgc, int(HALF_SIZE * 0.15), int(HALF_SIZE * 1.5) + i, IMAGE_SIZE - int(HALF_SIZE * 0.15), int(HALF_SIZE * 1.5) + i)
            self.image_pixmap.draw_line(bgc, int(HALF_SIZE * 0.5), int(HALF_SIZE * 0.15) + i, IMAGE_SIZE - int(HALF_SIZE * 0.5), int(HALF_SIZE * 0.15) + i)
            self.image_pixmap.draw_line(bgc, int(HALF_SIZE * 0.5), int(HALF_SIZE * 1.85) + i, IMAGE_SIZE - int(HALF_SIZE * 0.5), int(HALF_SIZE * 1.85) + i)

        # Key text
        pango_layout.set_text(_("Latitude"))
        self.image_pixmap.draw_layout(bgc, 15, IMAGE_SIZE - 48 - 15, pango_layout)
        pango_layout.set_text(_("Longitude"))
        self.image_pixmap.draw_layout(rgc, 15, IMAGE_SIZE - 24 - 15, pango_layout)

        # Compass
        # TODO: fix string index to support multi-byte texts
        for i in (-1, 0, 1):
            self.image_pixmap.draw_line(rgc, 22 + 15, 48 + 15 + i, 68 + 15, 48 + 15 + i)
        for i in (-1, 0, 1):
            self.image_pixmap.draw_line(bgc, 45 + 15 + i, 24 + 15, 45 + 15 + i, 68 + 15)
        pango_layout.set_text(compass_text[0])
        self.image_pixmap.draw_layout(bgc, 38 + 15, 15, pango_layout)
        pango_layout.set_text(compass_text[1])
        self.image_pixmap.draw_layout(bgc, 38 + 15, 72 + 15, pango_layout)
        pango_layout.set_text(compass_text[2])
        self.image_pixmap.draw_layout(rgc, 72 + 15, 36 + 15, pango_layout)
        pango_layout.set_text(compass_text[3])
        self.image_pixmap.draw_layout(rgc, 15, 36 + 15, pango_layout)

    def _moon_size_allocate_cb(self, widget, allocation):
        global IMAGE_SIZE, HALF_SIZE
        size = min(allocation.width, allocation.height) - 30

        if size != IMAGE_SIZE and size != self.image_size_cache:
            self.image_size_cache = size
            IMAGE_SIZE = size
            HALF_SIZE = IMAGE_SIZE / 2
            self.update_moon_image_view()

    def save_image(self, widget):
        """
        Save the curren phase to image and show alert
        """

        w, h = self.get_size()
        pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
                    int(w / 1.70), h - 55)

        shot = pixbuf.get_from_drawable(self.window, self.get_colormap(),
                    w - int(w / 1.70), 55, 0, 0, int(w / 1.70), h - 55)

        path = os.path.join(activity.get_activity_root(), "instance",
            "shot.png")

        shot.save(path, "png")
        journal_entry = datastore.create()
        journal_entry.metadata['title'] = "%s %s" % \
            (self.metadata['title'], _("Image"))
        journal_entry.metadata['icon-color'] = profile.get_color().to_string()
        journal_entry.metadata['mime_type'] = "image/png"
        journal_entry.set_file_path(path)
        datastore.write(journal_entry)
        journal_entry.destroy()

        # Alert
        HAS_ALERT = False
        try:
            from sugar.graphics.alert import NotifyAlert
            HAS_ALERT = True
        except:
            pass

        if HAS_ALERT:
            alert = NotifyAlert(5)
            alert.props.title =_('Image saved')
            alert.props.msg = _('An image of the current phase of the moon has been saved to the Journal')
            alert.connect('response', lambda x, y: self.remove_alert(x))
            self.add_alert(alert)
Example #10
0
class LybnizActivity(activity.Activity):
    def write_file(self, file_path):
        x, y, w, h = self.graph.drawing_area.get_allocation()
        pix_buffer = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h)
        pix_buffer.get_from_drawable(self.graph.pix_map, self.graph.pix_map.get_colormap(), 0, 0, 0, 0, w, h)
        pix_buffer.save(file_path, "png")
    
    def parameter_entries_repopulate(self):
        # set text in entries for parameters
        self.y1_entry.set_text(y1)
        self.y2_entry.set_text(y2)
        self.y3_entry.set_text(y3)
        self.x_min_entry.set_text(str(self.graph.x_min))
        self.x_max_entry.set_text(str(self.graph.x_max))
        self.x_scale_entry.set_text(str(self.graph.x_scale))
        self.y_min_entry.set_text(str(self.graph.y_min))
        self.y_max_entry.set_text(str(self.graph.y_max))
        self.y_scale_entry.set_text(str(self.graph.y_scale))

    def zoom_in(self, widget, event=None):
        "Narrow the plotted section by half"
        center_x = (self.graph.x_min + self.graph.x_max) / 2
        center_y = (self.graph.y_min + self.graph.y_max) / 2
        range_x = (self.graph.x_max - self.graph.x_min)
        range_y = (self.graph.y_max - self.graph.y_min)

        self.graph.x_min = center_x - (range_x / 4)
        self.graph.x_max = center_x + (range_x / 4)
        self.graph.y_min = center_y - (range_y / 4)
        self.graph.y_max = center_y +(range_y / 4)

        self.parameter_entries_repopulate()
        self.graph.plot()

    def zoom_out(self, widget, event=None):
        "Double the plotted section"
        center_x = (self.graph.x_min + self.graph.x_max) / 2
        center_y = (self.graph.y_min + self.graph.y_max) / 2
        range_x = (self.graph.x_max - self.graph.x_min)
        range_y = (self.graph.y_max - self.graph.y_min)

        self.graph.x_min = center_x - (range_x)
        self.graph.x_max = center_x + (range_x)
        self.graph.y_min = center_y - (range_y)
        self.graph.y_max = center_y +(range_y)	

        self.parameter_entries_repopulate()
        self.graph.plot()

    def zoom_reset(self, widget, event=None):
        "Set the range back to the user's input"

        self.graph.x_min = eval(x_min,{"__builtins__":{}},safe_dict)
        self.graph.y_min = eval(y_min,{"__builtins__":{}},safe_dict)
        self.graph.x_max = eval(x_max,{"__builtins__":{}},safe_dict)
        self.graph.y_max = eval(y_max,{"__builtins__":{}},safe_dict)
        self.x_min_entry.set_text(self.x_min)
        self.x_max_entry.set_text(self.x_max)
        self.x_scale_entry.set_text(self.x_scale)
        self.y_min_entry.set_text(self.y_min)
        self.y_max_entry.set_text(self.y_max)
        self.y_scale_entry.set_text(self.y_scale)
        self.graph.plot()

    def evaluate(self, widget, event=None):
        "Evaluate a given x for the three functions"

        def entry_changed(widget):
            for e in ((y1, dlg_win.y1_entry), (y2, dlg_win.y2_entry), (y3, dlg_win.y3_entry)):
                try:
                    x = float(dlg_win.x_entry.get_text())
                    safe_dict['x']=x
                    e[1].set_text(str(eval(e[0].replace("^","**"),{"__builtins__":{}},safe_dict)))
                except:
                    if len(e[0]) > 0:
                        e[1].set_text("Error: %s" % sys.exc_value)
                    else:
                        e[1].set_text("")

        def close(self):
            dlg_win.destroy()

        dlg_win = gtk.Window(gtk.WINDOW_TOPLEVEL)
        dlg_win.set_position(gtk.WIN_POS_CENTER)
        dlg_win.set_title(_("Evaluate"))
        dlg_win.connect("destroy", close)

        dlg_win.x_entry = gtk.Entry()
        dlg_win.x_entry.set_editable(True)
        dlg_win.x_entry.connect("changed", entry_changed)
        dlg_win.y1_entry = gtk.Entry()
        dlg_win.y1_entry.set_size_request(200, 24)
        dlg_win.y1_entry.set_sensitive(False)
        dlg_win.y2_entry = gtk.Entry()
        dlg_win.y2_entry.set_size_request(200, 24)
        dlg_win.y2_entry.set_sensitive(False)
        dlg_win.y3_entry = gtk.Entry()
        dlg_win.y3_entry.set_size_request(200, 24)
        dlg_win.y3_entry.set_sensitive(False)

        table = gtk.Table(2, 5)
        label = gtk.Label("x = ")
        label.set_alignment(0, .5)
        table.attach(label, 0, 1, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        table.attach(dlg_win.x_entry, 1, 2, 0, 1)
        label = gtk.Label("y1 = ")
        label.set_alignment(0, .5)
        label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("blue"))
        table.attach(label, 0, 1, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        table.attach(dlg_win.y1_entry, 1, 2, 1, 2)
        label = gtk.Label("y2 = ")
        label.set_alignment(0, .5)
        label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red"))
        table.attach(label, 0, 1, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        table.attach(dlg_win.y2_entry, 1, 2, 2, 3)
        label = gtk.Label("y3 = ")
        label.set_alignment(0, .5)
        label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("DarkGreen"))
        table.attach(label, 0, 1, 3, 4, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        table.attach(dlg_win.y3_entry, 1, 2, 3, 4)
        table.set_border_width(24)
        dlg_win.add(table)
        dlg_win.show_all()
    
    def plot(self, widget, event=None):
        global x_max, x_min, x_scale, y_max, y_min, y_scale, y1, y2, y3
        x_max = self.x_max_entry.get_text()
        x_min = self.x_min_entry.get_text()
        x_scale = self.x_scale_entry.get_text()

        y_max = self.y_max_entry.get_text()
        y_min = self.y_min_entry.get_text()
        y_scale = self.y_scale_entry.get_text()

        self.graph.x_max = eval(x_max,{"__builtins__":{}},safe_dict)
        self.graph.x_min = eval(x_min,{"__builtins__":{}},safe_dict)
        self.graph.x_scale = eval(x_scale,{"__builtins__":{}},safe_dict)

        self.graph.y_max = eval(y_max,{"__builtins__":{}},safe_dict)
        self.graph.y_min = eval(y_min,{"__builtins__":{}},safe_dict)
        self.graph.y_scale = eval(y_scale,{"__builtins__":{}},safe_dict)

        y1 = self.y1_entry.get_text()
        y2 = self.y2_entry.get_text()
        y3 = self.y3_entry.get_text()

        self.graph.plot()

    def toggle_connect(self, widget, event=None):
        "Toggle between a graph that connects points with lines and one that does not"
        global connect_points
        connect_points = not connect_points
        self.graph.plot()
    
    def scale_dec(self, widget, event=None):
        self.graph.scale_style = "dec"
        self.scale_box.hide()
        self.plot(None)


    def scale_rad(self, widget, event=None):
        self.graph.scale_style = "rad"
        self.scale_box.hide()
        self.plot(None)

    def scale_cust(self, widget, event=None):
        self.graph.scale_style = "cust"
        self.scale_box.show()
        self.plot(None)

    def __init__(self, handle):
        activity.Activity.__init__(self, handle)
        self.y1 = y1
        self.y2 = y2
        self.y3 = y3
        self.x_max = x_max
        self.x_min = x_min
        self.x_scale = x_scale
        self.y_max = y_max
        self.y_min = y_min
        self.y_scale = y_scale
        if have_toolbox:
            self.toolbar_box = ToolbarBox()
            self.activity_button = ActivityToolbarButton(self)
            self.activity_button.page.share.hide()
            self.toolbar_box.toolbar.insert(self.activity_button, 0)
            self.activity_button.show()
            self.graph_item = ToolbarButton()
            self.graph_item.props.icon_name = 'graph'
        else:
            self.toolbox = activity.ActivityToolbox(self)
            activity_toolbar = self.toolbox.get_activity_toolbar()
            activity_toolbar.share.props.visible = False
        self.graph_toolbar = gtk.Toolbar()
        if have_toolbox:
            self.graph_item.props.page = self.graph_toolbar
        else:
            self.toolbox.add_toolbar(_('Graph'), self.graph_toolbar)
        self.plot_item = ToolButton('gtk-refresh')
        self.plot_item.props.tooltip = _("Plot")
        self.plot_item.connect("clicked", self.plot)
        self.plot_item.show()
        self.graph_toolbar.insert(self.plot_item, 0)
        self.evaluate_item = ToolButton('evaluate')
        self.evaluate_item.props.tooltip = _('Evaluate')
        self.evaluate_item.connect("clicked", self.evaluate)
        self.evaluate_item.show()
        self.graph_toolbar.insert(self.evaluate_item, -1)
        separator = gtk.SeparatorToolItem()
        separator.show()
        self.graph_toolbar.insert(separator, -1)
        self.zoom_in_item = ToolButton('zoom-in')
        self.zoom_in_item.props.tooltip = _('Zoom In')
        self.zoom_in_item.connect("clicked", self.zoom_in)
        self.zoom_in_item.show()
        self.graph_toolbar.insert(self.zoom_in_item, -1)
        self.zoom_out_item = ToolButton('zoom-out')
        self.zoom_out_item.props.tooltip = _('Zoom Out')
        self.zoom_out_item.connect("clicked", self.zoom_out)
        self.zoom_out_item.show()
        self.graph_toolbar.insert(self.zoom_out_item, -1)
        self.zoom_reset_item = ToolButton('zoom-original')
        self.zoom_reset_item.props.tooltip = _('Zoom Reset')
        self.zoom_reset_item.connect("clicked", self.zoom_reset)
        self.zoom_reset_item.show()
        self.graph_toolbar.insert(self.zoom_reset_item, -1)
        separator = gtk.SeparatorToolItem()
        separator.show()
        self.graph_toolbar.insert(separator, -1)
        self.connect_points_item = ToggleToolButton('connect-points')
        self.connect_points_item.set_tooltip(_("Connect Points"))
        self.connect_points_item.set_active(True)
        self.connect_points_item.connect("toggled", self.toggle_connect)
        self.connect_points_item.show()
        self.graph_toolbar.insert(self.connect_points_item, -1)
        separator = gtk.SeparatorToolItem()
        separator.show()
        self.graph_toolbar.insert(separator, -1)
        self.decimal_item = RadioToolButton()
        self.decimal_item.set_named_icon('decimal')
        self.decimal_item.set_tooltip(_("Decimal Scale Style"))
        self.decimal_item.connect("toggled", self.scale_dec)
        self.decimal_item.show()
        self.graph_toolbar.insert(self.decimal_item, -1)
        self.radians_item = RadioToolButton()
        self.radians_item.set_named_icon('radian')
        self.radians_item.set_tooltip(_("Radians Scale Style"))
        self.radians_item.set_group(self.decimal_item)
        self.radians_item.connect("toggled", self.scale_rad)
        self.radians_item.show()
        self.graph_toolbar.insert(self.radians_item, -1)
        self.custom_item = RadioToolButton()
        self.custom_item.set_named_icon('custom')
        self.custom_item.set_tooltip(_("Custom Scale Style"))
        self.custom_item.set_group(self.radians_item)
        self.custom_item.connect("toggled", self.scale_cust)
        self.custom_item.show()
        self.graph_toolbar.insert(self.custom_item, -1)
        self.graph_toolbar.show()
        if have_toolbox:
            self.graph_item.show()
            self.toolbar_box.toolbar.insert(self.graph_item, -1)
            separator = gtk.SeparatorToolItem()
            separator.set_draw(False)
            separator.set_expand(True)
            separator.show()
            self.toolbar_box.toolbar.insert(separator, -1)
            self.stop = StopButton(self)
            self.stop.show()
            self.toolbar_box.toolbar.insert(self.stop, -1)
            self.set_toolbar_box(self.toolbar_box)
            self.toolbar_box.show()
        else:
            self.toolbox.show()
            self.set_toolbox(self.toolbox)
        self.v_box = gtk.VBox()
        self.set_canvas(self.v_box)
        self.parameter_entries = gtk.Table(6, 3)
        self.y1_entry = gtk.Entry()
        self.y2_entry = gtk.Entry()
        self.y3_entry = gtk.Entry()
        self.x_min_entry = gtk.Entry()
        self.x_min_entry.set_size_request(90, 24)
        self.x_min_entry.set_alignment(1)
        self.x_max_entry = gtk.Entry()
        self.x_max_entry.set_size_request(90, 24)
        self.x_max_entry.set_alignment(1)
        self.x_scale_entry = gtk.Entry()
        self.x_scale_entry.set_size_request(90, 24)
        self.x_scale_entry.set_alignment(1)
        self.y_min_entry = gtk.Entry()
        self.y_min_entry.set_size_request(90, 24)
        self.y_min_entry.set_alignment(1)
        self.y_max_entry = gtk.Entry()
        self.y_max_entry.set_size_request(90, 24)
        self.y_max_entry.set_alignment(1)
        self.y_scale_entry = gtk.Entry()
        self.y_scale_entry.set_size_request(90, 24)
        self.y_scale_entry.set_alignment(1)
        self.y1_entry.set_text(self.y1)
        self.y2_entry.set_text(self.y2)
        self.y3_entry.set_text(self.y3)
        self.x_min_entry.set_text(self.x_min)
        self.x_max_entry.set_text(self.x_max)
        self.x_scale_entry.set_text(self.x_scale)
        self.y_min_entry.set_text(self.y_min)
        self.y_max_entry.set_text(self.y_max)
        self.y_scale_entry.set_text(self.y_scale)
        self.scale_box = gtk.HBox()
        label = gtk.Label("y1 = ")
        label.set_alignment(0, .5)
        label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("blue"))
        self.parameter_entries.attach(label, 0, 1, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        self.parameter_entries.attach(self.y1_entry, 1, 2, 0, 1)
        label = gtk.Label(_("X min"))
        label.set_alignment(1, .5)
        self.parameter_entries.attach(label, 2, 3, 0, 1, xpadding=5, ypadding=7, xoptions=gtk.FILL)
        self.parameter_entries.attach(self.x_min_entry, 3, 4, 0, 1, xoptions=gtk.FILL)
        label = gtk.Label(_("Y min"))
        label.set_alignment(1, .5)
        self.parameter_entries.attach(label, 4, 5, 0, 1, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        self.parameter_entries.attach(self.y_min_entry, 5, 6, 0, 1, xpadding=5, xoptions=gtk.FILL)
        label = gtk.Label("y2 = ")
        label.set_alignment(0, .5)
        label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red"))
        self.parameter_entries.attach(label, 0, 1, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        self.parameter_entries.attach(self.y2_entry, 1, 2, 1, 2)
        label = gtk.Label(_("X max"))
        label.set_alignment(1, .5)
        self.parameter_entries.attach(label, 2, 3, 1, 2, xpadding=5, ypadding=7, xoptions=gtk.FILL)
        self.parameter_entries.attach(self.x_max_entry, 3, 4, 1, 2, xoptions=gtk.FILL)
        label = gtk.Label(_("Y max"))
        label.set_alignment(1, .5)
        self.parameter_entries.attach(label, 4, 5, 1, 2, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        self.parameter_entries.attach(self.y_max_entry, 5, 6, 1, 2, xpadding=5, xoptions=gtk.FILL)
        label = gtk.Label("y3 = ")
        label.set_alignment(0, .5)
        label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("DarkGreen"))
        self.parameter_entries.attach(label, 0, 1, 2, 3, xpadding=5, ypadding=5, xoptions=gtk.FILL)
        self.parameter_entries.attach(self.y3_entry, 1, 2, 2, 3)
        label = gtk.Label(_("X scale"))
        label.set_alignment(0, .5)
        self.scale_box.add(label)
        self.scale_box.add(self.x_scale_entry)
        label = gtk.Label(_("Y scale"))
        label.set_alignment(0, .5)
        self.scale_box.add(label)
        self.scale_box.add(self.y_scale_entry)
        self.parameter_entries.attach(self.scale_box, 2, 6, 2, 3, xpadding=5, xoptions=gtk.FILL)
        self.v_box.pack_start(self.parameter_entries, False, True, 4)
        self.parameter_entries.show_all()
        self.graph = GraphClass(self)
        self.v_box.pack_start(self.graph.drawing_area, True, True, 0)
        self.status_bar = gtk.Statusbar()
        self.status_bar.ContextId = self.status_bar.get_context_id("Dummy")
        self.status_bar.show()
        self.v_box.pack_end(self.status_bar, False, True, 0)
        self.v_box.show_all()