diff options
author | C. Neves <cn@sueste.net> | 2007-11-07 14:06:33 (GMT) |
---|---|---|
committer | C. Neves <cn@sueste.net> | 2007-11-07 14:06:33 (GMT) |
commit | ddb53471b4e7dc1d19235672f3080cdc0afb1cf4 (patch) | |
tree | b59338ca3be272ee90a0595e58a664f44ead1067 /mmm_modules/image_category.py | |
parent | 394128551fdb03004846c75c3d5b0176dd9bd3a4 (diff) |
Removed a little kungfu I had with soft links. This adds some files redundant between my activities but makes it able to build on jhbuild.
Diffstat (limited to 'mmm_modules/image_category.py')
-rw-r--r-- | mmm_modules/image_category.py | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/mmm_modules/image_category.py b/mmm_modules/image_category.py new file mode 100644 index 0000000..9181436 --- /dev/null +++ b/mmm_modules/image_category.py @@ -0,0 +1,445 @@ +import pygtk +pygtk.require('2.0') +import gtk, gobject + +import os +from glob import glob +import logging +import md5 + +from sugar.graphics.objectchooser import ObjectChooser + +from borderframe import BorderFrame +from utils import load_image, resize_image, RESIZE_CUT + +cwd = os.path.normpath(os.path.join(os.path.split(__file__)[0], '..')) + +if os.path.exists(os.path.join(cwd, 'mamamedia_icons')): + # Local, no shared code, version + mmmpath = cwd + iconpath = os.path.join(mmmpath, 'mamamedia_icons') +else: + propfile = os.path.expanduser("~/.sugar/default/org.worldwideworkshop.olpc.MMMPath") + + if os.path.exists(propfile): + mmmpath = file(propfile, 'rb').read() + else: + mmmpath = cwd + iconpath = os.path.join(mmmpath, 'icons') + + +from gettext import gettext as _ + +THUMB_SIZE = 48 +IMAGE_SIZE = 200 +#MYOWNPIC_FOLDER = os.path.expanduser("~/.sugar/default/org.worldwideworkshop.olpc.MyOwnPictures") + +def prepare_btn (btn): + return btn + +def register_category (pixbuf_class, path): + pass + +class CategoryDirectory (object): + def __init__ (self, path, width=-1, height=-1, method=RESIZE_CUT): + self.path = path + self.method = method + self.pb = None + if os.path.isdir(path): + self.gather_images() + else: + self.images = [path] + self.set_thumb_size(THUMB_SIZE, THUMB_SIZE) + self.set_image_size(width, height) + self.filename = None + self.name = os.path.basename(path) + + def gather_images (self): + """ Lists all images in the selected path as per the wildcard expansion of 'image_*'. + Adds all linked images from files (*.lnk) """ + self.images = [] + links = glob(os.path.join(self.path, "*.lnk")) + for link in links: + fpath = file(link).readlines()[0].strip() + if os.path.isfile(fpath) and not (fpath in self.images): + self.images.append(fpath) + else: + os.remove(link) + self.images.extend(glob(os.path.join(self.path, "image_*"))) + self.images.sort() + + def set_image_size (self, w, h): + self.width = w + self.height = h + + def set_thumb_size (self, w, h): + self.twidth = w + self.theight = h + self.thumb = self._get_category_thumb() + + def get_image (self, name): + if not len(self.images) or name is None or name not in self.images: + return None + self.pb = load_image(name) + if self.pb is not None: + rv = resize_image(self.pb, self.width, self.height, method=self.method) + self.filename = name + return rv + return None + + def get_next_image (self): + if not len(self.images): + return None + if self.filename is None or self.filename not in self.images: + pos = -1 + else: + pos = self.images.index(self.filename) + pos += 1 + if pos >= len(self.images): + pos = 0 + return self.get_image(self.images[pos]) + + def get_previous_image (self): + if not len(self.images): + return None + if self.filename is None or self.filename not in self.images: + pos = len(self.images) + else: + pos = self.images.index(self.filename) + pos -= 1 + if pos < 0: + pos = len(self.images) - 1 + return self.get_image(self.images[pos]) + + def has_images (self): + print ("IMG", self.images) + return len(self.images) > 0 + + def count_images (self): + return len(self.images) + + def has_image (self): + return self.pb is not None + + def _get_category_thumb (self): + if os.path.isdir(self.path): + thumbs = glob(os.path.join(self.path, "thumb.*")) + thumbs.extend(glob(os.path.join(self.path, "default_thumb.*"))) + thumbs.extend(glob(os.path.join(mmmpath, "mmm_images","default_thumb.*"))) + print thumbs + thumbs = filter(lambda x: os.path.exists(x), thumbs) + thumbs.append(None) + else: + thumbs = [self.path] + print (self.path, thumbs) + return load_image(thumbs[0], self.twidth, self.theight) + + +class ImageSelectorWidget (gtk.Table): + __gsignals__ = {'category_press' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), + 'image_press' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),} + + def __init__ (self, + width=IMAGE_SIZE, + height=IMAGE_SIZE, + frame_color=None, + prepare_btn_cb=prepare_btn, + method=RESIZE_CUT, + image_dir=None): + gtk.Table.__init__(self, 2,5,False) + self._signals = [] + self.width = width + self.height = height + self.image = gtk.Image() + self.method = method + #self.set_myownpath(MYOWNPIC_FOLDER) + img_box = BorderFrame(border_color=frame_color) + img_box.add(self.image) + img_box.set_border_width(5) + self._signals.append((img_box, img_box.connect('button_press_event', self.emit_image_pressed))) + self.attach(img_box, 0,5,0,1,0,0) + self.attach(gtk.Label(), 0,1,1,2) + self.bl = gtk.Button() + + il = gtk.Image() + il.set_from_pixbuf(load_image(os.path.join(iconpath, 'arrow_left.png'))) + self.bl.set_image(il) + + self.bl.connect('clicked', self.previous) + self.attach(prepare_btn_cb(self.bl), 1,2,1,2,0,0) + + cteb = gtk.EventBox() + self.cat_thumb = gtk.Image() + self.cat_thumb.set_size_request(THUMB_SIZE, THUMB_SIZE) + cteb.add(self.cat_thumb) + self._signals.append((cteb, cteb.connect('button_press_event', self.emit_cat_pressed))) + self.attach(cteb, 2,3,1,2,0,0,xpadding=10) + + self.br = gtk.Button() + ir = gtk.Image() + ir.set_from_pixbuf(load_image(os.path.join(iconpath,'arrow_right.png'))) + self.br.set_image(ir) + self.br.connect('clicked', self.next) + self.attach(prepare_btn_cb(self.br), 3,4,1,2,0,0) + self.attach(gtk.Label(),4,5,1,2) + self.filename = None + self.show_all() + self.image.set_size_request(width, height) + if image_dir is None: + image_dir = os.path.join(mmmpath, "mmm_images") + self.set_image_dir(image_dir) + + def add_image (self, *args):#widget=None, response=None, *args): + """ Use to trigger and process the My Own Image selector. """ + + chooser = ObjectChooser(_('Choose image'), None, #self._parent, + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) + try: + result = chooser.run() + if result == gtk.RESPONSE_ACCEPT: + jobject = chooser.get_selected_object() + if jobject and jobject.file_path: + if self.load_image(str(jobject.file_path), True): + pass + else: + err = gtk.MessageDialog(self._parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, + _("Not a valid image file")) + err.run() + err.destroy() + return + finally: + chooser.destroy() + del chooser + + + #print (widget,response,args) + #if response is None: + # # My Own Image selector + # imgfilter = gtk.FileFilter() + # imgfilter.set_name(_("Image Files")) + # imgfilter.add_mime_type('image/*') + # fd = gtk.FileChooserDialog(title=_("Select Image File"), parent=None, + # action=gtk.FILE_CHOOSER_ACTION_OPEN, + # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) + # + # fd.set_current_folder(os.path.expanduser("~/")) + # fd.set_modal(True) + # fd.add_filter(imgfilter) + # fd.connect("response", self.add_image) + # fd.resize(800,600) + # fd.show() + #else: + # if response == gtk.RESPONSE_ACCEPT: + # if self.load_image(widget.get_filename()): + # pass + # #self.do_shuffle() + # else: + # err = gtk.MessageDialog(self._parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, + # _("Not a valid image file")) + # err.run() + # err.destroy() + # return + # widget.destroy() + + def set_readonly (self, ro=True): + if ro: + self.bl.hide() + self.br.hide() + for w, s in self._signals: + w.handler_block(s) + + #def set_myownpath (self, path): + # """ Sets the path to My Own Pictures storage, so we know where to add links to new pictures """ + # if path is None: + # self.myownpath = None + # else: + # if not os.path.exists(path): + # os.mkdir(path) + # self.myownpath = path + + #def is_myownpath (self): + # """ Checks current path against the set custom image path """ + # return self.myownpath == self.category.path + # + #def gather_myownpath_images(self): + # """ """ + # rv = [] + # self.images = [] + # links = glob(os.path.join(self.myownpath, "*.lnk")) + # for link in links: + # linfo = filter(None, map(lambda x: x.strip(), file(link).readlines())) + # fpath = linfo[0] + # if os.path.isfile(fpath) and not (fpath in self.images): + # self.images.append(fpath) + # if len(linfo) > 1: + # digest = linfo[1] + # else: + # digest = md5.new(file(fpath, 'rb').read()).hexdigest() + # rv.append((link, fpath, digest)) + # for fpath in glob(os.path.join(self.myownpath, "image_*")): + # digest = md5.new(file(fpath, 'rb').read()).hexdigest() + # rv.append((fpath, fpath, digest)) + # return rv + + def emit_cat_pressed (self, *args): + self.emit('category_press') + return True + + def emit_image_pressed (self, *args): + self.emit('image_press') + return True + + def has_image (self): + return self.category.has_image() + + def get_category_name (self): + return self.category.name + + def get_filename (self): + return self.category.filename + + def get_image (self): + return self.category.pb + + def next (self, *args, **kwargs): + pb = self.category.get_next_image() + if pb is not None: + self.image.set_from_pixbuf(pb) + + def previous (self, *args, **kwargs): + pb = self.category.get_previous_image() + if pb is not None: + self.image.set_from_pixbuf(pb) + + def get_image_dir (self): + return self.category.path + + def set_image_dir (self, directory): + if os.path.exists(directory) and not os.path.isdir(directory): + filename = directory + directory = os.path.dirname(directory) + logging.debug("dir=%s, filename=%s" % (directory, filename)) + else: + logging.debug("dir=%s" % (directory)) + filename = None + self.category = CategoryDirectory(directory, self.width, self.height, self.method) + self.cat_thumb.set_from_pixbuf(self.category.thumb) + if filename: + self.image.set_from_pixbuf(self.category.get_image(filename)) + else: + if self.category.has_images(): + self.next() + + def load_image(self, filename, fromJournal=False): + """ Loads an image from the file """ + #if self.myownpath is not None and os.path.isdir(self.myownpath) and not fromJournal: + # name = os.path.splitext(os.path.basename(filename))[0] + # while os.path.exists(os.path.join(self.myownpath, '%s.lnk' % name)): + # name = name + '_' + # f = file(os.path.join(self.myownpath, '%s.lnk' % name), 'w') + # f.write(filename) + # image_digest = md5.new(file(filename, 'rb').read()).hexdigest() + # f.write('\n%s' % image_digest) + # f.close() + # self.category = CategoryDirectory(self.myownpath, self.width, self.height, method=self.method) + # self.image.set_from_pixbuf(self.category.get_image(filename)) + #else: + self.category = CategoryDirectory(filename, self.width, self.height, method=self.method) + self.next() + self.cat_thumb.set_from_pixbuf(self.category.thumb) + return self.image.get_pixbuf() is not None + + def load_pb (self, pb): + self.category.pb = pb + self.image.set_from_pixbuf(resize_image(pb, self.width, self.height, method=self.method)) + + #def set_game_widget(self, game_widget): + # if self.has_image(): + # game_widget.load_image(self.get_filename()) + + def _freeze (self): + """ returns a json writable object representation capable of being used to restore our current status """ + return {'image_dir': self.get_image_dir(), + 'filename': self.get_filename()} + + def _thaw (self, obj): + """ retrieves a frozen status from a python object, as per _freeze """ + self.set_image_dir(obj.get('image_dir', None)) + self.image.set_from_pixbuf(self.category.get_image(obj.get('filename', None))) + +class CategorySelector (gtk.ScrolledWindow): + __gsignals__ = {'selected' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str,))} + + def __init__ (self, title=None, selected_category_path=None, path=None, extra=()): + gtk.ScrolledWindow.__init__ (self) + self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + if path is None: + path = os.path.join(mmmpath, 'mmm_images') + self.path = path + self.thumbs = [] + model, selected = self.get_model(path, selected_category_path, extra) + self.ignore_first = selected is not None + + self.treeview = gtk.TreeView() + col = gtk.TreeViewColumn(title) + r1 = gtk.CellRendererPixbuf() + r2 = gtk.CellRendererText() + col.pack_start(r1, False) + col.pack_start(r2, True) + col.set_cell_data_func(r1, self.cell_pb) + col.set_attributes(r2, text=1) + self.treeview.append_column(col) + self.treeview.set_model(model) + + self.add(self.treeview) + self.show_all() + if selected is not None: + self.treeview.get_selection().select_path(selected) + self.treeview.connect("cursor-changed", self.do_select) + + def grab_focus (self): + self.treeview.grab_focus() + + def cell_pb (self, tvcolumn, cell, model, it): + # Renders a pixbuf stored in the thumbs cache + cell.set_property('pixbuf', self.thumbs[model.get_value(it, 2)]) + + def get_pb (self, path): + thumbs = glob(os.path.join(path, "thumb.*")) + thumbs.extend(glob(os.path.join(self.path, "default_thumb.*"))) + thumbs = filter(lambda x: os.path.exists(x), thumbs) + thumbs.append(None) + return load_image(thumbs[0], THUMB_SIZE, THUMB_SIZE) + + def get_model (self, path, selected_path, extra): + # Each row is (path/dirname, pretty name, 0 based index) + selected = None + store = gtk.ListStore(str, str, int) + store.set_sort_column_id(1, gtk.SORT_ASCENDING) + files = [os.path.join(path, x) for x in os.listdir(path) if not x.startswith('.')] + files.extend(extra) + for fullpath, prettyname in [(x, _(os.path.basename(x))) for x in files if os.path.isdir(x)]: + count = CategoryDirectory(fullpath).count_images() + print (fullpath, prettyname, count) + store.append([fullpath, prettyname + (" (%i)" % count), len(self.thumbs)]) + self.thumbs.append(self.get_pb(fullpath)) + #if os.path.isdir(MYOWNPIC_FOLDER): + # count = CategoryDirectory(MYOWNPIC_FOLDER).count_images() + # store.append([MYOWNPIC_FOLDER, _("My Pictures") + (" (%i)" % count), len(self.thumbs)]) + # self.thumbs.append(self.get_pb(MYOWNPIC_FOLDER)) + + i = store.get_iter_first() + while i: + if selected_path == store.get_value(i, 0): + selected = store.get_path(i) + break + i = store.iter_next(i) + return store, selected + + def do_select (self, tree, *args, **kwargs): + if self.ignore_first: + self.ignore_first = False + else: + tv, it = tree.get_selection().get_selected() + self.emit("selected", tv.get_value(it,0)) + |