Commit cdea6b98 authored by Allison Barlow's avatar Allison Barlow

Adds the Queryable class and classes for boxing stucts, changes Photo's

query_filesize to get_filesize, and moves set/get_dimensions to Exif from
PhotoExif.
parent 210c130d
......@@ -44,7 +44,8 @@ SRC_FILES = \
Debug.vala \
Sidebar.vala \
ColorTransformation.vala \
EditingTools.vala
EditingTools.vala \
Queryable.vala
VAPI_FILES = \
libexif.vapi \
......
......@@ -4,7 +4,7 @@
* See the COPYING file in this distribution.
*/
public abstract class LayoutItem : Gtk.Alignment {
public abstract class LayoutItem : Gtk.Alignment, Queryable {
public const int LABEL_PADDING = 4;
public const int FRAME_PADDING = 4;
......@@ -169,6 +169,12 @@ public abstract class LayoutItem : Gtk.Alignment {
image.set_from_pixbuf(pixbuf);
brightened = false;
}
public abstract Queryable.Type get_queryable_type();
public abstract Value? query_property(Queryable.Property property);
public abstract Gee.Iterable<Queryable>? get_queryables();
}
public class CollectionLayout : Gtk.Layout {
......
......@@ -163,6 +163,16 @@ class SlideshowPage : SinglePhotoPage {
return (base.key_press_event != null) ? base.key_press_event(event) : true;
}
public override Gee.Iterable<Queryable>? get_queryables() {
Gee.ArrayList<Photo> photo_array_list = new Gee.ArrayList<Photo>();
photo_array_list.add(thumbnail.get_photo());
return photo_array_list;
}
public override Gee.Iterable<Queryable>? get_selected_queryables() {
return get_queryables();
}
}
public class CollectionPage : CheckerboardPage {
......
......@@ -960,6 +960,13 @@ public class EventTable : DatabaseTable {
return (time_t) stmt.column_int64(0);
}
public time_t get_end_time(EventID event_id) {
Sqlite.Statement stmt;
if (!select_by_id(event_id.id, "end_time", out stmt))
return 0;
return (time_t) stmt.column_int64(0);
}
public bool set_end_time(EventID event_id, time_t end_time) {
Sqlite.Statement stmt;
int res = db.prepare_v2("UPDATE EventTable SET end_time = ? WHERE id = ?", -1, out stmt);
......
......@@ -25,6 +25,42 @@ public class DirectoryItem : LayoutItem {
set_image(pixbuf);
}
public override Queryable.Type get_queryable_type() {
return Queryable.Type.EVENT;
}
public override Value? query_property(Queryable.Property queryable_property) {
switch (queryable_property) {
case Queryable.Property.NAME:
return get_title();
case Queryable.Property.COUNT:
return get_photo_count();
case Queryable.Property.START_TIME:
return new BoxedTime((new EventTable()).get_start_time(event_id));
case Queryable.Property.END_TIME:
return new BoxedTime((new EventTable()).get_end_time(event_id));
default:
return null;
}
}
public override Gee.Iterable<Queryable>? get_queryables() {
Gee.ArrayList<PhotoID?> photo_ids = (new PhotoTable()).get_event_photos(event_id);
Gee.ArrayList<Photo> photos = new Gee.ArrayList<Photo>();
foreach (PhotoID photo_id in photo_ids) {
photos.add(Photo.fetch(photo_id));
}
return photos;
}
private int get_photo_count() {
return (new PhotoTable()).get_event_photos(event_id).size;
}
}
public class EventsDirectoryPage : CheckerboardPage {
......
......@@ -72,6 +72,76 @@ namespace Exif {
return false;
}
private Exif.Entry? find_entry_multiformat(Exif.Data exif, Exif.Ifd ifd, Exif.Tag tag,
Exif.Format format1, Exif.Format format2) {
assert(exif != null);
Exif.Content content = exif.ifd[(int) ifd];
assert(content != null);
Exif.Entry entry = content.get_entry(tag);
if (entry == null)
return null;
assert((entry.format == format1) || (entry.format == format2));
if ((entry.format != Exif.Format.ASCII) && (entry.format != Exif.Format.UNDEFINED))
assert((entry.size == format1.get_size()) || (entry.size == format2.get_size()));
return entry;
}
public bool get_dimensions(Exif.Data exif, out Dimensions dim) {
Exif.Entry width = find_entry_multiformat(exif, Exif.Ifd.EXIF,
Exif.Tag.PIXEL_X_DIMENSION, Exif.Format.SHORT, Exif.Format.LONG);
Exif.Entry height = find_entry_multiformat(exif, Exif.Ifd.EXIF,
Exif.Tag.PIXEL_Y_DIMENSION, Exif.Format.SHORT, Exif.Format.LONG);
if ((width == null) || (height == null))
return false;
if (width.format == Exif.Format.SHORT) {
dim.width = Exif.Convert.get_short(width.data, exif.get_byte_order());
} else {
assert(width.format == Exif.Format.LONG);
dim.width = (int) Exif.Convert.get_long(width.data, exif.get_byte_order());
}
if (height.format == Exif.Format.SHORT) {
dim.height = Exif.Convert.get_short(height.data, exif.get_byte_order());
} else {
assert(height.format == Exif.Format.LONG);
dim.height = (int) Exif.Convert.get_long(height.data, exif.get_byte_order());
}
return true;
}
public void set_dimensions(ref Exif.Data exif, Dimensions dim) {
Exif.Entry width = Exif.find_entry_multiformat(exif, Exif.Ifd.EXIF,
Exif.Tag.PIXEL_X_DIMENSION, Exif.Format.SHORT, Exif.Format.LONG);
Exif.Entry height = Exif.find_entry_multiformat(exif, Exif.Ifd.EXIF,
Exif.Tag.PIXEL_Y_DIMENSION, Exif.Format.SHORT, Exif.Format.LONG);
if ((width == null) || (height == null))
return;
if (width.format == Exif.Format.SHORT) {
Exif.Convert.set_short(width.data, exif.get_byte_order(), (uint16) dim.width);
} else {
assert(width.format == Exif.Format.LONG);
Exif.Convert.set_long(width.data, exif.get_byte_order(), dim.width);
}
if (height.format == Exif.Format.SHORT) {
Exif.Convert.set_short(height.data, exif.get_byte_order(), (uint16) dim.height);
} else {
assert(height.format == Exif.Format.LONG);
Exif.Convert.set_long(height.data, exif.get_byte_order(), dim.height);
}
}
}
public errordomain ExifError {
......@@ -193,58 +263,14 @@ public class PhotoExif {
public bool get_dimensions(out Dimensions dim) {
update();
Exif.Entry width = find_entry_multiformat(Exif.Ifd.EXIF, Exif.Tag.PIXEL_X_DIMENSION,
Exif.Format.SHORT, Exif.Format.LONG);
Exif.Entry height = find_entry_multiformat(Exif.Ifd.EXIF, Exif.Tag.PIXEL_Y_DIMENSION,
Exif.Format.SHORT, Exif.Format.LONG);
if ((width == null) || (height == null))
return false;
if (width.format == Exif.Format.SHORT) {
dim.width = Exif.Convert.get_short(width.data, exif.get_byte_order());
} else {
assert(width.format == Exif.Format.LONG);
dim.width = (int) Exif.Convert.get_long(width.data, exif.get_byte_order());
}
if (height.format == Exif.Format.SHORT) {
dim.height = Exif.Convert.get_short(height.data, exif.get_byte_order());
} else {
assert(height.format == Exif.Format.LONG);
dim.height = (int) Exif.Convert.get_long(height.data, exif.get_byte_order());
}
return true;
return Exif.get_dimensions(exif, out dim);
}
public void set_dimensions(Dimensions dim) {
update();
Exif.Entry width = find_entry_multiformat(Exif.Ifd.EXIF, Exif.Tag.PIXEL_X_DIMENSION,
Exif.Format.SHORT, Exif.Format.LONG);
Exif.Entry height = find_entry_multiformat(Exif.Ifd.EXIF, Exif.Tag.PIXEL_Y_DIMENSION,
Exif.Format.SHORT, Exif.Format.LONG);
if ((width == null) || (height == null))
return;
if (width.format == Exif.Format.SHORT) {
Exif.Convert.set_short(width.data, exif.get_byte_order(), (uint16) dim.width);
} else {
assert(width.format == Exif.Format.LONG);
Exif.Convert.set_long(width.data, exif.get_byte_order(), dim.width);
}
if (height.format == Exif.Format.SHORT) {
Exif.Convert.set_short(height.data, exif.get_byte_order(), (uint16) dim.height);
} else {
assert(height.format == Exif.Format.LONG);
Exif.Convert.set_long(height.data, exif.get_byte_order(), dim.height);
}
Exif.set_dimensions(ref exif, dim);
}
public string? get_datetime() {
......@@ -332,23 +358,7 @@ public class PhotoExif {
return Exif.find_first_entry(exif, tag, format);
}
private Exif.Entry? find_entry_multiformat(Exif.Ifd ifd, Exif.Tag tag, Exif.Format format1,
Exif.Format format2) {
assert(exif != null);
Exif.Content content = exif.ifd[(int) ifd];
assert(content != null);
Exif.Entry entry = content.get_entry(tag);
if (entry == null)
return null;
assert((entry.format == format1) || (entry.format == format2));
if ((entry.format != Exif.Format.ASCII) && (entry.format != Exif.Format.UNDEFINED))
assert((entry.size == format1.get_size()) || (entry.size == format2.get_size()));
return entry;
}
public void commit() throws Error {
if (exif == null)
......
......@@ -41,6 +41,50 @@ class ImportPreview : LayoutItem {
// honor rotation and display
set_image(orientation.rotate_pixbuf(scaled));
}
public override Queryable.Type get_queryable_type() {
return Queryable.Type.IMPORT_PREVIEW;
}
public override Value? query_property(Queryable.Property queryable_property) {
switch (queryable_property) {
case Queryable.Property.NAME:
return filename;
case Queryable.Property.DIMENSIONS:
Dimensions dimensions;
if(!Exif.get_dimensions(exif, out dimensions))
return null;
return new BoxedDimensions(dimensions);
case Queryable.Property.TIME:
return new BoxedTime(get_time());
case Queryable.Property.SIZE:
return get_filesize();
case Queryable.Property.EXIF:
return exif;
default:
return null;
}
}
public override Gee.Iterable<Queryable>? get_queryables() {
return null;
}
public time_t get_time() {
time_t exposure_time;
if (!Exif.get_timestamp(exif, out exposure_time))
exposure_time = 0;
return exposure_time;
}
public uint64 get_filesize() {
return file_size;
}
}
public class ImportPage : CheckerboardPage {
......@@ -764,7 +808,7 @@ public class ImportQueuePage : SinglePhotoPage {
private void on_imported(Photo photo) {
set_pixbuf(photo.get_pixbuf());
progress_bytes += photo.query_filesize();
progress_bytes += photo.get_filesize();
double pct = (progress_bytes <= total_bytes) ? (double) progress_bytes / (double) total_bytes
: 0.0;
......@@ -793,4 +837,12 @@ public class ImportQueuePage : SinglePhotoPage {
stop_button.sensitive = false;
}
}
public override Gee.Iterable<Queryable>? get_queryables() {
return null;
}
public override Gee.Iterable<Queryable>? get_selected_queryables() {
return get_queryables();
}
}
......@@ -404,6 +404,10 @@ public abstract class Page : Gtk.ScrolledWindow {
return on_motion(event, x, y, mask);
}
public abstract Gee.Iterable<Queryable>? get_queryables();
public abstract Gee.Iterable<Queryable>? get_selected_queryables();
}
public abstract class CheckerboardPage : Page {
......@@ -1158,6 +1162,14 @@ public abstract class CheckerboardPage : Page {
select(item);
}
}
public override Gee.Iterable<Queryable>? get_queryables() {
return get_selected();
}
public override Gee.Iterable<Queryable>? get_selected_queryables() {
return get_items();
}
}
public abstract class SinglePhotoPage : Page {
......
......@@ -15,7 +15,7 @@ public enum ImportResult {
UNSUPPORTED_FORMAT
}
public class Photo : Object {
public class Photo : Object, Queryable {
public const int EXCEPTION_NONE = 0;
public const int EXCEPTION_ORIENTATION = 1 << 0;
public const int EXCEPTION_CROP = 1 << 1;
......@@ -171,19 +171,39 @@ public class Photo : Object {
public string get_name() {
return photo_table.get_name(photo_id);
}
public uint64 query_filesize() {
FileInfo info = null;
try {
info = get_file().query_info(FILE_ATTRIBUTE_STANDARD_SIZE,
FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
} catch (Error err) {
debug("Unable to query filesize for %s: %s", get_file().get_path(), err.message);
return 0;
public Queryable.Type get_queryable_type() {
return Queryable.Type.PHOTO;
}
public Value? query_property(Queryable.Property queryable_property) {
switch (queryable_property) {
case Queryable.Property.NAME:
return get_name();
case Queryable.Property.DIMENSIONS:
return new BoxedDimensions(get_dimensions());
case Queryable.Property.TIME:
return new BoxedTime(get_exposure_time());
case Queryable.Property.SIZE:
return get_filesize();
case Queryable.Property.EXIF:
return (new PhotoExif(get_file())).get_exif();
default:
return null;
}
return info.get_size();
}
public Gee.Iterable<Queryable>? get_queryables() {
return null;
}
public uint64 get_filesize() {
return photo_table.get_filesize(photo_id);
}
public time_t get_exposure_time() {
......
......@@ -655,5 +655,15 @@ public class PhotoPage : SinglePhotoPage {
this.thumbnail = (Thumbnail) controller.get_previous_item(thumbnail);
update_display();
}
public override Gee.Iterable<Queryable>? get_queryables() {
Gee.ArrayList<Photo> photo_array_list = new Gee.ArrayList<Photo>();
photo_array_list.add(photo);
return photo_array_list;
}
public override Gee.Iterable<Queryable>? get_selected_queryables() {
return get_queryables();
}
}
/* Copyright 2009 Yorba Foundation
*
* This software is licensed under the GNU LGPL (version 2.1 or later).
* See the COPYING file in this distribution.
*/
// Value doesn't box structs, so use the following classes to box manually until the bug is fixed:
// http://bugzilla.gnome.org/show_bug.cgi?id=590987
public abstract class BoxedStruct {
}
public class BoxedTime : BoxedStruct {
public time_t time;
public BoxedTime(time_t time) {
this.time = time;
}
}
public class BoxedDimensions : BoxedStruct {
public Dimensions dimensions;
public BoxedDimensions(Dimensions dimensions) {
this.dimensions = dimensions;
}
}
public interface Queryable {
public enum Type {
EVENT,
PHOTO,
IMPORT_PREVIEW
}
public enum Property {
NAME,
START_TIME,
END_TIME,
TIME,
DIMENSIONS,
COUNT,
SIZE,
EXIF
}
public abstract Queryable.Type get_queryable_type();
public abstract Value? query_property(Queryable.Property property);
public abstract Gee.Iterable<Queryable>? get_queryables();
}
......@@ -118,5 +118,17 @@ public class Thumbnail : LayoutItem {
public bool is_exposed() {
return thumb_exposed;
}
public override Queryable.Type get_queryable_type() {
return photo.get_queryable_type();
}
public override Value? query_property(Queryable.Property queryable_property) {
return photo.query_property(queryable_property);
}
public override Gee.Iterable<Queryable>? get_queryables() {
return photo.get_queryables();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment