diff options
Diffstat (limited to 'trunk/dimbola/plugins/search_plugin.py')
-rw-r--r-- | trunk/dimbola/plugins/search_plugin.py | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/trunk/dimbola/plugins/search_plugin.py b/trunk/dimbola/plugins/search_plugin.py new file mode 100644 index 0000000..95abe8c --- /dev/null +++ b/trunk/dimbola/plugins/search_plugin.py @@ -0,0 +1,181 @@ +# Copyright (C) 2009 Lars Wirzenius <liw@liw.fi> +# +# 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 <http://www.gnu.org/licenses/>. + + +# 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() + |