summaryrefslogtreecommitdiff
path: root/rapid/rapid.py
diff options
context:
space:
mode:
Diffstat (limited to 'rapid/rapid.py')
-rwxr-xr-xrapid/rapid.py171
1 files changed, 136 insertions, 35 deletions
diff --git a/rapid/rapid.py b/rapid/rapid.py
index ded7324..a69b80a 100755
--- a/rapid/rapid.py
+++ b/rapid/rapid.py
@@ -61,12 +61,10 @@ from optparse import OptionParser
import pynotify
-import ValidatedEntry
-
import idletube as tube
import config
-from config import MAX_THUMBNAIL_SIZE
+
from config import STATUS_CANNOT_DOWNLOAD, STATUS_DOWNLOADED, \
STATUS_DOWNLOADED_WITH_WARNING, \
STATUS_DOWNLOAD_FAILED, \
@@ -75,7 +73,7 @@ from config import STATUS_CANNOT_DOWNLOAD, STATUS_DOWNLOADED, \
STATUS_NOT_DOWNLOADED, \
STATUS_DOWNLOAD_AND_BACKUP_FAILED, \
STATUS_WARNING
-
+
import common
import misc
import higdefaults as hd
@@ -84,6 +82,8 @@ from media import getDefaultPhotoLocation, getDefaultVideoLocation, \
getDefaultBackupPhotoIdentifier, \
getDefaultBackupVideoIdentifier
+import ValidatedEntry
+
from media import CardMedia
import media
@@ -123,7 +123,8 @@ _ = Configi18n._
#Translators: if neccessary, for guidance in how to translate this program, you may see http://damonlynch.net/translate.html
PROGRAM_NAME = _('Rapid Photo Downloader')
-
+TINY_SCREEN = gtk.gdk.screen_height() <= config.TINY_SCREEN_HEIGHT
+#~ TINY_SCREEN = True
def today():
return datetime.date.today().strftime('%Y-%m-%d')
@@ -407,6 +408,11 @@ class ThreadManager:
workers = ThreadManager()
class RapidPreferences(prefs.Preferences):
+ if TINY_SCREEN:
+ zoom = 120
+ else:
+ zoom = config.MIN_THUMBNAIL_SIZE * 2
+
defaults = {
"program_version": prefs.Value(prefs.STRING, ""),
"download_folder": prefs.Value(prefs.STRING,
@@ -465,6 +471,7 @@ class RapidPreferences(prefs.Preferences):
"main_window_size_y": prefs.Value(prefs.INT, 0),
"main_window_maximized": prefs.Value(prefs.INT, 0),
"show_warning_downloading_from_camera": prefs.Value(prefs.BOOL, True),
+ "preview_zoom": prefs.Value(prefs.INT, zoom),
}
def __init__(self):
@@ -1843,12 +1850,8 @@ class CopyPhotos(Thread):
# load images to display for when a thumbnail cannot be extracted or created
- if DROP_SHADOW:
- self.photoThumbnail = gtk.gdk.pixbuf_new_from_file(paths.share_dir('glade3/photo_shadow.png'))
- self.videoThumbnail = gtk.gdk.pixbuf_new_from_file(paths.share_dir('glade3/video_shadow.png'))
- else:
- self.photoThumbnail = gtk.gdk.pixbuf_new_from_file(paths.share_dir('glade3/photo.png'))
- self.videoThumbnail = gtk.gdk.pixbuf_new_from_file(paths.share_dir('glade3/video.png'))
+ self.photoThumbnail = gtk.gdk.pixbuf_new_from_file(paths.share_dir('glade3/photo.png'))
+ self.videoThumbnail = gtk.gdk.pixbuf_new_from_file(paths.share_dir('glade3/video.png'))
imageRenameUsesJobCode = rn.usesJobCode(self.prefs.image_rename)
imageSubfolderUsesJobCode = rn.usesJobCode(self.prefs.subfolder)
@@ -3603,7 +3606,6 @@ class SelectionTreeView(gtk.TreeView):
if DROP_SHADOW:
self.iconDropShadow = DropShadow(offset=(3,3), shadow = (0x34, 0x34, 0x34, 0xff), border=6)
- self.previewDropShadow = DropShadow(shadow = (0x44, 0x44, 0x44, 0xff), trim_border = True)
self.previewed_file_treerowref = None
self.icontheme = gtk.icon_theme_get_default()
@@ -3732,7 +3734,8 @@ class SelectionTreeView(gtk.TreeView):
name = mediaFile.name
size = mediaFile.size
thumbnail = mediaFile.thumbnail
- thumbnail_icon = common.scale2pixbuf(60, 36, mediaFile.thumbnail)
+ thumbnail_icon = common.scale2pixbuf(60, 36, thumbnail)
+ #thumbnail_icon = common.scale2pixbuf(80, 48, mediaFile.thumbnail)
if DROP_SHADOW:
if not mediaFile.genericThumbnail:
pil_image = pixbuf_to_image(thumbnail_icon)
@@ -4020,12 +4023,8 @@ class SelectionTreeView(gtk.TreeView):
self.previewed_file_treerowref = mediaFile.treerowref
- thumbnail = mediaFile.thumbnail
-
- if DROP_SHADOW and not mediaFile.genericThumbnail:
- pil_image = pixbuf_to_image(thumbnail)
- pil_image = self.previewDropShadow.dropShadow(pil_image)
- thumbnail = image_to_pixbuf(pil_image)
+ self.parentApp.set_base_preview_image(mediaFile.thumbnail)
+ thumbnail = self.parentApp.scaledPreviewImage()
self.parentApp.preview_image.set_from_pixbuf(thumbnail)
@@ -4329,7 +4328,9 @@ class SelectionVBox(gtk.VBox):
gtk.VBox.__init__(self)
self.parentApp = parentApp
- tiny_screen = gtk.gdk.screen_height() <= config.TINY_SCREEN_HEIGHT
+ tiny_screen = TINY_SCREEN
+ if tiny_screen:
+ config.max_thumbnail_size = 160
selection_scrolledwindow = gtk.ScrolledWindow()
selection_scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
@@ -4351,23 +4352,49 @@ class SelectionVBox(gtk.VBox):
#selection_scrolledwindow.set_size_request(350, -1)
- #Preview pane
+ # Preview pane
+
+ # Zoom in and out slider (make the image bigger / smaller)
+
+ # Zoom out (on the left of the slider)
+ self.zoom_out_eventbox = gtk.EventBox()
+ self.zoom_out_eventbox.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.zoom_out_image = gtk.Image()
+ self.zoom_out_image.set_from_file(paths.share_dir('glade3/zoom-out.png'))
+ self.zoom_out_eventbox.add(self.zoom_out_image)
+ self.zoom_out_eventbox.connect("button_press_event", self.zoom_out_0_callback)
+
+ # Zoom in (on the right of the slider)
+ self.zoom_in_eventbox = gtk.EventBox()
+ self.zoom_in_eventbox.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self.zoom_in_image = gtk.Image()
+ self.zoom_in_image.set_from_file(paths.share_dir('glade3/zoom-in.png'))
+ self.zoom_in_eventbox.add(self.zoom_in_image)
+ self.zoom_in_eventbox.connect("button_press_event", self.zoom_in_100_callback)
+
+ self.slider_adjustment = gtk.Adjustment(value=self.parentApp.prefs.preview_zoom,
+ lower=config.MIN_THUMBNAIL_SIZE, upper=config.max_thumbnail_size,
+ step_incr=1.0, page_incr=config.THUMBNAIL_INCREMENT, page_size=0)
+ self.slider_adjustment.connect("value_changed", self.resize_image_callback)
+ self.slider_hscale = gtk.HScale(self.slider_adjustment)
+ self.slider_hscale.set_draw_value(False) # don't display numeric value
+ self.slider_hscale.set_size_request(config.MIN_THUMBNAIL_SIZE * 2, -1)
- #Preview title
- self.preview_title_label = gtk.Label()
- self.preview_title_label.set_markup("<b>%s</b>" % _("Preview"))
- self.preview_title_label.set_alignment(0, 0.5)
- self.preview_title_label.set_padding(12, 0)
#Preview image
+ self.base_preview_image = None # large size image used to scale down from
self.preview_image = gtk.Image()
+
self.preview_image.set_alignment(0, 0.5)
#leave room for thumbnail shadow
if DROP_SHADOW:
- shadow_size = 21
+ self.cacheDropShadow()
else:
- shadow_size = 0
- self.preview_image.set_size_request(MAX_THUMBNAIL_SIZE + shadow_size, MAX_THUMBNAIL_SIZE + shadow_size)
+ self.shadow_size = 0
+
+ image_size, shadow_size, offset = self._imageAndShadowSize()
+
+ self.preview_image.set_size_request(image_size, image_size)
#labels to display file information
@@ -4460,9 +4487,14 @@ class SelectionVBox(gtk.VBox):
self.preview_table.attach(right_spacer, 3, 4, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
row = 0
- if not tiny_screen:
- self.preview_table.attach(self.preview_title_label, 0, 3, row, row+1, yoptions=gtk.SHRINK)
- row += 1
+ zoom_hbox = gtk.HBox()
+ zoom_hbox.pack_start(self.zoom_out_eventbox, False, False)
+ zoom_hbox.pack_start(self.slider_hscale, False, False)
+ zoom_hbox.pack_start(self.zoom_in_eventbox, False, False)
+
+ self.preview_table.attach(zoom_hbox, 1, 3, row, row+1, yoptions=gtk.SHRINK)
+
+ row += 1
self.preview_table.attach(self.preview_image, 1, 3, row, row+1, yoptions=gtk.SHRINK)
row += 1
@@ -4504,6 +4536,26 @@ class SelectionVBox(gtk.VBox):
self.show_all()
+ def set_base_preview_image(self, pixbuf):
+ """
+ sets the unscaled pixbuf image to be displayed to the user
+ the actual image the user will see will depend on the scale
+ they've set to view it at
+ """
+ self.base_preview_image = pixbuf
+
+ def zoom_in(self):
+ self.slider_adjustment.set_value(min([config.max_thumbnail_size, int(self.slider_adjustment.get_value()) + config.THUMBNAIL_INCREMENT]))
+
+ def zoom_out(self):
+ self.slider_adjustment.set_value(max([config.MIN_THUMBNAIL_SIZE, int(self.slider_adjustment.get_value()) - config.THUMBNAIL_INCREMENT]))
+
+ def zoom_in_100_callback(self, widget, value):
+ self.slider_adjustment.set_value(config.max_thumbnail_size)
+
+ def zoom_out_0_callback(self, widget, value):
+ self.slider_adjustment.set_value(config.MIN_THUMBNAIL_SIZE)
+
def set_display_preview_folders(self, value):
if value and self.selection_treeview.previewed_file_treerowref:
self.preview_destination_expander.show()
@@ -4512,6 +4564,51 @@ class SelectionVBox(gtk.VBox):
else:
self.preview_destination_expander.hide()
self.preview_device_expander.hide()
+
+ def cacheDropShadow(self):
+ i, self.shadow_size, offset_v = self._imageAndShadowSize()
+ self.drop_shadow = DropShadow(offset=(offset_v,offset_v), shadow = (0x44, 0x44, 0x44, 0xff), border=self.shadow_size, trim_border = True)
+
+ def _imageAndShadowSize(self):
+ image_size = int(self.slider_adjustment.get_value())
+ offset_v = max([image_size / 25, 5]) # realistically size the shadow based on the size of the image
+ shadow_size = offset_v + 3
+ image_size = image_size + offset_v * 2 + 3
+ return (image_size, shadow_size, offset_v)
+
+ def resize_image_callback(self, adjustment):
+ """
+ Resize the preview image after the adjustment value has been
+ changed
+ """
+ size = int(adjustment.value)
+ self.parentApp.prefs.preview_zoom = size
+ self.cacheDropShadow()
+
+ pixbuf = self.scaledPreviewImage()
+ if pixbuf:
+ self.preview_image.set_from_pixbuf(pixbuf)
+ size = max([pixbuf.get_width(), pixbuf.get_height()])
+ self.preview_image.set_size_request(size, size)
+ else:
+ self.preview_image.set_size_request(size + self.shadow_size, size + self.shadow_size)
+
+ def scaledPreviewImage(self):
+ """
+ Generate a scaled version of the preview image
+ """
+ size = int(self.slider_adjustment.get_value())
+ if not self.base_preview_image:
+ return None
+ else:
+ pixbuf = common.scale2pixbuf(size, size, self.base_preview_image)
+
+ if DROP_SHADOW:
+ pil_image = pixbuf_to_image(pixbuf)
+ pil_image = self.drop_shadow.dropShadow(pil_image)
+ pixbuf = image_to_pixbuf(pil_image)
+
+ return pixbuf
def set_job_code_display(self):
"""
@@ -4542,8 +4639,6 @@ class SelectionVBox(gtk.VBox):
# clear existing entry displayed in entry box
self.job_code_entry.set_text('')
-
-
def add_job_code_combo(self):
self.job_code_hbox = gtk.HBox(spacing = 12)
@@ -5926,6 +6021,12 @@ class RapidApp(gnomeglade.GnomeApp, dbus.service.Object):
def on_menu_preview_folders_toggled(self, check_button):
self.prefs.display_preview_folders = check_button.get_active()
+ def on_menu_zoom_out_activate(self, widget):
+ self.selection_vbox.zoom_out()
+
+ def on_menu_zoom_in_activate(self, widget):
+ self.selection_vbox.zoom_in()
+
def on_menu_select_all_activate(self, widget):
self.selection_vbox.selection_treeview.select_rows('all')
@@ -6376,7 +6477,7 @@ def start ():
if DOWNLOAD_VIDEO:
cmd_line(_("Using") + " hachoir " + videometadata.version_info())
else:
- cmd_line(_("\n" + "Video downloading functionality disabled.\nTo download videos, please install the kaa metadata package for python.") + "\n")
+ cmd_line(_("\n" + "Video downloading functionality disabled.\nTo download videos, please install the hachoir metadata and kaa metadata packages for python.") + "\n")
if using_gio:
cmd_line(_("Using") + " GIO")