# Copyright (C) 2009 Lars Wirzenius # # 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # This is necessary for running under Python 2.5, which we need to # do on Debian, for now. from __future__ import with_statement import gtk import pango import dimbola class Search(dimbola.Plugin): '''Search for photos in the currently selected folders.''' def __init__(self, mwc): self.mwc = mwc mwc.connect('setup-widgets', self.setup_widgets) self.tagids = set() self.photoids = list() def setup_widgets(self, mwc): self.textview = mwc.widgets['searchtags_textview'] self.popup = mwc.widgets['searchtags_textview_popup'] self.remove_menuitem = mwc.widgets['remove_search_tag_menuitem'] self.taglist = dimbola.Taglist(self.textview, self.popup, self.prepare_popup) stars = ('one_star', 'two_stars', 'three_stars', 'four_stars', 'five_stars') for n, x in enumerate(stars): w = mwc.widgets['search_%s_drawingarea' % x] height = w.get_style().font_desc.get_size() pixels = max(height / pango.SCALE, 5) w.set_size_request(pixels * (n+1), pixels) def enable(self): self.mwc.add_to_sidebar('left_sidebar', 'search_expander', weight=dimbola.MAX_WEIGHT) self.enable_signal(self.mwc, 'folder-selection-changed', self.folder_selection_changed) self.enable_signal(self.mwc, 'tagtree-changed', lambda *args: self.refresh_tags()) def disable(self): self.mwc.remove_from_sidebar('left_sidebar', 'search_expander') self.disable_signals() def refresh_tags(self): with self.mwc.db: tags = [] for tagid in self.tagids: tagname = self.mwc.db.get_tagname(tagid) if tagname is not None: tags.append((tagname, tagid)) tags.sort() self.taglist.set_tags(0, [(y, x) for x, y in tags]) def prepare_popup(self): self.remove_menuitem.set_sensitive( self.taglist.buf.get_has_selection()) def draw_stars(self, n_stars, drawingarea): gc = drawingarea.get_style().fg_gc[drawingarea.state] dim = drawingarea.window.get_size()[1] dimbola.draw_stars(n_stars, drawingarea.window, gc, 0, 0, dim) def on_search_one_star_drawingarea_expose_event(self, widget, event): self.draw_stars(1, widget) def on_search_two_stars_drawingarea_expose_event(self, widget, event): self.draw_stars(2, widget) def on_search_three_stars_drawingarea_expose_event(self, widget, event): self.draw_stars(3, widget) def on_search_four_stars_drawingarea_expose_event(self, widget, event): self.draw_stars(4, widget) def on_search_five_stars_drawingarea_expose_event(self, widget, event): self.draw_stars(5, widget) def on_searchtags_textview_button_press_event(self, widget, event): return self.taglist.button_press_event(widget, event) def on_remove_search_tag_menuitem_activate(self, *args): photoid, tagid = self.taglist.selected_tag() if tagid in self.tagids: self.tagids.remove(tagid) self.refresh_tags() self.search_photos() def on_searchtags_textview_drag_motion(self, *args): return self.taglist.drag_motion(*args) def on_searchtags_textview_drag_leave(self, *args): return self.taglist.drag_leave(*args) def on_searchtags_textview_drag_data_received(self, *args): tagids = self.taglist.drag_data_received(*args) for tagid in tagids: self.tagids.add(tagid) self.refresh_tags() self.search_photos() def select_on_stars(self, photoids, stars_set): with self.mwc.db: for photoid in photoids[:]: a, b, rating, d = self.mwc.db.get_basic_photo_metadata(photoid) if rating not in stars_set: photoids.remove(photoid) return photoids def select_on_tags(self, photoids, tagids): with self.mwc.db: for photoid in photoids[:]: photo_tagids = set(self.mwc.db.get_tagids(photoid)) if not photo_tagids.issuperset(tagids): photoids.remove(photoid) return photoids def on_no_stars_checkbutton_toggled(self, button): self.search_photos() on_one_star_checkbutton_toggled = on_no_stars_checkbutton_toggled on_two_stars_checkbutton_toggled = on_no_stars_checkbutton_toggled on_three_stars_checkbutton_toggled = on_no_stars_checkbutton_toggled on_four_stars_checkbutton_toggled = on_no_stars_checkbutton_toggled on_five_stars_checkbutton_toggled = on_no_stars_checkbutton_toggled def search_photos(self): '''Set grid's list of photoids to matches for current search.''' if self.mwc.db is None: return photoids = self.photoids[:] buttons = ( ('no_stars_checkbutton', 0), ('one_star_checkbutton', 1), ('two_stars_checkbutton', 2), ('three_stars_checkbutton', 3), ('four_stars_checkbutton', 4), ('five_stars_checkbutton', 5), ) stars_set = set() for name, stars in buttons: w = self.mwc.widgets[name] if w.get_active(): stars_set.add(stars) if not stars_set: stars_set = set(range(6)) photoids = self.select_on_stars(photoids, stars_set) photoids = self.select_on_tags(photoids, self.tagids) self.mwc.grid.model.photoids = list(photoids) self.mwc.load_thumbnails_from_database() def folder_selection_changed(self, mwc, folderids, photoids): self.photoids = photoids self.search_photos()