diff options
Diffstat (limited to 'trunk/dimbola/plugins/photoviewer_plugin.py')
-rw-r--r-- | trunk/dimbola/plugins/photoviewer_plugin.py | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/trunk/dimbola/plugins/photoviewer_plugin.py b/trunk/dimbola/plugins/photoviewer_plugin.py new file mode 100644 index 0000000..45ce81c --- /dev/null +++ b/trunk/dimbola/plugins/photoviewer_plugin.py @@ -0,0 +1,214 @@ +# 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 os + +import gtk + +import dimbola + + +class PhotoViewerBase(object): + + '''Display the currently selected photo in full size. + + This is a base class, from which will be derived two other classes, + one for showing photos in a tab, the other in a separate toplevel + window. + + ''' + + def __init__(self, mwc): + self.mwc = mwc + + self.photoid = None + + mwc.connect('setup-widgets', self.setup_widgets) + mwc.connect('photo-meta-changed', lambda *args: self.draw_photo()) + + def remember_photo(self, model): + if len(model.selected) == 1: + self.photoid = model.selected[0] + else: + self.photoid = None + self.draw_photo() + + def draw_photo(self): + w = self.widget.window + if w is None: + return + w.clear() + width, height = w.get_size() + style = self.widget.get_style() + if self.widget.flags() & gtk.HAS_FOCUS: + self.widget.get_style().paint_focus(w, + self.widget.state, + None, + None, + None, + 0, 0, + width, height) + fg = style.fg_gc[gtk.STATE_NORMAL] + with self.mwc.db: + preview = self.mwc.db.get_preview(self.photoid) + a, b, c, rotate = \ + self.mwc.db.get_basic_photo_metadata(self.photoid) + if preview is not None: + pixbuf = dimbola.image_data_to_pixbuf(preview) + pixbuf = dimbola.rotate_pixbuf(pixbuf, rotate) + pixbuf = dimbola.scale_pixbuf(pixbuf, width, height) + x = (width - pixbuf.get_width()) / 2 + y = (height - pixbuf.get_height()) / 2 + w.draw_pixbuf(fg, pixbuf, 0, 0, x, y) + + def request_rating(self, stars): + self.mwc.emit('photo-rating-requested', stars) + + def key_press_event(self, event): + if event.type == gtk.gdk.KEY_PRESS: + bindings = { + '0': lambda *args: self.request_rating(0), + '1': lambda *args: self.request_rating(1), + '2': lambda *args: self.request_rating(2), + '3': lambda *args: self.request_rating(3), + '4': lambda *args: self.request_rating(4), + '5': lambda *args: self.request_rating(5), + } + if event.keyval in bindings: + bindings[event.keyval]() + return True + elif event.string in bindings: + bindings[event.string]() + return True + return False + + +class PhotoViewerNotebook(PhotoViewerBase, dimbola.Plugin): + + '''Display the currently selected photo in full size, in notebook.''' + + def enable(self): + pass + + def disable(self): + pass + + def setup_widgets(self, mwc): + self.widget = mwc.widgets['photo_drawingarea'] + self.box = mwc.widgets['photo_vbox'] + mwc.grid.model.connect('selection-changed', self.remember_photo) + + def on_photo_drawingarea_expose_event(self, *args): + self.draw_photo() + + def on_photo_previous_button_clicked(self, *args): + self.mwc.grid.model.select_previous() + + def on_photo_next_button_clicked(self, *args): + self.mwc.grid.model.select_next() + + def on_view_photo_menuitem_activate(self, radio): + if radio.get_active(): + self.box.show() + self.widget.grab_focus() + else: + self.box.hide() + + def on_photo_drawingarea_key_press_event(self, widget, event): + return self.key_press_event(event) + + def on_photo_drawingarea_button_press_event(self, widget, event): + widget.grab_focus() + return False + + +class PhotoViewerWindow(PhotoViewerBase, dimbola.Plugin): + + '''Like PhotoViewerNotebook, but use a separate window.''' + + def enable(self): + self.mwc.add_to_menu('photo_menu', 'photowin_menuitem', + 'View photo in separate window', + check=True) + self.menuitem = self.mwc.widgets['photowin_menuitem'] + + def disable(self): + self.mwc.remove_from_menu('photo_menu', 'photowin_menuitem') + self.menuitem = None + + def setup_widgets(self, mwc): + self.widget = mwc.widgets['photowin_drawingarea'] + self.window = mwc.widgets['photo_window'] + self.fullscreen_button = mwc.widgets['fullscreen_button'] + self.unfullscreen_button = mwc.widgets['unfullscreen_button'] + self.widget = mwc.widgets['photowin_drawingarea'] + mwc.grid.model.connect('selection-changed', self.remember_photo) + + def on_photowin_menuitem_activate(self, menuitem): + if menuitem.get_active(): + self.window.show() + else: + self.window.hide() + + def on_photowin_drawingarea_expose_event(self, *args): + self.draw_photo() + + def on_photo_window_delete_event(self, *args): + self.menuitem.set_active(False) + self.window.hide() + return True + + def on_fullscreen_button_clicked(self, *args): + self.window.fullscreen() + self.fullscreen_button.hide() + self.unfullscreen_button.show() + + def on_unfullscreen_button_clicked(self, *args): + self.window.unfullscreen() + self.unfullscreen_button.hide() + self.fullscreen_button.show() + + def on_photowin_previous_button_clicked(self, *args): + self.mwc.grid.model.select_previous() + + def on_photowin_next_button_clicked(self, *args): + self.mwc.grid.model.select_next() + + def on_photowin_drawingarea_key_press_event(self, widget, event): + + bindings = { + gtk.keysyms.Escape: self.on_unfullscreen_button_clicked, + } + + if event.type == gtk.gdk.KEY_PRESS: + if event.keyval == gtk.keysyms.Escape: + self.on_unfullscreen_button_clicked() + return True + elif (event.keyval == gtk.keysyms.w and + event.state & gtk.gdk.CONTROL_MASK): + self.on_photo_window_delete_event() + return True + return self.key_press_event(event) + + def on_photowin_drawingarea_button_press_event(self, widget, event): + widget.grab_focus() + return False + |