From 2467422171c71ce916a13d2dc9a0d7c7418b234f Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Thu, 09 May 2013 21:34:25 +0000 Subject: Add ability to remove macros --- diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index 109149b..8de5e2e 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -48,6 +48,8 @@ DEGTOR = 2 * pi / 360 import locale +import logging + from taconstants import (HORIZONTAL_PALETTE, VERTICAL_PALETTE, BLOCK_SCALE, MEDIA_SHAPES, STATUS_SHAPES, OVERLAY_SHAPES, TOOLBAR_SHAPES, TAB_LAYER, RETURN, OVERLAY_LAYER, CATEGORY_LAYER, BLOCKS_WITH_SKIN, ICON_SIZE, @@ -112,7 +114,9 @@ class TurtleArtWindow(): if running_sugar: self.parent.show_all() self.running_sugar = True + from sugar import profile + self.nick = profile.get_nick_name() self.macros_path = os.path.join( get_path(parent, 'data'), self._MACROS_SUBPATH) @@ -155,6 +159,7 @@ class TurtleArtWindow(): self.saving_blocks = False self.copying_blocks = False self.sharing_blocks = False + self.deleting_blocks = False try: locale.setlocale(locale.LC_NUMERIC, '') @@ -1383,6 +1388,11 @@ before making changes to your Turtle Blocks program')) self.copying_blocks = False self.sharing_blocks = False self.saving_blocks = False + elif self.deleting_blocks: + if blk is None or blk.type != 'proto': + self.parent.get_window().set_cursor( + gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) + self.deleting_blocks = False if blk is not None: if blk.type == 'block': self.selected_blk = blk @@ -1390,7 +1400,14 @@ before making changes to your Turtle Blocks program')) elif blk.type == 'trash': self._restore_from_trash(find_top_block(blk)) elif blk.type == 'proto': - if blk.name == 'restoreall': + if self.deleting_blocks: + if self.selected_palette == \ + palette_names.index('myblocks'): + self._delete_stack_alert(blk) + self.parent.get_window().set_cursor( + gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) + self.deleting_blocks = False + elif blk.name == 'restoreall': self._restore_all_from_trash() elif blk.name == 'restore': self.restore_latest_from_trash() @@ -1503,6 +1520,62 @@ before making changes to your Turtle Blocks program')) return True return False + def _delete_stack_alert(self, blk): + if self.running_sugar: + from sugar.graphics.alert import Alert + from sugar.graphics.icon import Icon + + alert = Alert() + alert.props.title = _('Delete stack') + alert.props.msg = _('Really delete stack?') + + cancel_icon = Icon(icon_name='dialog-cancel') + alert.add_button(gtk.RESPONSE_CANCEL, _('Cancel'), + cancel_icon) + stop_icon = Icon(icon_name='dialog-ok') + alert.add_button(gtk.RESPONSE_OK, + '%s %s' % (_('Delete stack'), blk.spr.labels[0]), + stop_icon) + + self.activity.add_alert(alert) + alert.connect('response', self._delete_stack_dialog_response_cb, + blk) + else: + msg = _('Really delete stack?') + dialog = gtk.MessageDialog(self.parent, 0, gtk.MESSAGE_WARNING, + gtk.BUTTONS_OK_CANCEL, msg) + dialog.set_title('%s %s' % (_('Delete stack'), blk.spr.labels[0])) + answer = dialog.run() + dialog.destroy() + if answer == gtk.RESPONSE_OK: + self._delete_stack(blk) + + def _delete_stack_dialog_response_cb(self, alert, response_id, blk): + self.activity.remove_alert(alert) + if response_id == gtk.RESPONSE_OK: + self._delete_stack(blk) + + def _delete_stack(self, blk): + name = blk.spr.labels[0] + error_output('deleting proto: clicked on %s %s' % (blk.name, name), + self.running_sugar) + macro_path = os.path.join(self.macros_path, '%s.tb' % (name)) + if os.path.exists(macro_path): + try: + os.remove(macro_path) + except Exception, e: + error_debug('Could not remove macro %s: %s' % ( + macro_path, e)) + return + i = palette_names.index('myblocks') + palette_blocks[i].remove(blk.name) + for pblk in self.palettes[i]: + if pblk.name == blk.name: + pblk.spr.hide() + self.palettes[i].remove(pblk) + break + self.show_toolbar_palette(i, regenerate=True) + def _look_for_a_turtle(self, spr, x, y): # Next, look for a turtle t = self.turtles.spr_to_turtle(spr) @@ -1891,11 +1964,14 @@ before making changes to your Turtle Blocks program')) debug_output('Serialize blocks and save.', self.running_sugar) i = find_hat(data) - if i is not None and data[i][4][1] is not None: + if i is not None: + name = '' try: name = str(data[data[i][4][1]][1][1]) except: - name = 'macro%d' % (int(uniform(0, 10000))) + pass + if name == '': + name = 'stack_%d' % (int(uniform(0, 10000))) debug_output('saving macro %s' % (name), self.running_sugar) if not os.path.exists(self.macros_path): @@ -1906,8 +1982,12 @@ before making changes to your Turtle Blocks program')) pass else: raise - data_to_file(data, os.path.join(self.macros_path, - '%s.tb' % (name))) + macro_path = os.path.join( + self.macros_path, '%s.tb' % (name)) + # Make sure name is unique + while os.path.exists(macro_path): + macro_path = increment_name(macro_path) + data_to_file(data, macro_path) elif self.copying_blocks: clipboard = gtk.Clipboard() debug_output('Serialize blocks and copy to clipboard', @@ -2415,7 +2495,7 @@ before making changes to your Turtle Blocks program')) if block_name in special_names: special_block_name = special_names[block_name] elif block_name in block_names: - special_block_name = block_names[block_name][0] + special_block_name = str(block_names[block_name][0]) elif block_name in TOOLBAR_SHAPES: special_block_name = '' else: diff --git a/TurtleArtActivity.py b/TurtleArtActivity.py index 2867cb8..c26b2b0 100644 --- a/TurtleArtActivity.py +++ b/TurtleArtActivity.py @@ -621,8 +621,11 @@ class TurtleArtActivity(activity.Activity): edit_toolbar, 'v') self._add_button('edit-undo', _('Restore blocks from trash'), self._undo_cb, edit_toolbar) - self._add_button('save-macro', _('Save stack'), self._save_macro_cb, + self._add_separator(edit_toolbar) + self._add_button('save-blocks', _('Save stack'), self._save_macro_cb, edit_toolbar) + self._add_button('delete-blocks', _('Delete stack'), + self._delete_macro_cb, edit_toolbar) self._add_button('view-fullscreen', _('Fullscreen'), self.do_fullscreen_cb, self._view_toolbar, @@ -1347,6 +1350,7 @@ in order to use the plugin.')) self.tw.copying_blocks = False self.tw.sharing_blocks = False self.tw.saving_blocks = False + self.tw.deleting_blocks = False if hasattr(self, 'get_window'): if hasattr(self.get_window(), 'get_cursor'): self.get_window().set_cursor(self._old_cursor) @@ -1366,7 +1370,7 @@ in order to use the plugin.')) self.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1)) def _save_macro_cb(self, button): - ''' Save stack macros_path ''' + ''' Save stack to macros_path ''' if self.tw.saving_blocks: self.tw.saving_blocks = False self.restore_cursor() @@ -1377,6 +1381,18 @@ 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 _delete_macro_cb(self, button): + ''' Delete stack from macros_path ''' + if self.tw.deleting_blocks: + self.tw.deleting_blocks = False + self.restore_cursor() + else: + self.tw.deleting_blocks = True + 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.HAND1)) + def _paste_cb(self, button): ''' Paste from the clipboard. ''' if self.tw.copying_blocks: diff --git a/icons/delete-blocks.svg b/icons/delete-blocks.svg new file mode 100644 index 0000000..992bb8d --- /dev/null +++ b/icons/delete-blocks.svg @@ -0,0 +1,78 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/icons/myblocksoff.svg b/icons/myblocksoff.svg new file mode 100644 index 0000000..7d9a28c --- /dev/null +++ b/icons/myblocksoff.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/icons/myblockson.svg b/icons/myblockson.svg new file mode 100644 index 0000000..bb8852d --- /dev/null +++ b/icons/myblockson.svg @@ -0,0 +1,70 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/icons/save-blocks.svg b/icons/save-blocks.svg new file mode 100644 index 0000000..c2cff38 --- /dev/null +++ b/icons/save-blocks.svg @@ -0,0 +1,78 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/turtleblocks.py b/turtleblocks.py index 36a03de..a31cb07 100755 --- a/turtleblocks.py +++ b/turtleblocks.py @@ -388,6 +388,8 @@ class TurtleMain(): MenuBuilder.make_menu_item(menu, _('Paste'), self._do_paste_cb) MenuBuilder.make_menu_item(menu, _('Save stack'), self._do_save_macro_cb) + MenuBuilder.make_menu_item(menu, _('Delete stack'), + self._do_delete_macro_cb) edit_menu = MenuBuilder.make_sub_menu(menu, _('Edit')) menu = gtk.Menu() @@ -601,6 +603,7 @@ class TurtleMain(): def _do_save_macro_cb(self, widget): ''' Callback for save stack button. ''' self.tw.copying_blocks = False + self.tw.deleting_blocks = False if self.tw.saving_blocks: self.win.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) self.tw.saving_blocks = False @@ -608,9 +611,21 @@ class TurtleMain(): self.win.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1)) self.tw.saving_blocks = True + def _do_delete_macro_cb(self, widget): + ''' Callback for delete stack button. ''' + self.tw.copying_blocks = False + self.tw.saving_blocks = False + if self.tw.deleting_blocks: + self.win.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) + self.tw.deleting_blocks = False + else: + self.win.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1)) + self.tw.deleting_blocks = True + def _do_copy_cb(self, button): ''' Callback for copy button. ''' self.tw.saving_blocks = False + self.tw.deleting_blocks = False if self.tw.copying_blocks: self.win.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) self.tw.copying_blocks = False @@ -622,6 +637,7 @@ class TurtleMain(): ''' Callback for paste button. ''' self.tw.copying_blocks = False self.tw.saving_blocks = False + self.tw.deleting_blocks = False self.win.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) clipBoard = gtk.Clipboard() text = clipBoard.wait_for_text() -- cgit v0.9.1