# 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 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