diff options
author | gls <gls@pkgsrc.org> | 2011-01-11 20:46:16 +0000 |
---|---|---|
committer | gls <gls@pkgsrc.org> | 2011-01-11 20:46:16 +0000 |
commit | d224796b29935a984950926c309f0922c3f66440 (patch) | |
tree | afaae6fc297c94b4338bb7835d1682bd6fa15ddd /graphics | |
parent | bd3e78da7f90a5ceebd2b3658e7df5d0aff443c6 (diff) | |
download | pkgsrc-d224796b29935a984950926c309f0922c3f66440.tar.gz |
pdate to version 0.8.0
Upstream changes:
* Video support for most major video formats, including importing them off
of camera and adding them to events and tags.
* Publish videos to major Web services, including YouTube, Flickr, Facebook,
and PicasaWeb.
* Runtime monitoring of library directory and auto-import of newly created
files.
* Background writing of metadata (tags, titles, ratings, orientation, and
exposure date) to master files (user-configurable).
* Flagging photos for batch operations.
* Set multiple photos to desktop background slideshow.
* Numerous translation updates.
* Various bug fixes.
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/shotwell/Makefile | 9 | ||||
-rw-r--r-- | graphics/shotwell/PLIST | 21 | ||||
-rw-r--r-- | graphics/shotwell/distinfo | 13 | ||||
-rw-r--r-- | graphics/shotwell/patches/patch-aa | 101 | ||||
-rw-r--r-- | graphics/shotwell/patches/patch-ab | 195 | ||||
-rw-r--r-- | graphics/shotwell/patches/patch-ac | 1496 |
6 files changed, 1584 insertions, 251 deletions
diff --git a/graphics/shotwell/Makefile b/graphics/shotwell/Makefile index 36f218ccb55..94d368cc91d 100644 --- a/graphics/shotwell/Makefile +++ b/graphics/shotwell/Makefile @@ -1,10 +1,9 @@ -# $NetBSD: Makefile,v 1.7 2010/12/17 07:36:11 obache Exp $ +# $NetBSD: Makefile,v 1.8 2011/01/11 20:46:16 gls Exp $ # -DISTNAME= shotwell-0.7.2 -PKGREVISION= 4 +DISTNAME= shotwell-0.8.0 CATEGORIES= graphics -MASTER_SITES= http://yorba.org/download/shotwell/0.7/ +MASTER_SITES= http://yorba.org/download/shotwell/0.8/ EXTRACT_SUFX= .tar.bz2 MAINTAINER= pkgrsc-users@NetBSD.org @@ -19,6 +18,7 @@ USE_TOOLS+= gmake bash pkg-config CONFIG_SHELL= bash CONFIGURE_ARGS+= --prefix=${PREFIX} +CONFIGURE_ARGS+= --assume-pkgs CONFIGURE_ENV+= --define=NO_CAMERA REPLACE_SH+= minver configure libraw-config @@ -43,6 +43,7 @@ post-install: .include "../../sysutils/desktop-file-utils/desktopdb.mk" .include "../../sysutils/dbus-glib/buildlink3.mk" .include "../../textproc/libxml2/buildlink3.mk" +.include "../../textproc/json-glib/buildlink3.mk" .include "../../www/webkit-gtk/buildlink3.mk" .include "../../x11/gtk2/buildlink3.mk" .include "../../x11/libunique/buildlink3.mk" diff --git a/graphics/shotwell/PLIST b/graphics/shotwell/PLIST index 1928a9299ee..6c0b098329a 100644 --- a/graphics/shotwell/PLIST +++ b/graphics/shotwell/PLIST @@ -1,4 +1,4 @@ -@comment $NetBSD: PLIST,v 1.1.1.1 2010/11/15 19:04:53 gls Exp $ +@comment $NetBSD: PLIST,v 1.2 2011/01/11 20:46:16 gls Exp $ bin/shotwell share/applications/shotwell-viewer.desktop share/applications/shotwell.desktop @@ -24,21 +24,26 @@ share/gnome/help/shotwell/C/import-file.page share/gnome/help/shotwell/C/import-memorycard.page share/gnome/help/shotwell/C/index.page share/gnome/help/shotwell/C/organize-event.page +share/gnome/help/shotwell/C/organize-flag.page share/gnome/help/shotwell/C/organize-rating.page share/gnome/help/shotwell/C/organize-remove.page share/gnome/help/shotwell/C/organize-tag.page share/gnome/help/shotwell/C/organize-title.page +share/gnome/help/shotwell/C/other-files.page share/gnome/help/shotwell/C/other-missing.page share/gnome/help/shotwell/C/other-multiple.page share/gnome/help/shotwell/C/running.page share/gnome/help/shotwell/C/share-background.page share/gnome/help/shotwell/C/share-export.page share/gnome/help/shotwell/C/share-print.page +share/gnome/help/shotwell/C/share-send.page share/gnome/help/shotwell/C/share-slideshow.page share/gnome/help/shotwell/C/share-upload.page share/gnome/help/shotwell/C/view-displaying.page share/gnome/help/shotwell/C/view-information.page share/gnome/help/shotwell/C/view-sidebar.page +share/icons/hicolor/16x16/apps/shotwell.svg +share/icons/hicolor/24x24/apps/shotwell.svg share/icons/hicolor/scalable/apps/shotwell.svg share/locale/ar/LC_MESSAGES/shotwell.mo share/locale/ast/LC_MESSAGES/shotwell.mo @@ -52,9 +57,11 @@ share/locale/el/LC_MESSAGES/shotwell.mo share/locale/en_GB/LC_MESSAGES/shotwell.mo share/locale/es/LC_MESSAGES/shotwell.mo share/locale/et/LC_MESSAGES/shotwell.mo +share/locale/eu/LC_MESSAGES/shotwell.mo share/locale/fi/LC_MESSAGES/shotwell.mo share/locale/fr/LC_MESSAGES/shotwell.mo share/locale/gl/LC_MESSAGES/shotwell.mo +share/locale/he/LC_MESSAGES/shotwell.mo share/locale/hr/LC_MESSAGES/shotwell.mo share/locale/hu/LC_MESSAGES/shotwell.mo share/locale/id/LC_MESSAGES/shotwell.mo @@ -64,11 +71,13 @@ share/locale/kk/LC_MESSAGES/shotwell.mo share/locale/ko/LC_MESSAGES/shotwell.mo share/locale/lt/LC_MESSAGES/shotwell.mo share/locale/lv/LC_MESSAGES/shotwell.mo +share/locale/mk/LC_MESSAGES/shotwell.mo share/locale/nb/LC_MESSAGES/shotwell.mo share/locale/nl/LC_MESSAGES/shotwell.mo share/locale/pa/LC_MESSAGES/shotwell.mo share/locale/pl/LC_MESSAGES/shotwell.mo share/locale/pt/LC_MESSAGES/shotwell.mo +share/locale/pt_BR/LC_MESSAGES/shotwell.mo share/locale/ro/LC_MESSAGES/shotwell.mo share/locale/ru/LC_MESSAGES/shotwell.mo share/locale/sk/LC_MESSAGES/shotwell.mo @@ -87,16 +96,18 @@ share/shotwell/icons/drag_nub.png share/shotwell/icons/enhance.png share/shotwell/icons/five-star-filter.svg share/shotwell/icons/five-stars.svg +share/shotwell/icons/flag-page.png +share/shotwell/icons/flag-trinket.png share/shotwell/icons/four-star-filter-plus.svg share/shotwell/icons/four-stars.svg share/shotwell/icons/image-adjust.svg share/shotwell/icons/import-all.png share/shotwell/icons/import.svg -share/shotwell/icons/last-import-roll.png share/shotwell/icons/make-primary.svg share/shotwell/icons/merge.svg share/shotwell/icons/multiple-events.png share/shotwell/icons/multiple-tags.png +share/shotwell/icons/noninterpretable-video.png share/shotwell/icons/one-event.png share/shotwell/icons/one-star-filter-plus.svg share/shotwell/icons/one-star.svg @@ -110,10 +121,12 @@ share/shotwell/icons/shotwell-24.svg share/shotwell/icons/shotwell-street.jpg share/shotwell/icons/shotwell.ico share/shotwell/icons/shotwell.svg +share/shotwell/icons/sprocket.png share/shotwell/icons/three-star-filter-plus.svg share/shotwell/icons/three-stars.svg share/shotwell/icons/two-star-filter-plus.svg share/shotwell/icons/two-stars.svg +share/shotwell/icons/videos-page.png share/shotwell/icons/zoom-in.png share/shotwell/icons/zoom-out.png share/shotwell/ui/collection.ui @@ -123,8 +136,12 @@ share/shotwell/ui/events_directory.ui share/shotwell/ui/fullscreen.ui share/shotwell/ui/import.ui share/shotwell/ui/import_queue.ui +share/shotwell/ui/media.ui share/shotwell/ui/offline.ui share/shotwell/ui/photo.ui +share/shotwell/ui/set_background_dialog.glade share/shotwell/ui/shotwell.glade share/shotwell/ui/tags.ui share/shotwell/ui/trash.ui +share/shotwell/ui/video.ui +share/shotwell/ui/yandex_publish_model.glade diff --git a/graphics/shotwell/distinfo b/graphics/shotwell/distinfo index 216c9190fe0..c101604b878 100644 --- a/graphics/shotwell/distinfo +++ b/graphics/shotwell/distinfo @@ -1,7 +1,8 @@ -$NetBSD: distinfo,v 1.2 2010/12/13 20:36:53 gls Exp $ +$NetBSD: distinfo,v 1.3 2011/01/11 20:46:16 gls Exp $ -SHA1 (shotwell-0.7.2.tar.bz2) = 892ae852e990ab9815108b41b8151ee7ef7f11d9 -RMD160 (shotwell-0.7.2.tar.bz2) = 4b9e6abfda6fb479a7cb376340c226fa10357e86 -Size (shotwell-0.7.2.tar.bz2) = 1064127 bytes -SHA1 (patch-aa) = fdddc3979c1d2367f4e59745e3426a7ed6e093a5 -SHA1 (patch-ab) = f415b6a90eb61f5a2696a9f87733fa617af8f163 +SHA1 (shotwell-0.8.0.tar.bz2) = 944ea702333637e3d5ec358fef07fb615b08f51c +RMD160 (shotwell-0.8.0.tar.bz2) = 95cb65a25c0d4a9e1b915fabf2c98948c9b44679 +Size (shotwell-0.8.0.tar.bz2) = 1321376 bytes +SHA1 (patch-aa) = b6e1e8da2dd4370073d70a786ff7cf8aca06d868 +SHA1 (patch-ab) = 390a2e725e10de42ce6d3617f4c093d3a63374e6 +SHA1 (patch-ac) = 6a54ecf0ff0694aa70f7e6f515650b56cc119033 diff --git a/graphics/shotwell/patches/patch-aa b/graphics/shotwell/patches/patch-aa index 4b207ca9520..a9b8431b884 100644 --- a/graphics/shotwell/patches/patch-aa +++ b/graphics/shotwell/patches/patch-aa @@ -1,98 +1,33 @@ -$NetBSD: patch-aa,v 1.2 2010/12/13 20:36:53 gls Exp $ +$NetBSD: patch-aa,v 1.3 2011/01/11 20:46:16 gls Exp $ ---- Makefile.orig 2010-09-10 22:55:54.000000000 +0000 +--- Makefile.orig 2010-12-23 23:01:46.000000000 +0000 +++ Makefile -@@ -124,11 +124,6 @@ SRC_FILES = \ - FSpotDatabaseDriver.vala \ - FSpotDatabaseTables.vala - --ifndef LINUX --SRC_FILES += \ -- GConf.vala --endif -- - VAPI_FILES = \ - libexif.vapi \ - libgphoto2.vapi \ -@@ -268,6 +263,7 @@ EXT_PKGS = \ - gee-1.0 \ +@@ -280,7 +280,7 @@ EXT_PKGS = \ + gstreamer-base-0.10 \ gtk+-2.0 \ glib-2.0 \ +- gudev-1.0 \ + gmodule-2.0 \ + json-glib-1.0 \ libexif \ - sqlite3 \ - gexiv2 -@@ -275,7 +271,6 @@ EXT_PKGS = \ - LIBRAW_PKG = \ - libraw - --ifdef LINUX - EXT_PKGS += \ - gconf-2.0 \ libgphoto2 \ -@@ -283,10 +278,8 @@ EXT_PKGS += \ - libxml-2.0 \ - unique-1.0 \ - webkit-1.0 \ -- gudev-1.0 \ - dbus-glib-1 \ - gdk-x11-2.0 --endif - - # libraw is handled separately (see note below); when libraw-config is no longer needed, the version - # should be added to this list -@@ -301,7 +294,6 @@ EXT_PKG_VERSIONS = \ - LIBRAW_VERSION = \ - 0.9.0 - --ifdef LINUX - EXT_PKG_VERSIONS += \ - gconf-2.0 >= 2.22.0 \ - libgphoto2 >= 2.4.2 \ -@@ -309,9 +301,7 @@ EXT_PKG_VERSIONS += \ - libxml-2.0 >= 2.6.32 \ - unique-1.0 >= 1.0.0 \ - webkit-1.0 >= 1.1.5 \ +@@ -306,7 +306,6 @@ EXT_PKG_VERSIONS = \ + glib-2.0 >= 2.24.0 \ + gstreamer-0.10 >= 0.10.28 \ + gstreamer-base-0.10 >= 0.10.28 \ - gudev-1.0 >= 145 \ - dbus-glib-1 >= 0.80 --endif - - PKGS = $(EXT_PKGS) $(LOCAL_PKGS) $(LIBRAW_PKG) - -@@ -366,7 +356,7 @@ ifndef BUILD_DEBUG - # -mwindows prevents a console window from appearing when we run Shotwell, but also hides - # all logging/debugging output, so we specify it only in a release build. - VALA_LDFLAGS += -mwindows --endif -+endif - - shotwell.res: windows/shotwell.rc - windres windows/shotwell.rc -O coff -o shotwell.res -@@ -470,7 +460,6 @@ endif - ifndef DISABLE_DESKTOP_UPDATE - -update-desktop-database || : - endif --ifdef LINUX - ifndef DISABLE_SCHEMAS_INSTALL - GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source` gconftool-2 --makefile-install-rule misc/shotwell.schemas - else -@@ -487,7 +476,6 @@ ifndef DISABLE_HELP_INSTALL - mkdir -p $(DESTDIR)$(PREFIX)/share/gnome/help/shotwell/C/figures - $(INSTALL_DATA) $(EXPANDED_HELP_IMAGES) $(DESTDIR)$(PREFIX)/share/gnome/help/shotwell/C/figures - endif --endif - -$(foreach lang,$(SUPPORTED_LANGUAGES),`mkdir -p $(SYSTEM_LANG_DIR)/$(lang)/LC_MESSAGES ; \ - $(INSTALL_DATA) $(LOCAL_LANG_DIR)/$(lang)/LC_MESSAGES/shotwell.mo \ - $(SYSTEM_LANG_DIR)/$(lang)/LC_MESSAGES/shotwell.mo`) -@@ -518,7 +506,6 @@ endif + json-glib-1.0 >= 0.7.6 \ + libexif >= 0.6.16 \ + libgphoto2 >= 2.4.2 \ +@@ -504,7 +503,6 @@ endif $(VALA_STAMP): $(EXPANDED_SRC_FILES) $(EXPANDED_VAPI_FILES) $(EXPANDED_SRC_HEADER_FILES) Makefile \ $(CONFIG_IN) -- @ ./minver `valac --version | awk '{print $$2}'` $(MIN_VALAC_VERSION) || ( echo 'Shotwell requires Vala compiler $(MIN_VALAC_VERSION) or greater. You are running' `valac --version` '\b.'; exit 1 ) +- @ ./minver `$(VALAC) --version | awk '{print $$2}'` $(MIN_VALAC_VERSION) || ( echo 'Shotwell requires Vala compiler $(MIN_VALAC_VERSION) or greater. You are running' `$(VALAC) --version` '\b.'; exit 1 ) ifndef ASSUME_PKGS ifdef EXT_PKG_VERSIONS - @pkg-config --print-errors --exists '$(EXT_PKG_VERSIONS)' -@@ -546,15 +533,15 @@ $(EXPANDED_C_FILES): $(VALA_STAMP) + @pkg-config --print-errors --exists '$(EXT_PKG_VERSIONS) $(DIRECT_LIBS_VERSIONS)' +@@ -530,13 +528,13 @@ $(EXPANDED_C_FILES): $(VALA_STAMP) @ $(EXPANDED_OBJ_FILES): %.o: %.c $(CONFIG_IN) Makefile @@ -109,5 +44,3 @@ $NetBSD: patch-aa,v 1.2 2010/12/13 20:36:53 gls Exp $ - $(CC) $(EXPANDED_OBJ_FILES) $(CFLAGS) $(RESOURCES) $(VALA_LDFLAGS) `$(LIBRAW_CONFIG) --libs` $(EXPORT_FLAGS) -shared -o $@ + $(CC) $(EXPANDED_OBJ_FILES) $(CFLAGS) $(RESOURCES) $(VALA_LDFLAGS) $(LDFLAGS) `pkg-config --libs libraw` $(EXPORT_FLAGS) -shared -o $@ - shotwell-setup-$(VERSION).exe: $(PROGRAM) windows/winstall.iss - iscc windows\winstall.iss diff --git a/graphics/shotwell/patches/patch-ab b/graphics/shotwell/patches/patch-ab index 0ac9426fa03..665f09890d7 100644 --- a/graphics/shotwell/patches/patch-ab +++ b/graphics/shotwell/patches/patch-ab @@ -1,113 +1,24 @@ -$NetBSD: patch-ab,v 1.1.1.1 2010/11/15 19:04:53 gls Exp $ +$NetBSD: patch-ab,v 1.2 2011/01/11 20:46:16 gls Exp $ ---- src/CameraTable.vala.orig 2010-09-10 22:55:55.000000000 +0000 +--- src/CameraTable.vala.orig 2010-12-23 23:01:46.000000000 +0000 +++ src/CameraTable.vala -@@ -1,7 +1,7 @@ - /* Copyright 2009-2010 Yorba Foundation - * - * This software is licensed under the GNU Lesser General Public License -- * (version 2.1 or later). See the COPYING file in this distribution. -+ * (version 2.1 or later). See the COPYING file in this distribution. - */ - - #if !NO_CAMERA -@@ -9,7 +9,7 @@ - public class DiscoveredCamera { - public GPhoto.Camera gcamera; - public string uri; -- -+ - public DiscoveredCamera(GPhoto.Camera gcamera, string uri) { - this.gcamera = gcamera; - this.uri = uri; -@@ -18,70 +18,66 @@ public class DiscoveredCamera { - - public class CameraTable { - private const int UPDATE_DELAY_MSEC = 500; -- -+ - // list of subsystems being monitored for events - private const string[] SUBSYSTEMS = { "usb", "block", null }; -- -+ +@@ -24,7 +24,6 @@ public class CameraTable { + private static CameraTable instance = null; -- + - private GUdev.Client client = new GUdev.Client(SUBSYSTEMS); -+ private OneShotScheduler camera_update_scheduler = null; private GPhoto.Context null_context = new GPhoto.Context(); private GPhoto.CameraAbilitiesList abilities_list; -- -+ - private Gee.HashMap<string, DiscoveredCamera> camera_map = new Gee.HashMap<string, DiscoveredCamera>( - str_hash, str_equal, direct_equal); - - public signal void camera_added(DiscoveredCamera camera); -- -+ - public signal void camera_removed(DiscoveredCamera camera); -- -+ - private CameraTable() { - camera_update_scheduler = new OneShotScheduler("CameraTable update scheduler", +@@ -42,7 +41,6 @@ public class CameraTable { on_update_cameras); -- -- // listen for interesting events on the specified subsystems + + // listen for interesting events on the specified subsystems - client.uevent.connect(on_udev_event); -- -+ - // because loading the camera abilities list takes a bit of time and slows down app - // startup, delay loading it (and notifying any observers) for a small period of time, - // after the dust has settled - Timeout.add(500, delayed_init); - } -- -+ - private bool delayed_init() { - try { - init_camera_table(); - } catch (GPhotoError err) { - warning("Unable to initialize camera table: %s", err.message); -- -+ - return false; - } -- -+ - try { - update_camera_table(); - } catch (GPhotoError err) { - warning("Unable to update camera table: %s", err.message); - } -- -+ - return false; - } -- -+ - public static CameraTable get_instance() { - if (instance == null) - instance = new CameraTable(); -- -+ - return instance; - } -- -+ - public Gee.Iterable<DiscoveredCamera> get_cameras() { - return camera_map.values; - } -- -+ - public int get_count() { - return camera_map.size; - } -- -+ - public DiscoveredCamera? get_for_uri(string uri) { - return camera_map.get(uri); - } -@@ -90,43 +86,18 @@ public class CameraTable { + volume_monitor = VolumeMonitor.get(); + volume_monitor.volume_changed.connect(on_volume_changed); + volume_monitor.volume_added.connect(on_volume_changed); +@@ -94,43 +92,18 @@ public class CameraTable { if (res != GPhoto.Result.OK) throw new GPhotoError.LIBRARY("[%d] Unable to %s: %s", (int) res, op, res.as_string()); } @@ -155,7 +66,7 @@ $NetBSD: patch-ab,v 1.1.1.1 2010/11/15 19:04:53 gls Exp $ // USB (or libusb) is a funny beast; if only one USB device is present (i.e. the camera), // then a single camera is detected at port usb:. However, if multiple USB devices are // present (including non-cameras), then the first attached camera will be listed twice, -@@ -135,59 +106,59 @@ public class CameraTable { +@@ -139,59 +112,59 @@ public class CameraTable { // // This function gleans the full port name of a particular port, even if it's the unadorned // "usb:", by using GUdev. @@ -230,7 +141,7 @@ $NetBSD: patch-ab,v 1.1.1.1 2010/11/15 19:04:53 gls Exp $ public static string get_port_uri(string port) { return "gphoto2://[%s]/".printf(port); } -@@ -201,13 +172,13 @@ public class CameraTable { +@@ -220,13 +193,13 @@ public class CameraTable { GPhoto.CameraList camera_list; do_op(GPhoto.CameraList.create(out camera_list), "create camera list"); do_op(abilities_list.detect(port_info_list, camera_list, null_context), "detect cameras"); @@ -247,7 +158,7 @@ $NetBSD: patch-ab,v 1.1.1.1 2010/11/15 19:04:53 gls Exp $ // go through the detected camera list and glean their ports for (int ctr = 0; ctr < camera_list.count(); ctr++) { string name; -@@ -215,55 +186,55 @@ public class CameraTable { +@@ -234,55 +207,55 @@ public class CameraTable { string port; do_op(camera_list.get_value(ctr, out port), "get detected camera port"); @@ -316,56 +227,32 @@ $NetBSD: patch-ab,v 1.1.1.1 2010/11/15 19:04:53 gls Exp $ camera_removed(camera); } -@@ -275,50 +246,42 @@ public class CameraTable { - if (camera_map.has_key(uri)) { - // already known about - debug("%s @ %s already registered, skipping", name, port); -- -+ +@@ -299,21 +272,6 @@ public class CameraTable { continue; } -- -+ - int index = port_info_list.lookup_path(port); - if (index < 0) - do_op((GPhoto.Result) index, "lookup port %s".printf(port)); -- -+ - GPhoto.PortInfo port_info; - do_op(port_info_list.get_info(index, out port_info), "get port info for %s".printf(port)); -- -+ - // this should match, every time - assert(port == port_info.path); -- -+ - index = abilities_list.lookup_model(name); - if (index < 0) - do_op((GPhoto.Result) index, "lookup camera model %s".printf(name)); - - GPhoto.CameraAbilities camera_abilities; -- do_op(abilities_list.get_abilities(index, out camera_abilities), -+ do_op(abilities_list.get_abilities(index, out camera_abilities), - "lookup camera abilities for %s".printf(name)); -- -+ - GPhoto.Camera gcamera; - do_op(GPhoto.Camera.create(out gcamera), "create camera object for %s".printf(name)); - do_op(gcamera.set_abilities(camera_abilities), "set camera abilities for %s".printf(name)); - do_op(gcamera.set_port_info(port_info), "set port info for %s on %s".printf(name, port)); -- -+ - debug("Adding to camera table: %s @ %s", name, port); -- -+ - DiscoveredCamera camera = new DiscoveredCamera(gcamera, uri); - camera_map.set(uri, camera); -- -+ - camera_added(camera); + +- // Get display name for camera. +- string path = get_port_path(port); +- if (null != path) { +- GUdev.Device device = client.query_by_device_file(path); +- string serial = device.get_property("ID_SERIAL_SHORT"); +- if (null != serial) { +- display_name = get_name_for_uuid(serial); +- } +- if (null == display_name) { +- display_name = device.get_sysfs_attr("product"); +- } +- if (null == display_name) { +- display_name = device.get_property("ID_MODEL"); +- } +- } + if (null == display_name) { + // Default to GPhoto detected name. + display_name = name; +@@ -351,13 +309,6 @@ public class CameraTable { } } -- + - private void on_udev_event(string action, GUdev.Device device) { - debug("udev event: %s on %s", action, device.get_name()); - @@ -373,8 +260,6 @@ $NetBSD: patch-ab,v 1.1.1.1 2010/11/15 19:04:53 gls Exp $ - // update to occur when they come in all at once - camera_update_scheduler.after_timeout(UPDATE_DELAY_MSEC, true); - } -- -+ - private void on_update_cameras() { - try { - get_instance().update_camera_table(); + + public void on_volume_changed(Volume volume) { + camera_update_scheduler.after_timeout(UPDATE_DELAY_MSEC, true); diff --git a/graphics/shotwell/patches/patch-ac b/graphics/shotwell/patches/patch-ac new file mode 100644 index 00000000000..57cce8212a9 --- /dev/null +++ b/graphics/shotwell/patches/patch-ac @@ -0,0 +1,1496 @@ +$NetBSD: patch-ac,v 1.1 2011/01/11 20:46:16 gls Exp $ + +--- src/Dialogs.vala.orig 2010-12-23 23:01:46.000000000 +0000 ++++ src/Dialogs.vala +@@ -1,7 +1,7 @@ + /* Copyright 2009-2010 Yorba Foundation + * + * This software is licensed under the GNU LGPL (version 2.1 or later). +- * See the COPYING file in this distribution. ++ * See the COPYING file in this distribution. + */ + + namespace ExportUI { +@@ -13,9 +13,9 @@ public File? choose_file(string current_ + + string file_chooser_title = VideoReader.is_supported_video_filename(current_file_basename) ? + _("Export Video") : _("Export Photo"); +- ++ + Gtk.FileChooserDialog chooser = new Gtk.FileChooserDialog(file_chooser_title, +- AppWindow.get_instance(), Gtk.FileChooserAction.SAVE, Gtk.STOCK_CANCEL, ++ AppWindow.get_instance(), Gtk.FileChooserAction.SAVE, Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.ACCEPT, null); + chooser.set_do_overwrite_confirmation(true); + chooser.set_current_folder(current_export_dir.get_path()); +@@ -27,9 +27,9 @@ public File? choose_file(string current_ + file = File.new_for_path(chooser.get_filename()); + current_export_dir = file.get_parent(); + } +- ++ + chooser.destroy(); +- ++ + return file; + } + +@@ -41,19 +41,19 @@ public File? choose_dir(string? user_tit + user_title = _("Export Photos"); + + Gtk.FileChooserDialog chooser = new Gtk.FileChooserDialog(user_title, +- AppWindow.get_instance(), Gtk.FileChooserAction.SELECT_FOLDER, Gtk.STOCK_CANCEL, ++ AppWindow.get_instance(), Gtk.FileChooserAction.SELECT_FOLDER, Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT, null); + chooser.set_current_folder(current_export_dir.get_path()); + chooser.set_local_only(false); +- ++ + File dir = null; + if (chooser.run() == Gtk.ResponseType.ACCEPT) { + dir = File.new_for_path(chooser.get_filename()); + current_export_dir = dir; + } +- ++ + chooser.destroy(); +- ++ + return dir; + } + } +@@ -84,17 +84,17 @@ public class ExportDialog : Gtk.Dialog { + public const int NUM_SPECIAL_FORMATS = 2; + public const string UNMODIFIED_FORMAT_LABEL = _("Unmodified"); + public const string CURRENT_FORMAT_LABEL = _("Current"); +- ++ + public const ScaleConstraint[] CONSTRAINT_ARRAY = { ScaleConstraint.ORIGINAL, + ScaleConstraint.DIMENSIONS, ScaleConstraint.WIDTH, ScaleConstraint.HEIGHT }; +- +- public const Jpeg.Quality[] QUALITY_ARRAY = { Jpeg.Quality.LOW, Jpeg.Quality.MEDIUM, ++ ++ public const Jpeg.Quality[] QUALITY_ARRAY = { Jpeg.Quality.LOW, Jpeg.Quality.MEDIUM, + Jpeg.Quality.HIGH, Jpeg.Quality.MAXIMUM }; + + private static ScaleConstraint current_constraint = ScaleConstraint.ORIGINAL; + private static ExportFormatParameters current_parameters = ExportFormatParameters.current(); + private static int current_scale = DEFAULT_SCALE; +- ++ + private Gtk.Table table = new Gtk.Table(0, 0, false); + private Gtk.ComboBox quality_combo; + private Gtk.ComboBox constraint_combo; +@@ -103,7 +103,7 @@ public class ExportDialog : Gtk.Dialog { + private Gtk.Entry pixels_entry; + private Gtk.Widget ok_button; + private bool in_insert = false; +- ++ + public ExportDialog(string title) { + this.title = title; + has_separator = false; +@@ -117,7 +117,7 @@ public class ExportDialog : Gtk.Dialog { + quality_combo.set_active(ctr); + ctr++; + } +- ++ + constraint_combo = new Gtk.ComboBox.text(); + ctr = 0; + foreach (ScaleConstraint constraint in CONSTRAINT_ARRAY) { +@@ -138,7 +138,7 @@ public class ExportDialog : Gtk.Dialog { + pixels_entry.set_max_length(6); + pixels_entry.set_size_request(60, -1); + pixels_entry.set_text("%d".printf(current_scale)); +- ++ + // register after preparation to avoid signals during init + constraint_combo.changed.connect(on_constraint_changed); + format_combo.changed.connect(on_format_changed); +@@ -152,20 +152,20 @@ public class ExportDialog : Gtk.Dialog { + + add_label(_("_Quality:"), 0, 1, quality_combo); + add_control(quality_combo, 1, 1); +- ++ + add_label(_("_Scaling constraint:"), 0, 2, constraint_combo); + add_control(constraint_combo, 1, 2); + + Gtk.Label pixels_label = new Gtk.Label.with_mnemonic(_(" _pixels")); + pixels_label.set_mnemonic_widget(pixels_entry); +- ++ + Gtk.HBox pixels_box = new Gtk.HBox(false, 0); + pixels_box.pack_start(pixels_entry, false, false, 0); + pixels_box.pack_end(pixels_label, false, false, 0); + add_control(pixels_box, 1, 3); +- ++ + ((Gtk.VBox) get_content_area()).add(table); +- ++ + // add buttons to action area + add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL); + ok_button = add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK); +@@ -180,12 +180,12 @@ public class ExportDialog : Gtk.Dialog { + + ok_button.grab_focus(); + } +- ++ + private void format_add_option(string format_name) { + format_options.add(format_name); + format_combo.append_text(format_name); + } +- ++ + private void format_set_active_text(string text) { + int selection_ticker = 0; + +@@ -196,10 +196,10 @@ public class ExportDialog : Gtk.Dialog { + } + selection_ticker++; + } +- ++ + error("format_set_active_text: text '%s' isn't in combo box", text); + } +- ++ + private PhotoFileFormat get_specified_format() { + int index = format_combo.get_active(); + assert(index >= NUM_SPECIAL_FORMATS); +@@ -208,23 +208,23 @@ public class ExportDialog : Gtk.Dialog { + PhotoFileFormat[] writeable_formats = PhotoFileFormat.get_writeable(); + return writeable_formats[index]; + } +- ++ + private string get_label_for_parameters(ExportFormatParameters params) { + switch(params.mode) { + case ExportFormatMode.UNMODIFIED: + return UNMODIFIED_FORMAT_LABEL; +- ++ + case ExportFormatMode.CURRENT: + return CURRENT_FORMAT_LABEL; +- ++ + case ExportFormatMode.SPECIFIED: +- return params.specified_format.get_properties().get_user_visible_name(); +- ++ return params.specified_format.get_properties().get_user_visible_name(); ++ + default: + error("get_label_for_parameters: unrecognized export format mode"); + } + } +- ++ + // unlike other parameters, which should be persisted across dialog executions, the + // format parameters must be set each time the dialog is executed -- this is why + // it's passed qualified as ref and not as out +@@ -246,19 +246,19 @@ public class ExportDialog : Gtk.Dialog { + + format_set_active_text(get_label_for_parameters(parameters)); + on_format_changed(); +- ++ + bool ok = (run() == Gtk.ResponseType.OK); + if (ok) { + int index = constraint_combo.get_active(); + assert(index >= 0); + constraint = CONSTRAINT_ARRAY[index]; + current_constraint = constraint; +- ++ + scale = pixels_entry.get_text().to_int(); + if (constraint != ScaleConstraint.ORIGINAL) + assert(scale > 0); + current_scale = scale; +- ++ + if (format_combo.get_active_text() == UNMODIFIED_FORMAT_LABEL) { + parameters.mode = current_parameters.mode = ExportFormatMode.UNMODIFIED; + } else if (format_combo.get_active_text() == CURRENT_FORMAT_LABEL) { +@@ -270,35 +270,35 @@ public class ExportDialog : Gtk.Dialog { + parameters.quality = current_parameters.quality = QUALITY_ARRAY[quality_combo.get_active()]; + } + } +- ++ + destroy(); +- ++ + return ok; + } +- ++ + private void add_label(string text, int x, int y, Gtk.Widget? widget = null) { + Gtk.Alignment left_aligned = new Gtk.Alignment(0.0f, 0.5f, 0, 0); +- ++ + Gtk.Label new_label = new Gtk.Label.with_mnemonic(text); + new_label.set_use_underline(true); +- ++ + if (widget != null) + new_label.set_mnemonic_widget(widget); +- ++ + left_aligned.add(new_label); +- +- table.attach(left_aligned, x, x + 1, y, y + 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, ++ ++ table.attach(left_aligned, x, x + 1, y, y + 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, + 10, 5); + } +- ++ + private void add_control(Gtk.Widget widget, int x, int y) { + Gtk.Alignment left_aligned = new Gtk.Alignment(0, 0.5f, 0, 0); + left_aligned.add(widget); +- ++ + table.attach(left_aligned, x, x + 1, y, y + 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, + 10, 5); + } +- ++ + private void on_constraint_changed() { + bool original = CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL; + bool jpeg = format_combo.get_active_text() == +@@ -313,7 +313,7 @@ public class ExportDialog : Gtk.Dialog { + + private void on_format_changed() { + bool original = CONSTRAINT_ARRAY[constraint_combo.get_active()] == ScaleConstraint.ORIGINAL; +- ++ + if (format_combo.get_active_text() == UNMODIFIED_FORMAT_LABEL) { + // if the user wishes to export the media unmodified, then we just copy the original + // files, so parameterizing size, quality, etc. is impossible -- these are all +@@ -332,7 +332,7 @@ public class ExportDialog : Gtk.Dialog { + // format. + constraint_combo.set_sensitive(true); + quality_combo.set_sensitive(false); +- pixels_entry.sensitive = !original; ++ pixels_entry.sensitive = !original; + } else { + // if the user has chosen a specific format, then allow JPEG quality customization if + // the format is JPEG and the user is re-sizing the image, otherwise, disallow JPEG +@@ -342,25 +342,25 @@ public class ExportDialog : Gtk.Dialog { + quality_combo.sensitive = !original && jpeg; + } + } +- ++ + private void on_activate() { + response(Gtk.ResponseType.OK); + } +- ++ + private void on_pixels_changed() { + ok_button.sensitive = (pixels_entry.get_text_length() > 0) && (pixels_entry.get_text().to_int() > 0); + } +- ++ + private void on_pixels_insert_text(string text, int length, void *position) { + // This is necessary because SignalHandler.block_by_func() is not properly bound + if (in_insert) + return; +- ++ + in_insert = true; +- ++ + if (length == -1) + length = (int) text.length; +- ++ + // only permit numeric text + string new_text = ""; + for (int ctr = 0; ctr < length; ctr++) { +@@ -368,12 +368,12 @@ public class ExportDialog : Gtk.Dialog { + new_text += ((char) text[ctr]).to_string(); + } + } +- ++ + if (new_text.length > 0) + pixels_entry.insert_text(new_text, (int) new_text.length, position); +- ++ + Signal.stop_emission_by_name(pixels_entry, "insert-text"); +- ++ + in_insert = false; + } + } +@@ -384,17 +384,17 @@ private const int REPORT_FAILURE_COUNT = + private string? generate_import_failure_list(Gee.List<BatchImportResult> failed, bool show_dest_id) { + if (failed.size == 0) + return null; +- ++ + string list = ""; + for (int ctr = 0; ctr < REPORT_FAILURE_COUNT && ctr < failed.size; ctr++) { +- list += "%s\n".printf(show_dest_id ? failed.get(ctr).dest_identifier : ++ list += "%s\n".printf(show_dest_id ? failed.get(ctr).dest_identifier : + failed.get(ctr).src_identifier); + } +- ++ + int remaining = failed.size - REPORT_FAILURE_COUNT; + if (remaining > 0) + list += _("(and %d more)\n").printf(remaining); +- ++ + return list; + } + +@@ -402,7 +402,7 @@ public class QuestionParams { + public string question; + public string yes_button; + public string no_button; +- ++ + public QuestionParams(string question, string yes_button, string no_button) { + this.question = question; + this.yes_button = yes_button; +@@ -430,7 +430,7 @@ public string get_media_specific_string( + string photos_msg, string videos_msg, string both_msg) { + bool has_photos = import_has_photos(import_collection); + bool has_videos = import_has_videos(import_collection); +- ++ + if (has_photos && has_videos) + return both_msg; + else if (has_photos) +@@ -442,10 +442,10 @@ public string get_media_specific_string( + } + + // Returns true if the user selected the yes action, false otherwise. +-public bool report_manifest(ImportManifest manifest, bool show_dest_id, ++public bool report_manifest(ImportManifest manifest, bool show_dest_id, + QuestionParams? question = null) { + string message = ""; +- ++ + if (manifest.already_imported.size > 0) { + string photos_message = (ngettext("1 duplicate photo was not imported:\n", + "%d duplicate photos were not imported:\n", +@@ -459,14 +459,14 @@ public bool report_manifest(ImportManife + + message += get_media_specific_string(manifest.already_imported, photos_message, + videos_message, both_message); +- ++ + message += generate_import_failure_list(manifest.already_imported, show_dest_id); + } +- ++ + if (manifest.failed.size > 0) { + if (message.length > 0) + message += "\n"; +- ++ + string photos_message = (ngettext("1 photo failed to import due to a file or hardware error:\n", + "%d photos failed to import due to a file or hardware error:\n", + manifest.failed.size)).printf(manifest.failed.size); +@@ -476,13 +476,13 @@ public bool report_manifest(ImportManife + string both_message = (ngettext("1 photo/video failed to import due to a file or hardware error:\n", + "%d photos/videos failed to import due to a file or hardware error:\n", + manifest.failed.size)).printf(manifest.failed.size); +- ++ + message += get_media_specific_string(manifest.failed, photos_message, videos_message, + both_message); +- ++ + message += generate_import_failure_list(manifest.failed, show_dest_id); + } +- ++ + if (manifest.camera_failed.size > 0) { + if (message.length > 0) + message += "\n"; +@@ -496,13 +496,13 @@ public bool report_manifest(ImportManife + string both_message = (ngettext("1 photo/video failed to import due to a camera error:\n", + "%d photos/videos failed to import due to a camera error:\n", + manifest.camera_failed.size)).printf(manifest.camera_failed.size); +- ++ + message += get_media_specific_string(manifest.camera_failed, photos_message, videos_message, + both_message); +- ++ + message += generate_import_failure_list(manifest.camera_failed, show_dest_id); + } +- ++ + if (manifest.skipped_photos.size > 0) { + if (message.length > 0) + message += "\n"; +@@ -515,7 +515,7 @@ public bool report_manifest(ImportManife + manifest.skipped_photos.size); + + message += skipped_photos_message; +- ++ + message += generate_import_failure_list(manifest.skipped_photos, show_dest_id); + } + +@@ -531,7 +531,7 @@ public bool report_manifest(ImportManife + + message += skipped_files_message; + } +- ++ + if (manifest.aborted.size > 0) { + if (message.length > 0) + message += "\n"; +@@ -545,13 +545,13 @@ public bool report_manifest(ImportManife + string both_message = (ngettext("1 photo/video skipped due to user cancel:\n", + "%d photos/videos skipped due to user cancel:\n", + manifest.aborted.size)).printf(manifest.aborted.size); +- ++ + message += get_media_specific_string(manifest.aborted, photos_message, videos_message, + both_message); +- ++ + message += generate_import_failure_list(manifest.aborted, show_dest_id); + } +- ++ + if (manifest.success.size > 0) { + if (message.length > 0) + message += "\n"; +@@ -565,47 +565,47 @@ public bool report_manifest(ImportManife + string both_message = (ngettext("1 photo/video successfully imported.\n", + "%d photos/videos successfully imported.\n", + manifest.success.size)).printf(manifest.success.size); +- ++ + message += get_media_specific_string(manifest.success, photos_message, videos_message, + both_message); + } +- ++ + int total = manifest.success.size + manifest.failed.size + manifest.camera_failed.size + + manifest.skipped_photos.size + manifest.skipped_files.size + + manifest.already_imported.size + manifest.aborted.size; + assert(total == manifest.all.size); +- ++ + // if no media items were imported at all (i.e. an empty directory attempted), need to at least + // report that nothing was imported + if (total == 0) + message += _("No photos or videos imported.\n"); +- ++ + Gtk.MessageDialog dialog = null; + if (question == null) { + dialog = new Gtk.MessageDialog(AppWindow.get_instance(), Gtk.DialogFlags.MODAL, + Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "%s", message); + } else { + message += ("\n" + question.question); +- ++ + dialog = new Gtk.MessageDialog(AppWindow.get_instance(), Gtk.DialogFlags.MODAL, + Gtk.MessageType.QUESTION, Gtk.ButtonsType.NONE, "%s", message); + dialog.add_button(question.no_button, Gtk.ResponseType.NO); + dialog.add_button(question.yes_button, Gtk.ResponseType.YES); + } +- ++ + dialog.title = _("Import Complete"); +- ++ + bool yes = (dialog.run() == Gtk.ResponseType.YES); +- ++ + dialog.destroy(); +- ++ + return yes; + } + } + + public abstract class TextEntryDialogMediator { + private TextEntryDialog dialog; +- ++ + public TextEntryDialogMediator(string title, string label, string? initial_text = null, + Gee.Collection<string>? completion_list = null, string? completion_delimiter = null) { + Gtk.Builder builder = AppWindow.create_builder(); +@@ -613,7 +613,7 @@ public abstract class TextEntryDialogMed + dialog.set_builder(builder); + dialog.setup(on_modify_validate, title, label, initial_text, completion_list, completion_delimiter); + } +- ++ + protected virtual bool on_modify_validate(string text) { + return true; + } +@@ -627,16 +627,16 @@ public abstract class TextEntryDialogMed + // Partly inspired by the class of the same name in gtkmm-utils by Marko Anastasov + public class EntryMultiCompletion : Gtk.EntryCompletion { + private string delimiter; +- ++ + public EntryMultiCompletion(Gee.Collection<string> completion_list, string? delimiter) { + assert(delimiter == null || delimiter.length == 1); + this.delimiter = delimiter; +- ++ + set_model(create_completion_store(completion_list)); + set_text_column(0); + set_match_func(match_func); + } +- ++ + private static Gtk.ListStore create_completion_store(Gee.Collection<string> completion_list) { + Gtk.ListStore completion_store = new Gtk.ListStore(1, typeof(string)); + Gtk.TreeIter store_iter; +@@ -645,22 +645,22 @@ public class EntryMultiCompletion : Gtk. + completion_store.append(out store_iter); + completion_store.set(store_iter, 0, completion_iter.get(), -1); + } +- ++ + return completion_store; + } +- ++ + private bool match_func(Gtk.EntryCompletion completion, string key, Gtk.TreeIter iter) { + Gtk.TreeModel model = completion.get_model(); + string possible_match; + model.get(iter, 0, out possible_match); +- ++ + // Normalize key and possible matches to allow comparison of non-ASCII characters. +- // Use a "COMPOSE" normalization to allow comparison to the position value returned by ++ // Use a "COMPOSE" normalization to allow comparison to the position value returned by + // Gtk.Entry, i.e. one character=one position. Using the default normalization a character + // like "é" or "ö" would have a length of two. +- possible_match = possible_match.casefold().normalize(-1, NormalizeMode.ALL_COMPOSE); ++ possible_match = possible_match.casefold().normalize(-1, NormalizeMode.ALL_COMPOSE); + string normed_key = key.normalize(-1, NormalizeMode.ALL_COMPOSE); +- ++ + if (delimiter == null) { + return possible_match.has_prefix(normed_key.strip()); + } else { +@@ -671,12 +671,12 @@ public class EntryMultiCompletion : Gtk. + if (position <= offset) + return false; // TODO: Autocompletion for tags not last in list + } +- ++ + string last_part = get_last_part(normed_key.strip(), delimiter); +- +- if (last_part.length == 0) ++ ++ if (last_part.length == 0) + return false; // need at least one character to show matches +- ++ + return possible_match.has_prefix(last_part.strip()); + } + } +@@ -684,9 +684,9 @@ public class EntryMultiCompletion : Gtk. + public override bool match_selected(Gtk.TreeModel model, Gtk.TreeIter iter) { + string match; + model.get(iter, 0, out match); +- ++ + Gtk.Entry entry = (Gtk.Entry)get_entry(); +- ++ + string old_text = entry.get_text(); + if (old_text.length > 0) { + if (old_text.contains(delimiter)) { +@@ -695,21 +695,21 @@ public class EntryMultiCompletion : Gtk. + } else + old_text = ""; + } +- ++ + string new_text = old_text + match + delimiter + (delimiter != " " ? " " : ""); + entry.set_text(new_text); + entry.set_position((int) new_text.length); +- ++ + return true; + } +- ++ + // Find last string after any delimiter + private static string get_last_part(string s, string delimiter) { + string[] split = s.split(delimiter); + int i = 0; + while (split[i+1] != null) + i++; +- ++ + return split[i]; + } + } +@@ -719,18 +719,18 @@ public class SetBackgroundSlideshowDialo + private Gtk.Label delay_value_label; + private Gtk.Scale delay_scale; + private int delay_value = 0; +- ++ + public SetBackgroundSlideshowDialog() { + Gtk.Builder builder = AppWindow.create_builder("set_background_dialog.glade", this); +- ++ + dialog = builder.get_object("dialog1") as Gtk.Dialog; + dialog.set_type_hint(Gdk.WindowTypeHint.DIALOG); + dialog.set_parent_window(AppWindow.get_instance().get_parent_window()); + dialog.set_transient_for(AppWindow.get_instance()); + dialog.set_default_response(Gtk.ResponseType.OK); +- ++ + delay_value_label = builder.get_object("delay_value_label") as Gtk.Label; +- ++ + delay_scale = builder.get_object("delay_scale") as Gtk.Scale; + delay_scale.value_changed.connect(on_delay_scale_value_changed); + delay_scale.adjustment.value = 50; +@@ -738,12 +738,12 @@ public class SetBackgroundSlideshowDialo + + private void on_delay_scale_value_changed() { + double value = delay_scale.adjustment.value; +- ++ + // f(x)=x^5 allows to have fine-grained values (seconds) to the left + // and very coarse-grained values (hours) to the right of the slider. + // We limit maximum value to 1 day and minimum to 5 seconds. + delay_value = (int) (Math.pow(value, 5) / Math.pow(90, 5) * 60 * 60 * 24 + 5); +- ++ + // convert to text and remove fractions from values > 1 minute + string text; + if (delay_value < 60) { +@@ -751,7 +751,7 @@ public class SetBackgroundSlideshowDialo + } else if (delay_value < 60 * 60) { + int minutes = delay_value / 60; + text = ngettext("%d minute", "%d minutes", minutes).printf(minutes); +- delay_value = minutes * 60; ++ delay_value = minutes * 60; + } else if (delay_value < 60 * 60 * 24) { + int hours = delay_value / (60 * 60); + text = ngettext("%d hour", "%d hours", hours).printf(hours); +@@ -760,35 +760,35 @@ public class SetBackgroundSlideshowDialo + text = _("1 day"); + delay_value = 60 * 60 * 24; + } +- ++ + delay_value_label.label = text; + } + + public bool execute(out int delay_value) { + dialog.show_all(); +- ++ + bool result = dialog.run() == Gtk.ResponseType.OK; +- ++ + dialog.destroy(); +- ++ + delay_value = this.delay_value; +- ++ + return result; + } + } + + public class TextEntryDialog : Gtk.Dialog { + public delegate bool OnModifyValidateType(string text); +- ++ + private OnModifyValidateType on_modify_validate; + private Gtk.Entry entry; + private Gtk.Builder builder; +- ++ + public void set_builder(Gtk.Builder builder) { + this.builder = builder; + } +- +- public void setup(OnModifyValidateType? modify_validate, string title, string label, ++ ++ public void setup(OnModifyValidateType? modify_validate, string title, string label, + string? initial_text, Gee.Collection<string>? completion_list, string? completion_delimiter) { + set_title(title); + set_parent_window(AppWindow.get_instance().get_parent_window()); +@@ -807,26 +807,26 @@ public class TextEntryDialog : Gtk.Dialo + completion_delimiter); + entry.set_completion(completion); + } +- ++ + set_default_response(Gtk.ResponseType.OK); + } + + public string? execute() { + string? text = null; +- ++ + // validate entry to start with + set_response_sensitive(Gtk.ResponseType.OK, on_modify_validate(entry.get_text())); +- ++ + show_all(); +- ++ + if (run() == Gtk.ResponseType.OK) + text = entry.get_text(); +- ++ + destroy(); +- ++ + return text; + } +- ++ + public void on_entry_changed() { + set_response_sensitive(Gtk.ResponseType.OK, on_modify_validate(entry.get_text())); + } +@@ -857,17 +857,17 @@ public class EditTitleDialog : TextEntry + public Gtk.ResponseType remove_from_library_dialog(Gtk.Window owner, string title, + string user_message, int count) { + string trash_action = ngettext("_Trash File", "_Trash Files", count); +- ++ + Gtk.MessageDialog dialog = new Gtk.MessageDialog(owner, Gtk.DialogFlags.MODAL, + Gtk.MessageType.WARNING, Gtk.ButtonsType.CANCEL, "%s", user_message); + dialog.add_button(_("Only _Remove"), Gtk.ResponseType.NO); + dialog.add_button(trash_action, Gtk.ResponseType.YES); + dialog.title = title; +- ++ + Gtk.ResponseType result = (Gtk.ResponseType) dialog.run(); +- ++ + dialog.destroy(); +- ++ + return result; + } + +@@ -880,11 +880,11 @@ public Gtk.ResponseType remove_from_file + dialog.add_button(_("_Delete"), Gtk.ResponseType.YES); + dialog.set_default_response( Gtk.ResponseType.NO); + dialog.title = title; +- ++ + Gtk.ResponseType result = (Gtk.ResponseType) dialog.run(); +- ++ + dialog.destroy(); +- ++ + return result; + } + +@@ -894,48 +894,48 @@ public bool revert_editable_dialog(Gtk.W + if (photo.has_editable()) + count++; + } +- ++ + if (count == 0) + return false; +- ++ + string msg = ngettext( + "This will destroy all changes made to the external file. Continue?", + "This will destroy all changes made to %d external files. Continue?", + count).printf(count); + string action = ngettext("Re_vert External Edit", "Re_vert External Edits", count); +- ++ + Gtk.MessageDialog dialog = new Gtk.MessageDialog(owner, Gtk.DialogFlags.MODAL, + Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, "%s", msg); + dialog.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL); + dialog.add_button(action, Gtk.ResponseType.YES); + dialog.title = ngettext("Revert External Edit", "Revert External Edits", count); +- ++ + Gtk.ResponseType result = (Gtk.ResponseType) dialog.run(); +- ++ + dialog.destroy(); +- ++ + return result == Gtk.ResponseType.YES; + } + + public bool remove_offline_dialog(Gtk.Window owner, int count) { + if (count == 0) + return false; +- ++ + string msg = ngettext( + "This will remove the photo from the library. Continue?", + "This will remove %d photos from the library. Continue?", + count).printf(count); +- ++ + Gtk.MessageDialog dialog = new Gtk.MessageDialog(owner, Gtk.DialogFlags.MODAL, + Gtk.MessageType.WARNING, Gtk.ButtonsType.NONE, "%s", msg); + dialog.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL); + dialog.add_button(_("_Remove"), Gtk.ResponseType.OK); + dialog.title = ngettext("Remove Photo From Library", "Remove Photos From Library", count); +- ++ + Gtk.ResponseType result = (Gtk.ResponseType) dialog.run(); +- ++ + dialog.destroy(); +- ++ + return result == Gtk.ResponseType.OK; + } + +@@ -945,34 +945,34 @@ public class ProgressDialog : Gtk.Window + private Cancellable cancellable; + private uint64 last_count = uint64.MAX; + private int update_every = 1; +- ++ + public ProgressDialog(Gtk.Window? owner, string text, Cancellable? cancellable = null) { + this.cancellable = cancellable; +- ++ + set_title(text); + set_resizable(false); + if (owner != null) + set_transient_for(owner); + set_modal(true); + set_type_hint(Gdk.WindowTypeHint.DIALOG); +- ++ + progress_bar.set_size_request(300, -1); +- ++ + Gtk.VBox vbox_bar = new Gtk.VBox(false, 0); + vbox_bar.pack_start(progress_bar, true, false, 0); +- ++ + if (cancellable != null) { + cancel_button = new Gtk.Button.from_stock(Gtk.STOCK_CANCEL); + cancel_button.clicked.connect(on_cancel); + delete_event.connect(on_window_closed); + } +- ++ + Gtk.HBox hbox = new Gtk.HBox(false, 8); + hbox.pack_start(vbox_bar, true, false, 0); + if (cancel_button != null) + hbox.pack_end(cancel_button, false, false, 0); +- +- ++ ++ + Gtk.Label primary_text_label = new Gtk.Label(""); + primary_text_label.set_markup("<span weight=\"bold\">%s</span>".printf(text)); + primary_text_label.set_alignment(0, 0.5f); +@@ -984,65 +984,65 @@ public class ProgressDialog : Gtk.Window + Gtk.Alignment alignment = new Gtk.Alignment(0.5f, 0.5f, 1.0f, 1.0f); + alignment.set_padding(12, 12, 12, 12); + alignment.add(vbox); +- ++ + add(alignment); +- ++ + show_all(); +- ++ + if (cancellable == null) + window.set_functions(Gdk.WMFunction.MOVE); + } +- ++ + public void update_display_every(int update_every) { + assert(update_every >= 1); +- ++ + this.update_every = update_every; + } +- ++ + public void set_fraction(int current, int total) { + set_percentage((double) current / (double) total); + } +- ++ + public void set_percentage(double pct) { + pct = pct.clamp(0.0, 1.0); +- ++ + progress_bar.set_fraction(pct); + progress_bar.set_text(_("%d%%").printf((int) (pct * 100.0))); + } +- ++ + // This can be used as a ProgressMonitor delegate. + public bool monitor(uint64 count, uint64 total) { + if (last_count == uint64.MAX) + last_count = count; +- ++ + if ((count - last_count) > update_every) { + set_percentage((double) count / (double) total); +- ++ + // TODO: get rid of this. non-trivial, as some progress-monitor operations are blocking + // and need to allow the event loop to spin + spin_event_loop(); +- ++ + last_count = count; + } +- ++ + return (cancellable != null) ? !cancellable.is_cancelled() : true; + } +- ++ + public void close() { + hide(); + destroy(); + } +- ++ + private bool on_window_closed() { + on_cancel(); + return false; // return false so that the system handler will remove the window from + // the screen + } +- ++ + private void on_cancel() { + if (cancellable != null) + cancellable.cancel(); +- ++ + cancel_button.sensitive = false; + } + } +@@ -1070,7 +1070,7 @@ public class AdjustDateTimeDialog : Gtk. + AM, + PM, + 24HR; +- } ++ } + + TimeSystem previous_time_system; + +@@ -1082,7 +1082,7 @@ public class AdjustDateTimeDialog : Gtk. + has_separator = false; + set_transient_for(AppWindow.get_instance()); + +- add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, ++ add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OK, Gtk.ResponseType.OK); + set_title(Resources.ADJUST_DATE_TIME_LABEL); + +@@ -1098,7 +1098,7 @@ public class AdjustDateTimeDialog : Gtk. + hour = new Gtk.SpinButton.with_range(1, 12, 1); + + hour.output.connect(on_spin_button_output); +- hour.set_width_chars(2); ++ hour.set_width_chars(2); + + minute = new Gtk.SpinButton.with_range(0, 59, 1); + minute.set_width_chars(2); +@@ -1124,8 +1124,8 @@ public class AdjustDateTimeDialog : Gtk. + clock.pack_start(system, false, false, 3); + + set_default_response(Gtk.ResponseType.OK); +- +- relativity_radio_button = new Gtk.RadioButton.with_mnemonic(null, ++ ++ relativity_radio_button = new Gtk.RadioButton.with_mnemonic(null, + _("_Shift photos by the same amount")); + relativity_radio_button.set_active(Config.get_instance().get_keep_relativity()); + relativity_radio_button.sensitive = display_options && photo_count > 1; +@@ -1155,12 +1155,12 @@ public class AdjustDateTimeDialog : Gtk. + + Gdk.Pixbuf preview = null; + try { +- preview = source.get_pixbuf(Scaling.for_viewport(Dimensions(500, ++ preview = source.get_pixbuf(Scaling.for_viewport(Dimensions(500, + display_options ? 280 : 200), false)); + } catch (Error err) { + warning("Unable to fetch preview for %s", source.to_string()); + } +- ++ + Gtk.VBox image_content = new Gtk.VBox(false, 0); + Gtk.Image image = (preview != null) ? new Gtk.Image.from_pixbuf(preview) : new Gtk.Image(); + original_time_label = new Gtk.Label(null); +@@ -1184,7 +1184,7 @@ public class AdjustDateTimeDialog : Gtk. + notification.set_padding(12, 6); + + vbox.pack_start(notification, true, true, 0); +- ++ + original_time = source.get_exposure_time(); + + if (original_time == 0) { +@@ -1219,7 +1219,7 @@ public class AdjustDateTimeDialog : Gtk. + if (no_original_time) + return; + +- original_time_label.set_text(_("Original: ") + ++ original_time_label.set_text(_("Original: ") + + Time.local(original_time).format(use_24_hr_format ? _("%m/%d/%Y, %H:%M:%S") : + _("%m/%d/%Y, %I:%M:%S %p"))); + } +@@ -1246,7 +1246,7 @@ public class AdjustDateTimeDialog : Gtk. + return time.mktime(); + } + +- public bool execute(out int64 time_shift, out bool keep_relativity, ++ public bool execute(out int64 time_shift, out bool keep_relativity, + out bool modify_originals) { + show_all(); + +@@ -1310,8 +1310,8 @@ public class AdjustDateTimeDialog : Gtk. + _("Exposure time will be shifted backward by\n%d %s, %d %s, %d %s, and %d %s."); + + notification.set_text(shift_status.printf(days, ngettext("day", "days", days), +- hours, ngettext("hour", "hours", hours), minutes, +- ngettext("minute", "minutes", minutes), seconds, ++ hours, ngettext("hour", "hours", hours), minutes, ++ ngettext("minute", "minutes", minutes), seconds, + ngettext("second", "seconds", seconds))); + + notification.show(); +@@ -1346,7 +1346,7 @@ public class AdjustDateTimeDialog : Gtk. + } + + public const int MAX_OBJECTS_DISPLAYED = 3; +-public void multiple_object_error_dialog(Gee.ArrayList<DataObject> objects, string message, ++public void multiple_object_error_dialog(Gee.ArrayList<DataObject> objects, string message, + string title) { + string dialog_message = message + "\n"; + +@@ -1362,9 +1362,9 @@ public void multiple_object_error_dialog + + Gtk.MessageDialog dialog = new Gtk.MessageDialog(AppWindow.get_instance(), + Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, "%s", dialog_message); +- ++ + dialog.title = title; +- ++ + dialog.run(); + dialog.destroy(); + } +@@ -1384,7 +1384,7 @@ public class AddTagsDialog : TagsDialog + string? text = _execute(); + if (text == null) + return null; +- ++ + // only want to return null if the user chose cancel, however, on_modify_validate ensures + // that Tag.prep_tag_names won't return a zero-length array (and it never returns null) + return Tag.prep_tag_names(text.split(",")); +@@ -1394,57 +1394,57 @@ public class AddTagsDialog : TagsDialog + // Can't simply call Tag.prep_tag_names().length because of this bug: + // https://bugzilla.gnome.org/show_bug.cgi?id=602208 + string[] names = Tag.prep_tag_names(text.split(",")); +- ++ + return names.length > 0; + } + } + + public class ModifyTagsDialog : TagsDialog { + public ModifyTagsDialog(MediaSource source) { +- base (Resources.MODIFY_TAGS_LABEL, _("Tags (separated by commas):"), ++ base (Resources.MODIFY_TAGS_LABEL, _("Tags (separated by commas):"), + get_initial_text(source)); + } +- ++ + private static string? get_initial_text(MediaSource source) { + Gee.SortedSet<Tag>? sorted_tags = Tag.global.fetch_sorted_for_source(source); +- ++ + if (sorted_tags == null) + return null; +- ++ + string[] tag_names = new string[0]; + foreach (Tag tag in sorted_tags) + tag_names += tag.get_name(); +- ++ + string? text = null; + foreach (string tag in tag_names) { + if (text == null) + text = ""; + else + text += ", "; +- ++ + text += tag; + } +- ++ + return text; + } +- ++ + public Gee.ArrayList<Tag>? execute() { + string? text = _execute(); + if (text == null) + return null; +- ++ + Gee.ArrayList<Tag> new_tags = new Gee.ArrayList<Tag>(); +- ++ + // return empty list if no tags specified + if (is_string_empty(text)) + return new_tags; +- ++ + // break up by comma-delimiter, prep for use, and separate into list + string[] tag_names = Tag.prep_tag_names(text.split(",")); + + foreach (string name in tag_names) + new_tags.add(Tag.for_name(name)); +- ++ + return new_tags; + } + } +@@ -1475,13 +1475,13 @@ public class WelcomeDialog : Gtk.Dialog + } + secondary_text.set_alignment(0, 0.5f); + Gtk.Image image = new Gtk.Image.from_pixbuf(Resources.get_icon(Resources.ICON_APP, 50)); +- ++ + Gtk.Widget? header_text = null; + if (show_fspot_import || show_system_pictures_import) { + header_text = primary_text; + } else { + header_text = new Gtk.VBox(false, 0); +- ++ + ((Gtk.VBox) header_text).pack_start(primary_text, false, false, 5); + ((Gtk.VBox) header_text).pack_start(secondary_text, false, false, 0); + } +@@ -1498,18 +1498,18 @@ public class WelcomeDialog : Gtk.Dialog + _("Drag and drop photos onto the Shotwell window"), + _("Connect a camera to your computer and import"))); + instructions.set_alignment(0, 0.5f); +- ++ + Gtk.VBox? import_action_checkbox_packer = null; + if (show_fspot_import || show_system_pictures_import) { + import_action_checkbox_packer = new Gtk.VBox(false, 2); +- ++ + if (show_fspot_import) { + fspot_import_check = new Gtk.CheckButton.with_mnemonic( + _("Import photos from your _F-Spot library")); + import_action_checkbox_packer.add(fspot_import_check); + fspot_import_check.set_active(true); + } +- ++ + if (show_system_pictures_import) { + system_pictures_import_check = new Gtk.CheckButton.with_mnemonic( + _("_Import photos from your %s folder").printf( +@@ -1518,14 +1518,14 @@ public class WelcomeDialog : Gtk.Dialog + system_pictures_import_check.set_active(true); + } + } +- ++ + Gtk.Label? instruction_header = null; + if (show_fspot_import || show_system_pictures_import) { + instruction_header = new Gtk.Label( + _("You can also import photos in any of these ways:")); + instruction_header.set_alignment(0.0f, 0.5f); + } +- ++ + Gtk.VBox content = new Gtk.VBox(false, 16); + content.pack_start(header_content, true, true, 0); + if (show_fspot_import || show_system_pictures_import) { +@@ -1537,7 +1537,7 @@ public class WelcomeDialog : Gtk.Dialog + hide_button = new Gtk.CheckButton.with_mnemonic(_("_Don't show this message again")); + hide_button.set_active(true); + content.pack_start(hide_button, false, false, 6); +- ++ + Gtk.Alignment alignment = new Gtk.Alignment(0, 0, 0, 0); + alignment.set_padding(12, 0, 12, 12); + alignment.add(content); +@@ -1555,7 +1555,7 @@ public class WelcomeDialog : Gtk.Dialog + + if (ok) + show_dialog = !hide_button.get_active(); +- ++ + if (fspot_import_check != null) + do_fspot_import = fspot_import_check.get_active(); + if (system_pictures_import_check != null) +@@ -1565,12 +1565,12 @@ public class WelcomeDialog : Gtk.Dialog + + return show_dialog; + } +- ++ + private static bool is_system_pictures_import_possible() { + File system_pictures = AppDirs.get_import_dir(); + if (!system_pictures.query_exists(null)) + return false; +- ++ + if (!(system_pictures.query_file_type(FileQueryInfoFlags.NONE, null) == FileType.DIRECTORY)) + return false; + +@@ -1582,7 +1582,7 @@ public class WelcomeDialog : Gtk.Dialog + return false; + } + } +- ++ + private static bool is_fspot_import_possible() { + return FSpotDatabaseDriver.is_available(); + } +@@ -1611,7 +1611,7 @@ public class PreferencesDialog { + dialog.response.connect(on_close); + + bg_color_adjustment = builder.get_object("bg_color_adjustment") as Gtk.Adjustment; +- bg_color_adjustment.set_value(bg_color_adjustment.get_upper() - ++ bg_color_adjustment.set_value(bg_color_adjustment.get_upper() - + Config.get_instance().get_bg_color().red); + bg_color_adjustment.value_changed.connect(on_value_changed); + +@@ -1619,7 +1619,7 @@ public class PreferencesDialog { + bg_color_slider.button_press_event.connect(on_bg_color_reset); + + library_dir_button = builder.get_object("library_dir_button") as Gtk.FileChooserButton; +- ++ + photo_editor_combo = builder.get_object("external_photo_editor_combo") as Gtk.ComboBox; + raw_editor_combo = builder.get_object("external_raw_editor_combo") as Gtk.ComboBox; + +@@ -1627,33 +1627,33 @@ public class PreferencesDialog { + + photo_editor_combo.changed.connect(on_photo_editor_changed); + raw_editor_combo.changed.connect(on_raw_editor_changed); +- ++ + Gtk.CheckButton auto_import_button = builder.get_object("autoimport") as Gtk.CheckButton; + auto_import_button.set_active(Config.get_instance().get_auto_import_from_library()); +- ++ + Gtk.CheckButton commit_metadata_button = builder.get_object("write_metadata") as Gtk.CheckButton; + commit_metadata_button.set_active(Config.get_instance().get_commit_metadata_to_masters()); +- ++ + dialog.map_event.connect(map_event); + } +- ++ + public void populate_preference_options() { +- populate_app_combo_box(photo_editor_combo, PhotoFileFormat.get_editable_mime_types(), ++ populate_app_combo_box(photo_editor_combo, PhotoFileFormat.get_editable_mime_types(), + Config.get_instance().get_external_photo_app(), out external_photo_apps); + +- populate_app_combo_box(raw_editor_combo, PhotoFileFormat.RAW.get_mime_types(), ++ populate_app_combo_box(raw_editor_combo, PhotoFileFormat.RAW.get_mime_types(), + Config.get_instance().get_external_raw_app(), out external_raw_apps); + } +- ++ + private void populate_app_combo_box(Gtk.ComboBox combo_box, string[] mime_types, + string current_app_executable, out SortedList<AppInfo> external_apps) { + // get list of all applications for the given mime types + assert(mime_types.length != 0); + external_apps = DesktopIntegration.get_apps_for_mime_types(mime_types); +- ++ + if (external_apps.size == 0) + return; +- ++ + // populate application ComboBox with app names and icons + Gtk.CellRendererPixbuf pixbuf_renderer = new Gtk.CellRendererPixbuf(); + Gtk.CellRendererText text_renderer = new Gtk.CellRendererText(); +@@ -1662,13 +1662,13 @@ public class PreferencesDialog { + combo_box.pack_start(text_renderer, false); + combo_box.add_attribute(pixbuf_renderer, "pixbuf", 0); + combo_box.add_attribute(text_renderer, "text", 1); +- ++ + // TODO: need more space between icons and text + Gtk.ListStore combo_store = new Gtk.ListStore(2, typeof(Gdk.Pixbuf), typeof(string)); + Gtk.TreeIter iter; +- ++ + int current_app = -1; +- ++ + foreach (AppInfo app in external_apps) { + combo_store.append(out iter); + +@@ -1679,10 +1679,10 @@ public class PreferencesDialog { + ((FileIcon) app_icon).get_file().get_path()), Resources.DEFAULT_ICON_SCALE, + Gdk.InterpType.BILINEAR, false)); + } else if (app_icon is ThemedIcon) { +- unowned Gdk.Pixbuf icon_pixbuf = ++ Gdk.Pixbuf icon_pixbuf = + Gtk.IconTheme.get_default().load_icon(((ThemedIcon) app_icon).get_names()[0], + Resources.DEFAULT_ICON_SCALE, Gtk.IconLookupFlags.FORCE_SIZE); +- ++ + combo_store.set_value(iter, 0, icon_pixbuf); + } + } catch (GLib.Error error) { +@@ -1690,11 +1690,11 @@ public class PreferencesDialog { + } + + combo_store.set_value(iter, 1, app.get_name()); +- ++ + if (app.get_commandline() == current_app_executable) + current_app = external_apps.index_of(app); + } +- ++ + // TODO: allow users to choose unlisted applications like Nautilus's "Open with -> Other Application..." + + combo_box.set_model(combo_store); +@@ -1702,45 +1702,45 @@ public class PreferencesDialog { + if (current_app != -1) + combo_box.set_active(current_app); + } +- ++ + public static void show() { +- if (preferences_dialog == null) ++ if (preferences_dialog == null) + preferences_dialog = new PreferencesDialog(); +- ++ + preferences_dialog.populate_preference_options(); + preferences_dialog.dialog.show_all(); + preferences_dialog.library_dir_button.set_current_folder(AppDirs.get_import_dir().get_path()); + } +- ++ + // For items that should only be committed when the dialog is closed, not as soon as the change + // is made. + private void commit_on_close() { + Config.get_instance().commit_bg_color(); +- ++ + Gtk.CheckButton? autoimport = builder.get_object("autoimport") as Gtk.CheckButton; + if (autoimport != null) + Config.get_instance().set_auto_import_from_library(autoimport.active); +- ++ + Gtk.CheckButton? commit_metadata = builder.get_object("write_metadata") as Gtk.CheckButton; + if (commit_metadata != null) + Config.get_instance().set_commit_metadata_to_masters(commit_metadata.active); +- ++ + if (lib_dir != null) + AppDirs.set_import_dir(lib_dir); + } +- ++ + private bool on_delete() { + commit_on_close(); +- ++ + return dialog.hide_on_delete(); //prevent widgets from getting destroyed + } +- ++ + private void on_close() { + dialog.hide(); +- ++ + commit_on_close(); + } +- ++ + private void on_value_changed() { + set_background_color(bg_color_adjustment.get_upper() - bg_color_adjustment.get_value()); + } +@@ -1763,14 +1763,14 @@ public class PreferencesDialog { + + private Gdk.Color to_grayscale(uint16 color_value) { + Gdk.Color color = Gdk.Color(); +- ++ + color.red = color_value; + color.green = color_value; + color.blue = color_value; +- ++ + return color; + } +- ++ + private void on_photo_editor_changed() { + AppInfo app = external_photo_apps.get_at(photo_editor_combo.get_active()); + +@@ -1779,21 +1779,21 @@ public class PreferencesDialog { + debug("setting external photo editor to: %s", DesktopIntegration.get_app_open_command(app)); + + } +- ++ + private void on_raw_editor_changed() { + AppInfo app = external_raw_apps.get_at(raw_editor_combo.get_active()); +- ++ + Config.get_instance().set_external_raw_app(app.get_commandline()); +- ++ + debug("setting external raw editor to: %s", app.get_commandline()); + } +- ++ + private void on_current_folder_changed() { + lib_dir = library_dir_button.get_current_folder(); + } +- ++ + private bool map_event() { +- // Set the signal for the lib dir button after the dialog is displayed, ++ // Set the signal for the lib dir button after the dialog is displayed, + // because the FileChooserButton has a nasty habbit of selecting a + // different folder when displayed if the provided path doesn't exist. + // See ticket #3000 for more info. +@@ -1815,7 +1815,7 @@ public Gtk.ResponseType copy_files_dialo + dialog.title = _("Import to Library"); + + Gtk.ResponseType result = (Gtk.ResponseType) dialog.run(); +- ++ + dialog.destroy(); + + return result; |