Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter@sugarlabs.org>2013-07-19 16:55:19 (GMT)
committer Walter Bender <walter@sugarlabs.org>2013-07-19 16:55:19 (GMT)
commit84db297f0ef771c69c67fb94c975ef052441725f (patch)
tree201b88decc6cee5c6337241611cf8a502b15612c
new project
-rw-r--r--activity.py179
-rw-r--r--activity/activity.info8
-rw-r--r--activity/activity.svg86
-rw-r--r--icons/image-save.svg88
4 files changed, 361 insertions, 0 deletions
diff --git a/activity.py b/activity.py
new file mode 100644
index 0000000..8c2c224
--- /dev/null
+++ b/activity.py
@@ -0,0 +1,179 @@
+# -*- coding: utf-8 -*-
+#Copyright (c) 2011-2013 Walter Bender
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# You should have received a copy of the GNU General Public License
+# along with this library; if not, write to the Free Software
+# Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
+
+import os
+import glob
+
+from sugar3.activity import activity
+from sugar3.graphics.toolbarbox import ToolbarBox
+from sugar3.activity.widgets import StopButton
+from sugar3.graphics.toolbutton import ToolButton
+from sugar3.activity.widgets import _create_activity_icon as ActivityIcon
+from sugar3.graphics.alert import NotifyAlert
+from sugar3.graphics import style
+from sugar3.datastore import datastore
+from sugar3 import profile
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GdkPixbuf
+from gi.repository import GObject
+
+from gettext import gettext as _
+
+MIME_TYPES = {'svg': 'image/svg+xml', 'png': 'image/png', 'gif': 'image/gif',
+ 'jpg': 'image/jpg'}
+
+
+class ClipArtActivity(activity.Activity):
+
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle, False)
+
+ self._selected_image = None
+ self.max_participants = 1
+
+ self.toolbar_box = ToolbarBox()
+ self.toolbar = self.toolbar_box.toolbar
+
+ activity_button = ToolButton()
+ icon = ActivityIcon(None)
+ activity_button.set_icon_widget(icon)
+ activity_button.set_tooltip(self.get_title())
+ stop_button = StopButton(self)
+
+ separator = Gtk.SeparatorToolItem()
+ separator.props.draw = False
+ separator.set_expand(True)
+
+ self.save_button = ToolButton('image-save')
+ self.save_button.set_tooltip(_('Save to Journal'))
+ self.save_button.connect('clicked', self._save_to_journal)
+ self.save_button.set_sensitive(False)
+
+ self.toolbar.insert(activity_button, 0)
+ self.toolbar.insert(Gtk.SeparatorToolItem(), -1)
+ self.toolbar.insert(self.save_button, -1)
+
+ self.toolbar.insert(separator, -1)
+ self.toolbar.insert(stop_button, -1)
+
+ artwork_paths = self._scan()
+
+ scrolled_window = Gtk.ScrolledWindow()
+ scrolled_window.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
+ scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
+ Gtk.PolicyType.AUTOMATIC)
+ self.set_canvas(scrolled_window)
+ scrolled_window.show()
+
+ store = Gtk.ListStore(GdkPixbuf.Pixbuf, str)
+
+ icon_view = Gtk.IconView.new_with_model(store)
+ icon_view.set_selection_mode(Gtk.SelectionMode.SINGLE)
+ icon_view.connect('selection-changed', self._clipart_selected,
+ store)
+ icon_view.set_pixbuf_column(0)
+ icon_view.grab_focus()
+ scrolled_window.add(icon_view)
+ icon_view.show()
+
+ self.set_toolbar_box(self.toolbar_box)
+ self.set_canvas(self.canvas)
+ self.show_all()
+
+ self._notify()
+ GObject.idle_add(fill_clipart_list, store, artwork_paths)
+
+ def _save_to_journal(self, widget):
+ if self._selected_image is None:
+ return
+
+ basename = os.path.basename(self._selected_image)
+ dsobject = datastore.create()
+ dsobject.metadata['title'] = basename[:-4]
+ dsobject.metadata['icon-color'] = profile.get_color().to_string()
+ dsobject.metadata['mime_type'] = MIME_TYPES[basename.split('.')[-1]]
+ dsobject.set_file_path(self._selected_image)
+ datastore.write(dsobject)
+ dsobject.destroy()
+
+ self.save_button.set_sensitive(False)
+
+ def _get_selected_path(self, widget, store):
+ try:
+ iter_ = store.get_iter(widget.get_selected_items()[0])
+ image_path = store.get(iter_, 1)[0]
+
+ return image_path, iter_
+ except:
+ return None
+
+ def _clipart_selected(self, widget, store):
+ selected = self._get_selected_path(widget, store)
+
+ if selected is None:
+ self._selected_image = None
+ self.save_button.set_sensitive(False)
+ return
+
+ image_path, _iter = selected
+ iter_ = store.get_iter(widget.get_selected_items()[0])
+ image_path = store.get(iter_, 1)[0]
+
+ self._selected_image = image_path
+ self.save_button.set_sensitive(True)
+
+ def _scan(self):
+ # We need a list of all the .png, .jpg, .gif, and .svg files
+ # in ~/Activities. We don't need to search Documents since
+ # that is already available through the Journal.
+ root_path = os.path.join(os.path.expanduser('~'), 'Activities')
+ artwork_paths = []
+ for suffix in ['.png', '.jpg', '.gif', '.svg']:
+ # Look in ~/Activities/* and ~/Activities/*/*
+ file_list = glob.glob(os.path.join(root_path, '*', '*' + suffix))
+ for f in file_list:
+ artwork_paths.append(f)
+ file_list = glob.glob(os.path.join(root_path, '*', '*',
+ '*' + suffix))
+ for f in file_list:
+ artwork_paths.append(f)
+ return artwork_paths
+
+ def _notify(self):
+ alert = NotifyAlert()
+ alert.props.title = _('Scanning for clipart')
+ msg = _('Please wait.')
+ alert.props.msg = msg
+
+ def remove_alert(alert, response_id):
+ self.remove_alert(alert)
+
+ alert.connect('response', remove_alert)
+ self.add_alert(alert)
+
+
+def fill_clipart_list(store, artwork_paths):
+ '''
+ Append images from the artwork_paths to the store.
+ '''
+ for filepath in artwork_paths:
+ pixbuf = None
+ try:
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
+ filepath, style.XLARGE_ICON_SIZE,
+ style.XLARGE_ICON_SIZE)
+ except:
+ pass
+ else:
+ store.append([pixbuf, filepath])
diff --git a/activity/activity.info b/activity/activity.info
new file mode 100644
index 0000000..6a1ce09
--- /dev/null
+++ b/activity/activity.info
@@ -0,0 +1,8 @@
+[Activity]
+name = ClipArt
+bundle_id = org.sugarlabs.ClipArt
+icon = activity
+exec = sugar-activity activity.ClipArtActivity
+show_launcher = yes
+activity_version = 1
+summary = displays available clipart that can be saved to the Sugar Journal
diff --git a/activity/activity.svg b/activity/activity.svg
new file mode 100644
index 0000000..e6a4c60
--- /dev/null
+++ b/activity/activity.svg
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY fill_color "#FFFFFF">
+ <!ENTITY stroke_color "#010101">
+]>
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="55"
+ height="55"
+ viewBox="0 0 55 55"
+ id="svg3059"
+ style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round">
+<g
+ transform="matrix(0.55205508,0,0,0.55205508,77.118464,18.235971)"
+ id="g4382"><g
+ transform="translate(-80.093659,12.220029)"
+ id="g4308"
+ style="fill:none;stroke:&stroke_color;;stroke-opacity:1">
+ <g
+ id="g4310"
+ style="fill:none;stroke:&stroke_color;;stroke-opacity:1">
+ <path
+ d="m 6.736,49.002 h 24.52 c 2.225,0 3.439,-1.447 3.439,-3.441 v -27.28 c 0,-1.73 -1.732,-3.441 -3.439,-3.441 h -4.389"
+ id="path4312"
+ style="fill:none;stroke:&stroke_color;;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ </g><g
+ transform="translate(-80.093659,12.220029)"
+ id="g4314"
+ style="fill:none;stroke:&stroke_color;;stroke-opacity:1">
+ <g
+ id="g4316"
+ style="fill:none;stroke:&stroke_color;;stroke-opacity:1">
+ <path
+ d="m 26.867,38.592 c 0,1.836 -1.345,3.201 -3.441,4.047 L 6.736,49.002 V 14.84 l 16.69,-8.599 c 2.228,-0.394 3.441,0.84 3.441,2.834 v 29.517 z"
+ id="path4318"
+ style="fill:none;stroke:&stroke_color;;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ </g><path
+ d="m -70.669659,54.827029 c 0,0 -1.351,-0.543 -2.702,-0.543 -1.351,0 -2.703,0.543 -2.703,0.543"
+ id="path4320"
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m -70.669659,44.226029 c 0,0 -1.239,-0.543 -2.815,-0.543 -1.577,0 -2.59,0.543 -2.59,0.543"
+ id="path4322"
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m -70.669659,33.898029 c 0,0 -1.125,-0.544 -2.927,-0.544 -1.802,0 -2.478,0.544 -2.478,0.544"
+ id="path4324"
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><line
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ x1="-66.884659"
+ x2="-66.884659"
+ y1="58.753029"
+ y2="23.725029"
+ id="line4326" /></g><g
+ transform="matrix(1.1623273,0,0,1.1623273,-14.422024,-12.63995)"
+ id="g3882"
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.15085721;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"><g
+ id="g3884"
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.15085721;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"><polygon
+ points="43.041,21.577 35.281,13.812 15.204,13.812 15.204,35.189 43.041,35.189 "
+ id="polygon3886"
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.15085721;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><polyline
+ id="polyline3888"
+ points="35.281,13.812 35.281,21.577 43.041,21.577 "
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.15085721;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g><path
+ d="m 19.426691,12.275117 c -4.727185,0 -8.666312,4.714399 -8.666312,4.714399 0,0 3.939127,4.737646 8.666312,4.735322 4.729509,-0.0046 8.668637,-4.739971 8.668637,-4.739971 0,0 -3.939128,-4.713237 -8.668637,-4.70975 z m 0,8.039818 c -1.830666,0 -3.314958,-1.484292 -3.314958,-3.31612 0,-1.827179 1.484292,-3.314958 3.314958,-3.314958 1.828341,0 3.312632,1.487779 3.312632,3.314958 0,1.831828 -1.484291,3.31612 -3.312632,3.31612 z"
+ id="path3890"
+ style="fill:&stroke_color;;fill-opacity:1;stroke:none;display:inline" /><circle
+ cx="29.207001"
+ cy="25.863001"
+ r="1.294"
+ transform="matrix(1.1623273,0,0,1.1623273,-14.520241,-13.061294)"
+ id="circle3892"
+ style="fill:&fill_color;;fill-opacity:1;stroke:&stroke_color;;stroke-opacity:1;display:inline" /><g
+ transform="matrix(1,0,0,-1,-24.850339,47.707501)"
+ id="g4770"><g
+ transform="translate(34.0803,-1006.42)"
+ id="g4772"><polyline
+ transform="matrix(-0.469241,0.469241,-0.469241,-0.469241,66.2906,1019.03)"
+ style="fill:none;stroke:&stroke_color;;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round"
+ points="51.562,15.306 41.17,16.188 42.053,5.794"
+ id="polyline4774" /><path
+ d="m 39.363241,1033.1291 -0.05636,9.9115 -8.750608,0.067"
+ id="path4776"
+ style="fill:none;stroke:&stroke_color;;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>
diff --git a/icons/image-save.svg b/icons/image-save.svg
new file mode 100644
index 0000000..26523e6
--- /dev/null
+++ b/icons/image-save.svg
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="55"
+ height="55"
+ viewBox="0 0 55 55"
+ id="svg2"
+ xml:space="preserve">
+<g
+ transform="matrix(0.55205508,0,0,0.55205508,77.118464,18.235971)"
+ id="g4382"><g
+ transform="translate(-80.093659,12.220029)"
+ id="g4308"
+ style="fill:none;stroke:#ffffff;stroke-opacity:1">
+ <g
+ id="g4310"
+ style="fill:none;stroke:#ffffff;stroke-opacity:1">
+ <path
+ d="m 6.736,49.002 h 24.52 c 2.225,0 3.439,-1.447 3.439,-3.441 v -27.28 c 0,-1.73 -1.732,-3.441 -3.439,-3.441 h -4.389"
+ id="path4312"
+ style="fill:none;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ </g><g
+ transform="translate(-80.093659,12.220029)"
+ id="g4314"
+ style="fill:none;stroke:#ffffff;stroke-opacity:1">
+ <g
+ id="g4316"
+ style="fill:none;stroke:#ffffff;stroke-opacity:1">
+ <path
+ d="m 26.867,38.592 c 0,1.836 -1.345,3.201 -3.441,4.047 L 6.736,49.002 V 14.84 l 16.69,-8.599 c 2.228,-0.394 3.441,0.84 3.441,2.834 v 29.517 z"
+ id="path4318"
+ style="fill:none;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ </g><path
+ d="m -70.669659,54.827029 c 0,0 -1.351,-0.543 -2.702,-0.543 -1.351,0 -2.703,0.543 -2.703,0.543"
+ id="path4320"
+ style="fill:none;stroke:#ffffff;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m -70.669659,44.226029 c 0,0 -1.239,-0.543 -2.815,-0.543 -1.577,0 -2.59,0.543 -2.59,0.543"
+ id="path4322"
+ style="fill:none;stroke:#ffffff;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><path
+ d="m -70.669659,33.898029 c 0,0 -1.125,-0.544 -2.927,-0.544 -1.802,0 -2.478,0.544 -2.478,0.544"
+ id="path4324"
+ style="fill:none;stroke:#ffffff;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /><line
+ style="fill:none;stroke:#ffffff;stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ x1="-66.884659"
+ x2="-66.884659"
+ y1="58.753029"
+ y2="23.725029"
+ id="line4326" /></g><g
+ transform="matrix(1.1623273,0,0,1.1623273,-14.422024,-12.63995)"
+ id="g3882"
+ style="fill:none;stroke:#ffffff;stroke-width:2.15085721;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"><g
+ id="g3884"
+ style="fill:none;stroke:#ffffff;stroke-width:2.15085721;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"><polygon
+ points="43.041,21.577 35.281,13.812 15.204,13.812 15.204,35.189 43.041,35.189 "
+ id="polygon3886"
+ style="fill:none;stroke:#ffffff;stroke-width:2.15085721;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><polyline
+ id="polyline3888"
+ points="35.281,13.812 35.281,21.577 43.041,21.577 "
+ style="fill:none;stroke:#ffffff;stroke-width:2.15085721;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g><path
+ d="m 19.426691,12.275117 c -4.727185,0 -8.666312,4.714399 -8.666312,4.714399 0,0 3.939127,4.737646 8.666312,4.735322 4.729509,-0.0046 8.668637,-4.739971 8.668637,-4.739971 0,0 -3.939128,-4.713237 -8.668637,-4.70975 z m 0,8.039818 c -1.830666,0 -3.314958,-1.484292 -3.314958,-3.31612 0,-1.827179 1.484292,-3.314958 3.314958,-3.314958 1.828341,0 3.312632,1.487779 3.312632,3.314958 0,1.831828 -1.484291,3.31612 -3.312632,3.31612 z"
+ id="path3890"
+ style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" /><circle
+ cx="29.207001"
+ cy="25.863001"
+ r="1.294"
+ transform="matrix(1.1623273,0,0,1.1623273,-14.520241,-13.061294)"
+ id="circle3892"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;display:inline" /><g
+ transform="matrix(1,0,0,-1,-24.850339,47.707501)"
+ id="g4770"><g
+ transform="translate(34.0803,-1006.42)"
+ id="g4772"><polyline
+ transform="matrix(-0.469241,0.469241,-0.469241,-0.469241,66.2906,1019.03)"
+ style="fill:none;stroke:#ffffff;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round"
+ points="51.562,15.306 41.17,16.188 42.053,5.794"
+ id="polyline4774" /><path
+ d="m 39.363241,1033.1291 -0.05636,9.9115 -8.750608,0.067"
+ id="path4776"
+ style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></g></svg>