Ticket #2859: 0001-adding-copy-submenu-to-viewsource.patch

File 0001-adding-copy-submenu-to-viewsource.patch, 11.0 KB (added by walter, 13 years ago)

new version of patch that includes modifying icon of copied bundle

  • src/jarabe/view/Makefile.am

    From 2e7e565a00d843ddbe64d495c82331c52bba7184 Mon Sep 17 00:00:00 2001
    From: Walter Bender <walter.bender@gmail.com>
    Date: Mon, 6 Jun 2011 12:07:32 -0400
    Subject: [PATCH] adding copy submenu to viewsource
    Organization: Sugar Labs Foundation
    
    ---
     src/jarabe/view/Makefile.am     |    1 +
     src/jarabe/view/custombundle.py |  169 +++++++++++++++++++++++++++++++++++++++
     src/jarabe/view/viewsource.py   |   37 +++++++--
     3 files changed, 200 insertions(+), 7 deletions(-)
     create mode 100644 src/jarabe/view/custombundle.py
    
    diff --git a/src/jarabe/view/Makefile.am b/src/jarabe/view/Makefile.am
    index 1abea6d..b38b382 100644
    a b sugar_PYTHON = \ 
    33        __init__.py                     \
    44        buddyicon.py                    \
    55        buddymenu.py                    \
     6        custombundle.py                 \
    67        keyhandler.py                   \
    78        launcher.py                     \
    89        palettes.py                     \
  • new file src/jarabe/view/custombundle.py

    diff --git a/src/jarabe/view/custombundle.py b/src/jarabe/view/custombundle.py
    new file mode 100644
    index 0000000..e61a030
    - +  
     1# Copyright (C) 2011 Walter Bender
     2#
     3# This program is free software; you can redistribute it and/or modify
     4# it under the terms of the GNU General Public License as published by
     5# the Free Software Foundation; either version 2 of the License, or
     6# (at your option) any later version.
     7#
     8# This program is distributed in the hope that it will be useful,
     9# but WITHOUT ANY WARRANTY; without even the implied warranty of
     10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11# GNU General Public License for more details.
     12#
     13# You should have received a copy of the GNU General Public License
     14# along with this program; if not, write to the Free Software
     15# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     16
     17import os
     18import subprocess
     19import gtk
     20
     21import logging
     22_logger = logging.getLogger('ViewSource')
     23
     24CUSTOMICON = 'customize.svg'
     25RESCALE = '  <g transform="matrix(0.73,0,0,0.73,7.57,7.96)">\n'
     26
     27
     28def customize_bundle(home_activities, new_bundle_name):
     29    ''' Modify bundle_id in new activity.info file. '''
     30    fd_old = open(os.path.join(home_activities, new_bundle_name,
     31                               'activity', 'activity.info'), 'r')
     32    fd_new = open(os.path.join(home_activities, new_bundle_name,
     33                               'activity', 'new_activity.info'), 'w')
     34    for line in fd_old:
     35        tokens = line.split('=')
     36        if tokens[0].rstrip() == 'bundle_id':
     37            new_bundle_id = tokens[1].strip() + '_my_copy'
     38            fd_new.write('%s = %s\n' % (tokens[0].rstrip(), new_bundle_id))
     39        elif tokens[0].rstrip() == 'icon':
     40            old_icon_name = tokens[1].strip()
     41            new_icon_name = 'My' + old_icon_name
     42            fd_new.write('%s = %s\n' % (tokens[0].rstrip(), new_icon_name))
     43        else:
     44            fd_new.write(line)
     45    fd_old.close
     46    fd_new.close
     47    command_line = ['mv', os.path.join(home_activities, new_bundle_name,
     48                                       'activity', 'new_activity.info'),
     49                    os.path.join(home_activities, new_bundle_name,
     50                                 'activity', 'activity.info')]
     51    _logger.debug(subprocess.call(command_line))
     52
     53    _custom_icon(home_activities, new_bundle_name, old_icon_name,
     54                 new_icon_name)
     55
     56
     57def _custom_icon(home_activities, new_bundle_name, old_icon_name,
     58                 new_icon_name):
     59    ''' Modify new activity icon by overlaying custom icon. '''
     60
     61    # First, find customize.svg, which will be used as an overlay.
     62    for path in gtk.icon_theme_get_default().get_search_path():
     63        if os.path.exists(os.path.join(path, 'sugar', 'scalable', 'actions',
     64                                       CUSTOMICON)):
     65            break
     66        else:
     67            path = None
     68       
     69    if path == None:
     70        _logger.debug('customize.svg not found')
     71        command_line = ['mv', os.path.join(home_activities, new_bundle_name,
     72                                           'activity', old_icon_name + '.svg'),
     73                        os.path.join(home_activities, new_bundle_name,
     74                                     'activity', new_icon_name + '.svg')]
     75        _logger.debug(subprocess.call(command_line))
     76        return
     77
     78    # Extract custom_svg, i.e., the 'payload' from the svg file.
     79    fd_custom = open(os.path.join(path, 'sugar', 'scalable', 'actions',
     80                                CUSTOMICON), 'r')
     81
     82    custom_svg = ''
     83    found_begin_svg_tag = False
     84    found_close_tag = False
     85    found_end_svg_tag = False
     86
     87    for line in fd_custom:
     88        if not found_begin_svg_tag:
     89            if line.count('<svg') > 0:
     90                found_begin_svg_tag = True
     91                partials = line.split('<svg')
     92                found_close_tag, temp_string = _find_and_split(
     93                    partials[1], '>', '', None)
     94            else:
     95                pass
     96        elif not found_close_tag:
     97            found_close_tag, temp_string = _find_and_split(
     98                line, '>', '', None)
     99            temp_string = ''
     100        elif not found_end_svg_tag:
     101            custom_svg += temp_string
     102            found_end_svg_tag, temp_string = _find_and_split(
     103                line, '</svg>', '', None)
     104        else:
     105            custom += line
     106    fd_custom.close
     107 
     108    # Next, modify the old icon by shrinking it and applying the overlay.
     109    fd_old = open(os.path.join(home_activities, new_bundle_name, 'activity',
     110                             old_icon_name + '.svg'), 'r')
     111    fd_new = open(os.path.join(home_activities, new_bundle_name, 'activity',
     112                             new_icon_name + '.svg'), 'w')
     113
     114    found_begin_svg_tag = False
     115    found_close_tag = False
     116    found_end_svg_tag = False
     117
     118    for line in fd_old:
     119        if not found_begin_svg_tag:
     120            if line.count('<svg') > 0:
     121                found_begin_svg_tag = True
     122                partials = line.split('<svg')
     123                fd_new.write(partials[0] + '<svg\n')
     124                found_close_tag = _find_and_split(partials[1], '>',
     125                                                       RESCALE, fd_new)
     126            else:
     127                fd_new.write(line)
     128        elif not found_close_tag:
     129            found_close_tag = _find_and_split(line, '>', RESCALE, fd_new)
     130        elif not found_end_svg_tag:
     131            found_end_svg_tag = _find_and_split(
     132                line, '</svg>', '  </g>\n' + custom_svg, fd_new,
     133                insert_before=True)
     134        else:
     135            fd_new.write(line)
     136    fd_old.close
     137    fd_new.close
     138
     139
     140def _find_and_split(line, token, insert, fd, insert_before=False):
     141    ''' If token is found in line, split line, add insert, and write;
     142    else just write. '''
     143
     144    tmp_string = ''
     145
     146    if line.count(token) > 0:
     147        partials = line.split(token)
     148        if insert_before:
     149            tmp_string += insert
     150            tmp_string += partials[0] + token + '\n'
     151        else:
     152            tmp_string += partials[0] + token + '\n'
     153            tmp_string += insert
     154        tmp_string += partials[1]
     155        if len(partials) > 2:
     156            for i, part in enumerate(partials):
     157                if i > 1:
     158                    tmp_string += partials[i] + token
     159        if fd is None:
     160            return True, tmp_string
     161        else:
     162            fd.write(tmp_string)
     163            return True
     164    else:
     165        if fd is None:
     166            return False, line
     167        else:
     168            fd.write(line)
     169            return False
  • src/jarabe/view/viewsource.py

    diff --git a/src/jarabe/view/viewsource.py b/src/jarabe/view/viewsource.py
    index a9f6e12..5b9293a 100644
    a b  
    1616# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1717
    1818import os
     19import subprocess
    1920import logging
    2021from gettext import gettext as _
    2122
    from sugar.bundle.activitybundle import ActivityBundle 
    3637from sugar.datastore import datastore
    3738from sugar import mime
    3839
     40from custombundle import customize_bundle
    3941
    4042_SOURCE_FONT = pango.FontDescription('Monospace %d' % style.FONT_SIZE)
    4143
    class ViewSource(gtk.Window): 
    133135        command = activity_bundle.get_command()
    134136        if len(command.split(' ')) > 1:
    135137            name = command.split(' ')[1].split('.')[-1]
    136             tmp_path = command.split(' ')[1].replace('.', '/')
     138            tmppath = command.split(' ')[1].replace('.', '/')
    137139            file_name = tmppath[0:-(len(name) + 1)] + '.py'
    138140            path = os.path.join(activity_bundle.get_path(), file_name)
    139141            self._selected_file = path
    class ViewSource(gtk.Window): 
    201203class DocumentButton(RadioToolButton):
    202204    __gtype_name__ = 'SugarDocumentButton'
    203205
    204     def __init__(self, file_name, document_path, title):
     206    def __init__(self, file_name, document_path, title, bundle=False):
    205207        RadioToolButton.__init__(self)
    206208
    207209        self._document_path = document_path
    class DocumentButton(RadioToolButton): 
    218220        self.set_icon_widget(icon)
    219221        icon.show()
    220222
    221         menu_item = MenuItem(_('Keep'))
    222         icon = Icon(icon_name='document-save', icon_size=gtk.ICON_SIZE_MENU,
    223                     xo_color=XoColor(self._color))
     223        if bundle:
     224            menu_item = MenuItem(_('Copy'))
     225            icon = Icon(icon_name='edit-copy', icon_size=gtk.ICON_SIZE_MENU,
     226                        xo_color=XoColor(self._color))
     227            menu_item.connect('activate', self.__copy_to_home_cb)
     228        else:
     229            menu_item = MenuItem(_('Keep'))
     230            icon = Icon(icon_name='document-save', icon_size=gtk.ICON_SIZE_MENU,
     231                        xo_color=XoColor(self._color))
     232            menu_item.connect('activate', self.__keep_in_journal_cb)
     233
    224234        menu_item.set_image(icon)
    225235
    226         menu_item.connect('activate', self.__keep_in_journal_cb)
    227236        self.props.palette.menu.append(menu_item)
    228237        menu_item.show()
    229238
     239    def __copy_to_home_cb(self, menu_item):
     240        ''' Make a local copy of the activity bundle in
     241        $HOME/Activities as MyActivity and change the bundle_id to
     242        bundle_id_my_copy'''
     243        # TODO: Check to see if MyActivity already exisits
     244        home_activities = os.path.join(os.environ['HOME'], 'Activities')
     245        new_bundle_name = 'My' + self._document_path.split('/')[-1]
     246        command_line = ['cp', '-r', self._document_path,
     247                        os.path.join(home_activities, new_bundle_name)]
     248        _logger.debug(subprocess.call(command_line))
     249
     250        customize_bundle(home_activities, new_bundle_name)
     251
    230252    def __keep_in_journal_cb(self, menu_item):
    231253        mime_type = mime.get_from_file_name(self._document_path)
    232254        if mime_type == 'application/octet-stream':
    class Toolbar(gtk.Toolbar): 
    283305            self._add_separator()
    284306
    285307        if bundle_path is not None and os.path.exists(bundle_path):
    286             activity_button = RadioToolButton()
     308            activity_button = DocumentButton(file_name, bundle_path, title,
     309                                             bundle=True)
    287310            icon = Icon(file=file_name,
    288311                        icon_size=gtk.ICON_SIZE_LARGE_TOOLBAR,
    289312                        fill_color=style.COLOR_TRANSPARENT.get_svg(),