summaryrefslogtreecommitdiff
path: root/trunk/dimbola/plugins/photoviewer_plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/dimbola/plugins/photoviewer_plugin.py')
-rw-r--r--trunk/dimbola/plugins/photoviewer_plugin.py214
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
+