Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TurtleArtActivity.py
diff options
context:
space:
mode:
Diffstat (limited to 'TurtleArtActivity.py')
-rw-r--r--TurtleArtActivity.py501
1 files changed, 294 insertions, 207 deletions
diff --git a/TurtleArtActivity.py b/TurtleArtActivity.py
index 2fc7283..3cbe1a5 100644
--- a/TurtleArtActivity.py
+++ b/TurtleArtActivity.py
@@ -28,7 +28,6 @@ import gtk
import cairo
import gobject
import dbus
-import glob
import logging
_logger = logging.getLogger('turtleart-activity')
@@ -42,14 +41,17 @@ except ImportError:
HAS_TOOLBARBOX = False
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.radiotoolbutton import RadioToolButton
-from sugar.graphics.alert import (ConfirmationAlert, NotifyAlert)
+from sugar.graphics.alert import (ConfirmationAlert, Alert)
from sugar.graphics import style
from sugar.graphics.objectchooser import ObjectChooser
-from sugar import mime
+from sugar.graphics.icon import Icon
+from sugar.graphics.xocolor import XoColor
from sugar.datastore import datastore
from sugar import profile
+from sugar import mime
import os
+import glob
import tarfile
import subprocess
import ConfigParser
@@ -63,15 +65,19 @@ except ImportError:
from gettext import gettext as _
+from TurtleArt.taplugin import (load_a_plugin, cancel_plugin_install,
+ complete_plugin_install)
from TurtleArt.tapalette import (palette_names, help_strings, help_palettes,
- help_windows)
+ help_windows, default_values)
from TurtleArt.taconstants import (BLOCK_SCALE, XO1, XO15, XO175, XO4,
MIMETYPE)
from TurtleArt.taexportlogo import save_logo
+from TurtleArt.taexportpython import save_python
from TurtleArt.tautils import (data_to_file, data_to_string, data_from_string,
get_path, chooser_dialog, get_hardware)
from TurtleArt.tawindow import TurtleArtWindow
from TurtleArt.tacollaboration import Collaboration
+from TurtleArt.taprimitive import PyExportError
if HAS_TOOLBARBOX:
from util.helpbutton import (HelpButton, add_section, add_paragraph)
@@ -80,6 +86,8 @@ if HAS_TOOLBARBOX:
class TurtleArtActivity(activity.Activity):
''' Activity subclass for Turtle Art '''
_HOVER_HELP = '/desktop/sugar/activities/turtleart/hoverhelp'
+ _ORIENTATION = '/desktop/sugar/activities/turtleart/orientation'
+ _COORDINATE_SCALE = '/desktop/sugar/activities/turtleart/coordinatescale'
def __init__(self, handle):
''' Set up the toolbars, canvas, sharing, etc. '''
@@ -90,8 +98,13 @@ class TurtleArtActivity(activity.Activity):
self.tw = None
self.init_complete = False
+
self._stop_help = False
+ self.bundle_path = activity.get_bundle_path()
+
+ self.error_list = []
+
self.palette_buttons = []
self._palette_names = []
self._overflow_buttons = []
@@ -107,18 +120,28 @@ class TurtleArtActivity(activity.Activity):
self._setup_toolbar()
_logger.debug('_setup_canvas')
- self._canvas = self._setup_canvas(self._setup_scrolled_window())
-
- # FIX ME: not sure how or why self.canvas gets overwritten
- # It is set to self.sw in _setup_canvas but None here.
- # We need self.canvas for generating the preview image
- self.canvas = self.sw
+ self._setup_canvas(self._setup_scrolled_window())
_logger.debug('_setup_palette_toolbar')
self._setup_palette_toolbar()
self._setup_extra_controls()
_logger.debug('_setup_sharing')
+ if self.shared_activity:
+ # We're joining
+ if not self.get_shared():
+ xocolors = XoColor(profile.get_color().to_string())
+ share_icon = Icon(icon_name='zoom-neighborhood',
+ xo_color=xocolors)
+ self._joined_alert = Alert()
+ self._joined_alert.props.icon = share_icon
+ self._joined_alert.props.title = _('Please wait')
+ self._joined_alert.props.msg = _('Starting connection...')
+ self.add_alert(self._joined_alert)
+
+ # Wait for joined signal
+ self.connect("joined", self._joined_cb)
+
self._setup_sharing()
# Activity count is the number of times this instance has been
@@ -137,6 +160,16 @@ class TurtleArtActivity(activity.Activity):
self.client = gconf.client_get_default()
if self.client.get_int(self._HOVER_HELP) == 1:
self._do_hover_help_toggle(None)
+ if not self.client.get_int(self._COORDINATE_SCALE) in [0, 1]:
+ self.tw.coord_scale = 1
+ self.do_rescale_cb(None)
+ else:
+ self.tw.coord_scale = 0
+ self.do_rescale_cb(None)
+
+ self._selected_sample = None
+ self._sample_window = None
+
self.init_complete = True
if not hasattr(self, '_offsets'):
@@ -150,6 +183,30 @@ class TurtleArtActivity(activity.Activity):
self._challenge_window = None
self._load_level()
+ def update_palette_from_metadata(self):
+ if HAS_GCONF:
+ # We have to wait to set the orientation for the palettes
+ # to be loaded.
+ self.client = gconf.client_get_default()
+ if self.client.get_int(self._ORIENTATION) == 1:
+ self.tw.set_orientation(1)
+
+ if 'palette' in self.metadata:
+ n = int(self.metadata['palette'])
+ if n == -1:
+ self.tw.hideshow_palette(False)
+ else:
+ # Try to set radio button to active
+ if n < len(self.palette_buttons):
+ self.palette_buttons[n].set_active(True)
+ else:
+ self.tw.show_palette(n=0)
+ if 'orientation' in self.metadata:
+ self.tw.set_orientation(int(self.metadata['orientation']))
+ else:
+ # Else start on the Turtle palette
+ self.tw.show_palette(n=0)
+
def check_buttons_for_fit(self):
''' Check to see which set of buttons to display '''
if not self.has_toolbarbox:
@@ -159,51 +216,96 @@ class TurtleArtActivity(activity.Activity):
# scrolling window
self._setup_palette_toolbar()
- if self.samples_button in self._toolbox.toolbar:
- self._toolbox.toolbar.remove(self.extras_separator)
- self._toolbox.toolbar.remove(self.samples_button)
- self._toolbox.toolbar.remove(self.stop_separator)
- self._toolbox.toolbar.remove(self.stop_button)
+ if self.samples_button in self.toolbox.toolbar:
+ self.toolbox.toolbar.remove(self.extras_separator)
+ self.toolbox.toolbar.remove(self.samples_button)
+ self.toolbox.toolbar.remove(self.stop_separator)
+ self.toolbox.toolbar.remove(self.stop_button)
self._view_toolbar.remove(self._coordinates_toolitem)
if gtk.gdk.screen_width() / 14 < style.GRID_CELL_SIZE:
self.samples_button2.show()
self.samples_label2.show()
- self._toolbox.toolbar.insert(self.stop_button, -1)
+ self.toolbox.toolbar.insert(self.stop_button, -1)
else:
self.samples_button2.hide()
self.samples_label2.hide()
- self._toolbox.toolbar.insert(self.extras_separator, -1)
+ self.toolbox.toolbar.insert(self.extras_separator, -1)
self.extras_separator.props.draw = True
self.extras_separator.show()
- self._toolbox.toolbar.insert(self.samples_button, -1)
+ self.toolbox.toolbar.insert(self.samples_button, -1)
self.samples_button.show()
- self._toolbox.toolbar.insert(self.stop_separator, -1)
+ self.toolbox.toolbar.insert(self.stop_separator, -1)
self.stop_separator.show()
- self._toolbox.toolbar.insert(self.stop_button, -1)
+ self.toolbox.toolbar.insert(self.stop_button, -1)
self._view_toolbar.insert(self._coordinates_toolitem, -1)
- self._toolbox.show_all()
+ self.toolbox.show_all()
# Activity toolbar callbacks
def do_save_as_logo_cb(self, button):
''' Write UCB logo code to datastore. '''
self.save_as_logo.set_icon('logo-saveon')
+ if hasattr(self, 'get_window'):
+ if hasattr(self.get_window(), 'get_cursor'):
+ self._old_cursor = self.get_window().get_cursor()
+ self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
+ gobject.timeout_add(250, self.__save_as_logo)
+
+ def __save_as_logo(self):
logo_code_path = self._dump_logo_code()
- if logo_code_path is None:
- return
+ if logo_code_path is not None:
+ dsobject = datastore.create()
+ dsobject.metadata['title'] = self.metadata['title'] + '.lg'
+ dsobject.metadata['mime_type'] = 'text/plain'
+ dsobject.metadata['icon-color'] = profile.get_color().to_string()
+ dsobject.set_file_path(logo_code_path)
+ datastore.write(dsobject)
+ dsobject.destroy()
+ os.remove(logo_code_path)
+ self.save_as_logo.set_icon('logo-saveoff')
+ if hasattr(self, 'get_window'):
+ self.get_window().set_cursor(self._old_cursor)
- dsobject = datastore.create()
- dsobject.metadata['title'] = self.metadata['title'] + '.lg'
- dsobject.metadata['mime_type'] = 'text/plain'
- dsobject.metadata['icon-color'] = profile.get_color().to_string()
- dsobject.set_file_path(logo_code_path)
- datastore.write(dsobject)
- dsobject.destroy()
- os.remove(logo_code_path)
- gobject.timeout_add(250, self.save_as_logo.set_icon, 'logo-saveoff')
- self._notify_successful_save(title=_('Save as Logo'))
+ def do_save_as_python_cb(self, widget):
+ ''' Callback for saving the project as Python code. '''
+ self.save_as_python.set_icon('python-saveon')
+ if hasattr(self, 'get_window'):
+ if hasattr(self.get_window(), 'get_cursor'):
+ self._old_cursor = self.get_window().get_cursor()
+ self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
+ gobject.timeout_add(250, self.__save_as_python)
+
+ def __save_as_python(self):
+ # catch PyExportError and display a user-friendly message instead
+ try:
+ pythoncode = save_python(self.tw)
+ except PyExportError as pyee:
+ if pyee.block is not None:
+ pyee.block.highlight()
+ self.tw.showlabel('status', str(pyee))
+ _logger.debug(pyee)
+
+ if pythoncode:
+ datapath = get_path(activity, 'instance')
+ python_code_path = os.path.join(datapath, 'tmpfile.py')
+ f = file(python_code_path, 'w')
+ f.write(pythoncode)
+ f.close()
+
+ dsobject = datastore.create()
+ dsobject.metadata['title'] = self.metadata['title'] + '.py'
+ dsobject.metadata['mime_type'] = 'text/x-python'
+ dsobject.metadata['icon-color'] = profile.get_color().to_string()
+ dsobject.set_file_path(python_code_path)
+ datastore.write(dsobject)
+ dsobject.destroy()
+
+ os.remove(python_code_path)
+ self.save_as_python.set_icon('python-saveoff')
+ if hasattr(self, 'get_window'):
+ self.get_window().set_cursor(self._old_cursor)
def do_load_ta_project_cb(self, button, new=False):
''' Load a project from the Journal. '''
@@ -230,7 +332,6 @@ class TurtleArtActivity(activity.Activity):
def do_load_ta_plugin_cb(self, button):
''' Load a plugin from the Journal. '''
- # While the file is loading, use the watch cursor
if hasattr(self, 'get_window'):
if hasattr(self.get_window(), 'get_cursor'):
self._old_cursor = self.get_window().get_cursor()
@@ -257,13 +358,27 @@ class TurtleArtActivity(activity.Activity):
''' Save the canvas to the Journal. '''
self.save_as_image.set_icon('image-saveon')
_logger.debug('saving image to journal')
+ if hasattr(self, 'get_window'):
+ if hasattr(self.get_window(), 'get_cursor'):
+ self._old_cursor = self.get_window().get_cursor()
+ self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
+ gobject.timeout_add(250, self.__save_as_image)
+ def __save_as_image(self):
self.tw.save_as_image()
- gobject.timeout_add(250, self.save_as_image.set_icon, 'image-saveoff')
- self._notify_successful_save(title=_('Save as image'))
+ self.save_as_image.set_icon('image-saveoff')
+ if hasattr(self, 'get_window'):
+ self.get_window().set_cursor(self._old_cursor)
def do_keep_cb(self, button):
''' Save a snapshot of the project to the Journal. '''
+ if hasattr(self, 'get_window'):
+ if hasattr(self.get_window(), 'get_cursor'):
+ self._old_cursor = self.get_window().get_cursor()
+ self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
+ gobject.timeout_add(250, self.__keep)
+
+ def __keep(self):
tmpfile = self._dump_ta_code()
if tmpfile is not None:
dsobject = datastore.create()
@@ -276,7 +391,9 @@ class TurtleArtActivity(activity.Activity):
datastore.write(dsobject)
dsobject.destroy()
os.remove(tmpfile)
- self._notify_successful_save(title=_('Save snapshot'))
+
+ if hasattr(self, 'get_window'):
+ self.get_window().set_cursor(self._old_cursor)
# Main/palette toolbar button callbacks
@@ -285,7 +402,7 @@ class TurtleArtActivity(activity.Activity):
if self.tw.palette:
self.tw.hideshow_palette(False)
self.do_hidepalette()
- if self.has_toolbarbox and self.tw.selected_palette is not None:
+ if not self.has_toolbarbox and self.tw.selected_palette is not None:
self.palette_buttons[self.tw.selected_palette].set_icon(
palette_names[self.tw.selected_palette] + 'off')
else:
@@ -324,7 +441,8 @@ class TurtleArtActivity(activity.Activity):
self.tw.no_help = False
self._hover_help_toggle.set_icon('help-off')
self._hover_help_toggle.set_tooltip(_('Turn off hover help'))
- self.client.set_int(self._HOVER_HELP, 0)
+ if HAS_GCONF:
+ self.client.set_int(self._HOVER_HELP, 0)
else:
self.tw.no_help = True
self.tw.last_label = None
@@ -332,7 +450,8 @@ class TurtleArtActivity(activity.Activity):
self.tw.status_spr.hide()
self._hover_help_toggle.set_icon('help-on')
self._hover_help_toggle.set_tooltip(_('Turn on hover help'))
- self.client.set_int(self._HOVER_HELP, 1)
+ if HAS_GCONF:
+ self.client.set_int(self._HOVER_HELP, 1)
# These methods are called both from toolbar buttons and blocks.
@@ -503,7 +622,7 @@ class TurtleArtActivity(activity.Activity):
if self.tw.block_scale in BLOCK_SCALE:
i = BLOCK_SCALE.index(self.tw.block_scale) + inc
else:
- i = BLOCK_SCALE[3] # 2.0
+ i = 3
if i < 0:
self.tw.block_scale = BLOCK_SCALE[0]
elif i == len(BLOCK_SCALE):
@@ -534,18 +653,30 @@ class TurtleArtActivity(activity.Activity):
self.tw.set_metric(True)
def do_rescale_cb(self, button):
- ''' Rescale coordinate system (100==height/2 or 100 pixels). '''
+ ''' Rescale coordinate system (20==height/2 or 100 pixels). '''
if self.tw.coord_scale == 1:
- self.tw.coord_scale = self.tw.height / 200
+ self.tw.coord_scale = self.tw.height / 40
self.rescale_button.set_icon('contract-coordinates')
self.rescale_button.set_tooltip(_('Rescale coordinates down'))
+ default_values['forward'] = [10]
+ default_values['back'] = [10]
+ default_values['arc'] = [90, 10]
+ default_values['setpensize'] = [1]
+ self.tw.turtles.get_active_turtle().set_pen_size(1)
else:
self.tw.coord_scale = 1
self.rescale_button.set_icon('expand-coordinates')
self.rescale_button.set_tooltip(_('Rescale coordinates up'))
- self.tw.eraser_button()
+ default_values['forward'] = [100]
+ default_values['back'] = [100]
+ default_values['arc'] = [90, 100]
+ default_values['setpensize'] = [5]
+ self.tw.turtles.get_active_turtle().set_pen_size(5)
+ if HAS_GCONF:
+ self.client.set_int(self._COORDINATE_SCALE, self.tw.coord_scale)
# Given the change in how overlays are handled (v123), there is no way
# to erase and then redraw the overlays.
+ self.tw.eraser_button()
def _do_help_cb(self, button):
if self._selected_challenge is None:
@@ -637,8 +768,10 @@ class TurtleArtActivity(activity.Activity):
def _setup_toolbar(self):
''' Setup toolbar according to Sugar version. '''
if self.has_toolbarbox:
+ self.max_participants = 4
+
self._setup_toolbar_help()
- self._toolbox = ToolbarBox()
+ self.toolbox = ToolbarBox()
self.activity_toolbar_button = ActivityToolbarButton(self)
@@ -659,33 +792,31 @@ class TurtleArtActivity(activity.Activity):
_('Help'),
self._do_help_cb,
None)
- # self._help_button = HelpButton(self)
self._make_load_save_buttons(self.activity_toolbar_button)
self.activity_toolbar_button.show()
- self._toolbox.toolbar.insert(self.activity_toolbar_button, -1)
+ self.toolbox.toolbar.insert(self.activity_toolbar_button, -1)
self.edit_toolbar_button.show()
- self._toolbox.toolbar.insert(self.edit_toolbar_button, -1)
+ self.toolbox.toolbar.insert(self.edit_toolbar_button, -1)
self.view_toolbar_button.show()
- self._toolbox.toolbar.insert(self.view_toolbar_button, -1)
+ self.toolbox.toolbar.insert(self.view_toolbar_button, -1)
self.palette_toolbar_button.show()
- self._toolbox.toolbar.insert(self.palette_toolbar_button, -1)
+ self.toolbox.toolbar.insert(self.palette_toolbar_button, -1)
- self.set_toolbar_box(self._toolbox)
- self.palette_toolbar_button.set_expanded(True)
+ self.set_toolbar_box(self.toolbox)
else:
- self._toolbox = activity.ActivityToolbox(self)
- self.set_toolbox(self._toolbox)
+ self.toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(self.toolbox)
self._project_toolbar = gtk.Toolbar()
- self._toolbox.add_toolbar(_('Project'), self._project_toolbar)
+ self.toolbox.add_toolbar(_('Project'), self._project_toolbar)
self._view_toolbar = gtk.Toolbar()
- self._toolbox.add_toolbar(_('View'), self._view_toolbar)
+ self.toolbox.add_toolbar(_('View'), self._view_toolbar)
edit_toolbar = gtk.Toolbar()
- self._toolbox.add_toolbar(_('Edit'), edit_toolbar)
+ self.toolbox.add_toolbar(_('Edit'), edit_toolbar)
journal_toolbar = gtk.Toolbar()
- self._toolbox.add_toolbar(_('Save/Load'), journal_toolbar)
+ self.toolbox.add_toolbar(_('Save/Load'), journal_toolbar)
self._make_palette_buttons(self._project_toolbar,
palette_button=True)
@@ -737,10 +868,14 @@ class TurtleArtActivity(activity.Activity):
edit_toolbar.show()
self._view_toolbar.show()
- self._toolbox.show()
+ self.toolbox.show()
- if not self.has_toolbarbox:
- self._toolbox.set_current_toolbar(1)
+ if self.has_toolbarbox:
+ self.edit_toolbar_button.set_expanded(True)
+ self.edit_toolbar_button.set_expanded(False)
+ self.palette_toolbar_button.set_expanded(True)
+ else:
+ self.toolbox.set_current_toolbar(1)
def _setup_extra_controls(self):
''' Add the rest of the buttons to the main toolbar '''
@@ -753,24 +888,24 @@ class TurtleArtActivity(activity.Activity):
self._make_project_buttons(self._project_toolbar)
return
- self._make_project_buttons(self._toolbox.toolbar)
+ self._make_project_buttons(self.toolbox.toolbar)
self.extras_separator = self._add_separator(
- self._toolbox.toolbar, expand=False, visible=True)
+ self.toolbox.toolbar, expand=False, visible=True)
self.samples_button = self._add_button(
'ta-open', _('Load challenges'), self._create_store,
- self._toolbox.toolbar)
+ self.toolbox.toolbar)
- self._toolbox.toolbar.insert(self._help_button, -1)
+ self.toolbox.toolbar.insert(self._help_button, -1)
self._help_button.show()
self.stop_separator = self._add_separator(
- self._toolbox.toolbar, expand=True, visible=False)
+ self.toolbox.toolbar, expand=True, visible=False)
self.stop_button = StopButton(self)
self.stop_button.props.accelerator = '<Ctrl>Q'
- self._toolbox.toolbar.insert(self.stop_button, -1)
+ self.toolbox.toolbar.insert(self.stop_button, -1)
self.stop_button.show()
def _setup_toolbar_help(self):
@@ -816,12 +951,11 @@ class TurtleArtActivity(activity.Activity):
help_palettes['activity-toolbar'].show()
add_paragraph(help_box, _('Share selected blocks'), icon='shareon')
- if gtk.gdk.screen_width() < 1024:
- add_paragraph(help_box, _('Save/Load'), icon='save-load')
- else:
- add_section(help_box, _('Save/Load'), icon='turtleoff')
+ add_paragraph(help_box, _('Save/Load'), icon='save-load')
add_paragraph(help_box, _('Save as image'), icon='image-saveoff')
add_paragraph(help_box, _('Save as Logo'), icon='logo-saveoff')
+ add_paragraph(help_box, _('Save as Python'), icon='python-saveoff')
+ add_paragraph(help_box, _('Save snapshot'), icon='filesaveoff')
add_paragraph(help_box, _('Load project'), icon='load-from-journal')
home = os.environ['HOME']
if activity.get_bundle_path()[0:len(home)] == home:
@@ -999,10 +1133,10 @@ class TurtleArtActivity(activity.Activity):
self._share_cb, toolbar)
if self.has_toolbarbox:
self._add_separator(toolbar, expand=False, visible=True)
- save_load_button = self._add_button(
- 'save-load', _('Save/Load'), self._save_load_palette_cb,
+ save_button = self._add_button(
+ 'save', _('Save'), self._save_load_palette_cb,
toolbar)
- self._palette = save_load_button.get_palette()
+ self._save_palette = save_button.get_palette()
button_box = gtk.VBox()
self.save_as_image, label = self._add_button_and_label(
'image-saveoff', _('Save as image'), self.do_save_as_image_cb,
@@ -1010,16 +1144,28 @@ class TurtleArtActivity(activity.Activity):
self.save_as_logo, label = self._add_button_and_label(
'logo-saveoff', _('Save as Logo'), self.do_save_as_logo_cb,
None, button_box)
-
- # When screen is in portrait mode, the buttons don't fit
- # on the main toolbar, so put them here.
+ self.save_as_python, label = self._add_button_and_label(
+ 'python-saveoff', _('Save as Python'),
+ self.do_save_as_python_cb,
+ None, button_box)
self.keep_button2, self.keep_label2 = self._add_button_and_label(
'filesaveoff', _('Save snapshot'), self.do_keep_cb,
None, button_box)
+
+ load_button = self._add_button(
+ 'load', _('Load'), self._save_load_palette_cb,
+ toolbar)
+ button_box.show_all()
+ self._save_palette.set_content(button_box)
+
+ self._load_palette = load_button.get_palette()
+ button_box = gtk.VBox()
+ # When screen is in portrait mode, the buttons don't fit
+ # on the main toolbar, so put them here.
self.samples_button2, self.samples_label2 = \
self._add_button_and_label('ta-open',
- _('Load challenges'),
- self._create_store,
+ _('Load example'),
+ self.do_samples_cb,
None,
button_box)
@@ -1038,7 +1184,7 @@ class TurtleArtActivity(activity.Activity):
'pippy-openoff', _('Load Python block'),
self.do_load_python_cb, None, button_box)
button_box.show_all()
- self._palette.set_content(button_box)
+ self._load_palette.set_content(button_box)
else:
self.save_as_image = self._add_button(
'image-saveoff', _('Save as image'), self.do_save_as_image_cb,
@@ -1046,10 +1192,14 @@ class TurtleArtActivity(activity.Activity):
self.save_as_logo = self._add_button(
'logo-saveoff', _('Save as Logo'), self.do_save_as_logo_cb,
toolbar)
+ self.save_as_python = self._add_button(
+ 'python-saveoff', _('Save as Python'),
+ self.do_save_as_python_cb,
+ toolbar)
self.keep_button = self._add_button(
'filesaveoff', _('Save snapshot'), self.do_keep_cb, toolbar)
self.load_ta_project = self._add_button(
- 'load-from-journal', _('Load project'),
+ 'load-from-journal', _('Add project'),
self.do_load_ta_project_cb, toolbar)
# Only enable plugin loading if installed in $HOME
if activity.get_bundle_path()[0:len(home)] == home:
@@ -1061,13 +1211,12 @@ class TurtleArtActivity(activity.Activity):
self.do_load_python_cb, toolbar)
def _save_load_palette_cb(self, button):
- if self._palette:
- if not self._palette.is_up():
- self._palette.popup(immediate=True,
- state=self._palette.SECONDARY)
+ palette = button.get_palette()
+ if palette:
+ if not palette.is_up():
+ palette.popup(immediate=True, state=palette.SECONDARY)
else:
- self._palette.popdown(immediate=True)
- return
+ palette.popdown(immediate=True)
def _make_palette_buttons(self, toolbar, palette_button=False):
''' Creates the palette and block buttons for both toolbar types'''
@@ -1208,6 +1357,12 @@ class TurtleArtActivity(activity.Activity):
self._collaboration = Collaboration(self.tw, self)
self._collaboration.setup()
+ def _joined_cb(self, widget):
+ if self._joined_alert is not None:
+ self.remove_alert(self._joined_alert)
+ self._joined_alert = None
+ self.set_canvas(self.fixed)
+
def send_xy(self):
''' Resync xy position (and orientation) of my turtle. '''
self._collaboration.send_my_xy()
@@ -1243,112 +1398,26 @@ class TurtleArtActivity(activity.Activity):
self._offsets[basename][2])
self.metadata['mime_type'] = MIMETYPE[0]
self.metadata['turtle blocks'] = ''.join(self.tw.used_block_list)
- self.metadata['public'] = data_to_string(['activity count',
- 'turtle blocks'])
- _logger.debug('Wrote to file: %s' % (file_path))
-
- def _load_a_plugin(self, tmp_dir):
- ''' Load a plugin from the Journal and initialize it '''
- plugin_path = os.path.join(tmp_dir, 'plugin.info')
- _logger.debug(plugin_path)
- file_info = ConfigParser.ConfigParser()
- if len(file_info.read(plugin_path)) == 0:
- _logger.debug('Required file plugin.info could not be found.')
- self.tw.showlabel('status',
- label=_('Plugin could not be installed.'))
- elif not file_info.has_option('Plugin', 'name'):
- _logger.debug('Required open name not found in \
-Plugin section of plugin.info file.')
- self.tw.showlabel(
- 'status', label=_('Plugin could not be installed.'))
- else:
- plugin_name = file_info.get('Plugin', 'name')
- _logger.debug('Plugin name: %s' % (plugin_name))
- tmp_path = os.path.join(tmp_dir, plugin_name)
- plugin_path = os.path.join(activity.get_bundle_path(), 'plugins')
- if os.path.exists(os.path.join(plugin_path, plugin_name)):
- self._reload_plugin_alert(tmp_dir, tmp_path, plugin_path,
- plugin_name, file_info)
- else:
- self._complete_plugin_install(tmp_dir, tmp_path, plugin_path,
- plugin_name, file_info)
-
- def _complete_plugin_install(self, tmp_dir, tmp_path, plugin_path,
- plugin_name, file_info):
- ''' We complete the installation directly or from ConfirmationAlert '''
- status = subprocess.call(['cp', '-r', tmp_path, plugin_path + '/'])
- if status == 0:
- # Save the plugin.info file in the plugin directory
- subprocess.call(['cp', os.path.join(tmp_dir, 'plugin.info'),
- os.path.join(plugin_path, plugin_name) + '/'])
- _logger.debug('Plugin installed successfully.')
- if self.has_toolbarbox:
- palette_name_list = []
- if file_info.has_option('Plugin', 'palette'):
- palette_name_list = file_info.get(
- 'Plugin', 'palette').split(',')
- create_palette = []
- for palette_name in palette_name_list:
- if not palette_name.strip() in palette_names:
- create_palette.append(True)
- else:
- create_palette.append(False)
- _logger.debug('Initializing plugin...')
- self.tw.init_plugin(plugin_name)
- self.tw.turtleart_plugins[-1].setup()
- self.tw.load_media_shapes()
- for i, palette_name in enumerate(palette_name_list):
- if create_palette[i]:
- _logger.debug('Creating plugin palette %s (%d)' %
- (palette_name.strip(), i))
- j = len(self.palette_buttons)
- self.palette_buttons.append(
- self._radio_button_factory(
- palette_name.strip() + 'off',
- self._palette_toolbar,
- self.do_palette_buttons_cb,
- j - 1,
- help_strings[palette_name.strip()],
- self.palette_buttons[0]))
- self._overflow_buttons.append(
- self._add_button(
- palette_name.strip() + 'off',
- None,
- self.do_palette_buttons_cb,
- None,
- arg=j - 1))
- self._overflow_box.pack_start(
- self._overflow_buttons[j - 1])
- self.tw.palettes.insert(j - 1, [])
- self.tw.palette_sprs.insert(j - 1, [None, None])
- else:
- _logger.debug('Palette already exists... \
-skipping insert')
- # We need to change the index associated with the
- # Trash Palette Button.
- j = len(palette_names)
- pidx = palette_names.index(palette_name.strip())
- self.palette_buttons[pidx].connect(
- 'clicked', self.do_palette_buttons_cb, j - 1)
- self._overflow_buttons[pidx].connect(
- 'clicked', self.do_palette_buttons_cb, j - 1)
- _logger.debug('reinitializing palette toolbar')
- self._setup_palette_toolbar()
- else:
- self.tw.showlabel('status',
- label=_('Please restart Turtle Art \
-in order to use the plugin.'))
+ # Deprecated
+ # self.metadata['public'] = data_to_string(['activity count',
+ # 'turtle blocks'])
+ if self.tw.palette:
+ self.metadata['palette'] = str(self.tw.selected_palette)
else:
- self.tw.showlabel(
- 'status', label=_('Plugin could not be installed.'))
- status = subprocess.call(['rm', '-r', tmp_path])
- if status != 0:
- _logger.debug('Problems cleaning up tmp_path.')
- shutil.rmtree(tmp_dir)
+ self.metadata['palette'] = '-1'
+ self.metadata['orientation'] = str(self.tw.orientation)
+ if HAS_GCONF:
+ self.client.set_int(self._ORIENTATION, self.tw.orientation)
+ if len(self.error_list) > 0:
+ errors = []
+ if 'error_list' in self.metadata:
+ for error in data_from_string(self.metadata['error_list']):
+ errors.append(error)
+ for error in self.error_list:
+ errors.append(error)
+ self.metadata['error_list'] = data_to_string(errors)
+ _logger.debug('Wrote to file: %s' % (file_path))
- def _cancel_plugin_install(self, tmp_dir):
- ''' If we cancel, just cleanup '''
- shutil.rmtree(tmp_dir)
def _reload_plugin_alert(self, tmp_dir, tmp_path, plugin_path, plugin_name,
file_info):
@@ -1363,8 +1432,8 @@ in order to use the plugin.'))
if response_id is gtk.RESPONSE_OK:
_logger.debug('continue to install')
self.remove_alert(alert)
- self._complete_plugin_install(tmp_dir, tmp_path, plugin_path,
- plugin_name, file_info)
+ complete_plugin_install(self, tmp_dir, tmp_path, plugin_path,
+ plugin_name, file_info)
elif response_id is gtk.RESPONSE_CANCEL:
_logger.debug('cancel install')
self.remove_alert(alert)
@@ -1424,7 +1493,7 @@ in order to use the plugin.'))
gobject.idle_add(self._project_loader, turtle_code)
else:
_logger.debug('load a plugin from %s' % (tmp_dir))
- self._load_a_plugin(tmp_dir)
+ load_a_plugin(self, tmp_dir)
self.restore_cursor()
except:
_logger.debug('Could not extract files from %s.' %
@@ -1557,6 +1626,25 @@ in order to use the plugin.'))
self._old_cursor = self.get_window().get_cursor()
self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1))
+ def empty_trash_alert(self, title, msg):
+ ''' We get confirmation from the user before emptying the trash '''
+ alert = ConfirmationAlert()
+ alert.props.title = title
+ alert.props.msg = msg
+
+ def _empty_trash_alert_response_cb(alert, response_id, self):
+ if response_id is gtk.RESPONSE_OK:
+ _logger.debug('emptying the trash')
+ self.remove_alert(alert)
+ self.tw._empty_trash()
+ elif response_id is gtk.RESPONSE_CANCEL:
+ _logger.debug('cancel emptying the trash')
+ self.remove_alert(alert)
+
+ alert.connect('response', _empty_trash_alert_response_cb, self)
+ self.add_alert(alert)
+ alert.show()
+
def _add_label(self, string, toolbar, width=None):
''' Add a label to a toolbar. '''
label = gtk.Label(string)
@@ -1609,6 +1697,7 @@ in order to use the plugin.'))
return button
def _load_level(self, custom=False):
+ logging.error('LOAD LEVEL')
self.tw.canvas.clearscreen()
self._draw_cartoon()
if custom:
@@ -1673,19 +1762,6 @@ in order to use the plugin.'))
button_and_label.show()
return button, label
- def _notify_successful_save(self, title='', msg=''):
- ''' Notify user when saves are completed '''
-
- def _notification_alert_response_cb(alert, response_id, self):
- self.remove_alert(alert)
-
- alert = NotifyAlert()
- alert.props.title = title
- alert.connect('response', _notification_alert_response_cb, self)
- alert.props.msg = msg
- self.add_alert(alert)
- alert.show()
-
def hide_store(self, widget=None):
if self._challenge_window is not None:
self._challenge_box.hide()
@@ -1773,6 +1849,17 @@ in order to use the plugin.'))
filepath, 100, 100)
store.append([pixbuf, filepath])
+ def is_toolbar_expanded(self):
+ if self.palette_toolbar_button.is_expanded():
+ return True
+ elif self.edit_toolbar_button.is_expanded():
+ return True
+ elif self.view_toolbar_button.is_expanded():
+ return True
+ elif self.activity_toolbar_button.is_expanded():
+ return True
+ return False
+
def _scan_for_challenges(self):
file_list = list(glob.glob(os.path.join(activity.get_bundle_path(),
'samples', 'thumbnails',