f-spot r3541 - in trunk: . src src/Extensions src/Widgets
- From: sdelcroix svn gnome org
- To: svn-commits-list gnome org
- Subject: f-spot r3541 - in trunk: . src src/Extensions src/Widgets
- Date: Tue, 15 Jan 2008 16:07:31 +0000 (GMT)
Author: sdelcroix
Date: Tue Jan 15 16:07:30 2008
New Revision: 3541
URL: http://svn.gnome.org/viewvc/f-spot?rev=3541&view=rev
Log:
Rating patch
Added:
trunk/src/RatingFilter.cs
trunk/src/RatingMenu.cs
trunk/src/Widgets/Rating.cs
Modified:
trunk/ChangeLog
trunk/src/Extensions/PopupCommands.cs
trunk/src/FSpot.addin.xml
trunk/src/FileBrowsableItem.cs
trunk/src/IBrowsableItem.cs
trunk/src/MainWindow.cs
trunk/src/Makefile.am
trunk/src/MetadataStore.cs
trunk/src/PhotoQuery.cs
trunk/src/PhotoStore.cs
trunk/src/PhotoView.cs
trunk/src/Preferences.cs
trunk/src/QueryWidget.cs
trunk/src/SingleView.cs
trunk/src/TimeAdaptor.cs
trunk/src/Updater.cs
trunk/src/Widgets/IconView.cs
trunk/src/XmpTagsImporter.cs
trunk/src/f-spot.glade
Modified: trunk/src/Extensions/PopupCommands.cs
==============================================================================
--- trunk/src/Extensions/PopupCommands.cs (original)
+++ trunk/src/Extensions/PopupCommands.cs Tue Jan 15 16:07:30 2008
@@ -104,4 +104,23 @@
MainWindow.Toplevel.HandleTagMenuActivate (o, e);
}
}
+
+ public class Rate : IMenuGenerator
+ {
+ private RatingMenu rating_menu;
+
+ public Gtk.Menu GetMenu ()
+ {
+ rating_menu = new RatingMenu (null);
+ rating_menu.RatingSelected += MainWindow.Toplevel.HandleRatingMenuSelected;
+ return (Gtk.Menu) rating_menu;
+ }
+
+ public void OnActivated (object o, EventArgs e)
+ {
+ if (rating_menu != null)
+ rating_menu.Populate ();
+ }
+
+ }
}
Modified: trunk/src/FSpot.addin.xml
==============================================================================
--- trunk/src/FSpot.addin.xml (original)
+++ trunk/src/FSpot.addin.xml Tue Jan 15 16:07:30 2008
@@ -36,5 +36,6 @@
<MenuSeparator id = "Separator3" />
<MenuGenerator id = "AttachTag" _label = "_Attach Tag" icon = "gtk-add" generator_type = "FSpot.Extensions.AttachTag" />
<MenuGenerator id = "RemoveTag" _label = "Rem_ove Tag" icon = "gtk-remove" generator_type = "FSpot.Extensions.RemoveTag" />
+ <MenuGenerator id = "RatingMenu" _label = "Set ra_ting" generator_type = "FSpot.Extensions.Rate" />
</Extension>
</Addin>
Modified: trunk/src/FileBrowsableItem.cs
==============================================================================
--- trunk/src/FileBrowsableItem.cs (original)
+++ trunk/src/FileBrowsableItem.cs Tue Jan 15 16:07:30 2008
@@ -80,6 +80,12 @@
}
}
+ public uint Rating {
+ get {
+ return 0; //FIXME ndMaxxer: correct?
+ }
+ }
+
public void Dispose ()
{
img.Dispose ();
Modified: trunk/src/IBrowsableItem.cs
==============================================================================
--- trunk/src/IBrowsableItem.cs (original)
+++ trunk/src/IBrowsableItem.cs Tue Jan 15 16:07:30 2008
@@ -81,6 +81,10 @@
string Name {
get;
}
+
+ uint Rating {
+ get;
+ }
}
Modified: trunk/src/MainWindow.cs
==============================================================================
--- trunk/src/MainWindow.cs (original)
+++ trunk/src/MainWindow.cs Tue Jan 15 16:07:30 2008
@@ -79,6 +79,7 @@
[Glade.Widget] CheckMenuItem display_timeline;
[Glade.Widget] CheckMenuItem display_dates_menu_item;
[Glade.Widget] CheckMenuItem display_tags_menu_item;
+ [Glade.Widget] CheckMenuItem display_ratings_menu_item;
[Glade.Widget] MenuItem zoom_in;
[Glade.Widget] MenuItem zoom_out;
@@ -98,8 +99,10 @@
[Glade.Widget] MenuItem find_add_tag_with;
[Glade.Widget] MenuItem clear_date_range;
+ [Glade.Widget] MenuItem clear_rating_filter;
[Glade.Widget] CheckMenuItem find_untagged;
+ [Glade.Widget] CheckMenuItem find_unrated;
[Glade.Widget] MenuItem last_roll;
[Glade.Widget] MenuItem select_rolls;
@@ -364,6 +367,7 @@
LoadPreference (Preferences.ZOOM);
LoadPreference (Preferences.SHOW_TAGS);
LoadPreference (Preferences.SHOW_DATES);
+ LoadPreference (Preferences.SHOW_RATINGS);
icon_view_scrolled.Add (icon_view);
icon_view.DoubleClicked += HandleDoubleClicked;
icon_view.Vadjustment.ValueChanged += HandleIconViewScroll;
@@ -855,6 +859,7 @@
HigMessageDialog md = new HigMessageDialog (main_window, DialogFlags.DestroyWithParent,
MessageType.Error, ButtonsType.Ok,
short_msg, String.Format (long_msg, backup));
+ Console.WriteLine (e);
md.Run ();
md.Destroy ();
}
@@ -1365,6 +1370,27 @@
}
//
+ // RatingMenu commands
+ //
+
+ public void HandleRatingMenuSelected (int r)
+ {
+ Photo p;
+ db.BeginTransaction ();
+ foreach (int num in SelectedIds ()) {
+ p = query.Photos [num];
+
+ if (r == -1)
+ p.RemoveRating();
+ else
+ p.Rating = (uint) r;
+ query.Commit (num);
+ }
+ db.CommitTransaction ();
+ this.photo_view.UpdateRating();
+ }
+
+ //
// TagMenu commands.
//
@@ -1770,6 +1796,7 @@
Preferences.Set (Preferences.SHOW_TIMELINE, group_selector.Visible);
Preferences.Set (Preferences.SHOW_TAGS, icon_view.DisplayTags);
Preferences.Set (Preferences.SHOW_DATES, icon_view.DisplayDates);
+ Preferences.Set (Preferences.SHOW_RATINGS, icon_view.DisplayRatings);
Preferences.Set (Preferences.GROUP_ADAPTOR, (group_selector.Adaptor is DirectoryAdaptor) ? 1 : 0);
Preferences.Set (Preferences.GROUP_ADAPTOR_ORDER_ASC, group_selector.Adaptor.OrderAscending);
@@ -2064,6 +2091,11 @@
icon_view.DisplayDates = display_dates_menu_item.Active;
}
+ void HandleDisplayRatings (object sender, EventArgs args)
+ {
+ icon_view.DisplayRatings = display_ratings_menu_item.Active;
+ }
+
void HandleDisplayGroupSelector (object sender, EventArgs args)
{
if (group_selector.Visible)
@@ -2172,9 +2204,11 @@
{
if (find_untagged.Active != query.Untagged)
find_untagged.Active = query.Untagged;
-
+ if (find_unrated.Active != query.Unrated)
+ find_unrated.Active = query.Unrated;
clear_date_range.Sensitive = (query.Range != null);
+ clear_rating_filter.Sensitive = (query.RatingRange != null);
UpdateStatusLabel ();
}
@@ -2562,6 +2596,25 @@
query.RollSet = null;
}
+ void HandleSetRatingFilter (object sender, EventArgs args) {
+ query.Unrated = false;
+ find_unrated.Active = false;
+ RatingFilter.Set set_command = new RatingFilter.Set (query, main_window);
+ set_command.Execute ();
+ }
+
+ public void HandleClearRatingFilter (object sender, EventArgs args) {
+ query.RatingRange = null;
+ query.Unrated = false;
+ find_unrated.Active = false;
+ }
+
+ void HandleFindUnrated (object sender, EventArgs args) {
+ if (query.Unrated == find_unrated.Active)
+ return;
+
+ query.Unrated = !query.Unrated;
+ }
void HandleFindUntagged (object sender, EventArgs args) {
if (query.Untagged == find_untagged.Active)
@@ -2631,6 +2684,11 @@
//display_dates_menu_item.Toggle ();
break;
+ case Preferences.SHOW_RATINGS:
+ if (display_ratings_menu_item.Active != (bool) val)
+ display_ratings_menu_item.Active = (bool) val;
+ break;
+
case Preferences.GROUP_ADAPTOR:
if ((int) val == 1)
directory.Active = true;
@@ -2857,6 +2915,8 @@
sharpen.Sensitive = active_selection;
remove_from_catalog.Sensitive = active_selection;
+ clear_rating_filter.Sensitive = (query.RatingRange != null);
+
last_roll.Sensitive = (db.Rolls.GetRolls (1).Length > 0);
select_rolls.Sensitive = (db.Rolls.GetRolls (2).Length > 1);
clear_roll_filter.Sensitive = (query.RollSet != null);
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Tue Jan 15 16:07:30 2008
@@ -175,6 +175,8 @@
$(srcdir)/PreviewPopup.cs \
$(srcdir)/PrintDialog.cs \
$(srcdir)/ProgressDialog.cs \
+ $(srcdir)/RatingFilter.cs \
+ $(srcdir)/RatingMenu.cs \
$(srcdir)/QueuedSqliteDatabase.cs \
$(srcdir)/RepairDialog.cs \
$(srcdir)/RotateCommand.cs \
@@ -226,6 +228,7 @@
$(srcdir)/Widgets/PanZoom.cs \
$(srcdir)/Widgets/Push.cs \
$(srcdir)/Widgets/QueryView.cs \
+ $(srcdir)/Widgets/Rating.cs \
$(srcdir)/Widgets/Reveal.cs \
$(srcdir)/Widgets/SaneTreeView.cs \
$(srcdir)/Widgets/ScalingIconView.cs \
Modified: trunk/src/MetadataStore.cs
==============================================================================
--- trunk/src/MetadataStore.cs (original)
+++ trunk/src/MetadataStore.cs Tue Jan 15 16:07:30 2008
@@ -246,6 +246,28 @@
Add (sink, FSpotXMPBase, predicate, type, values);
}
+ public void Delete (string predicate)
+ {
+ System.Collections.ArrayList to_remove = new System.Collections.ArrayList ();
+ foreach (Statement stmt in this) {
+ if (stmt.Predicate == MetadataStore.Namespaces.Resolve (predicate)) {
+ to_remove.Add (stmt);
+ break;
+ }
+ }
+
+ foreach (Statement stmt in to_remove)
+ this.Remove (stmt);
+ }
+
+ public void Update (string predicate, string value1)
+ {
+ // Delete first..
+ Delete (predicate);
+ // Add after...
+ AddLiteral (this, predicate, value1);
+ }
+
public void Update (string predicate, string type, string [] values)
{
Entity anon = null;
@@ -253,7 +275,8 @@
System.Collections.ArrayList to_remove = new System.Collections.ArrayList ();
foreach (Statement stmt in this) {
if (stmt.Predicate == MetadataStore.Namespaces.Resolve (predicate)) {
- anon = (Entity) stmt.Object;
+ if (type != null) // only look further if we have a type.
+ anon = (Entity) stmt.Object;
to_remove.Add (stmt);
break;
}
Modified: trunk/src/PhotoQuery.cs
==============================================================================
--- trunk/src/PhotoQuery.cs (original)
+++ trunk/src/PhotoQuery.cs Tue Jan 15 16:07:30 2008
@@ -12,6 +12,7 @@
private string extra_condition;
private PhotoStore.DateRange range = null;
private RollSet roll_set = null;
+ private PhotoStore.RatingRange ratingrange = null;
// Constructor
public PhotoQuery (PhotoStore store)
@@ -22,7 +23,7 @@
this.store.ItemsAddedOverDBus += delegate { RequestReload(); };
this.store.ItemsRemovedOverDBus += delegate { RequestReload(); };
- photos = store.Query ((Tag [])null, null, range, roll_set);
+ photos = store.Query ((Tag [])null, null, range, roll_set, ratingrange);
}
public int Count {
@@ -134,12 +135,43 @@
}
}
+ public PhotoStore.RatingRange RatingRange {
+ get {
+ return ratingrange;
+ }
+ set {
+ if (value == ratingrange)
+ return;
+
+ ratingrange = value;
+ RequestReload ();
+ }
+ }
+
+ private bool unrated = false;
+ public bool Unrated {
+ get {
+ return unrated;
+ }
+ set {
+ if (value == unrated)
+ return;
+
+ unrated = value;
+ if (unrated)
+ ratingrange = new PhotoStore.RatingRange (PhotoStore.RatingRange.RatingType.Unrated);
+ else
+ ratingrange = null;
+ RequestReload ();
+ }
+ }
+
public void RequestReload ()
{
if (untagged)
- photos = store.QueryUntagged (range, roll_set);
+ photos = store.QueryUntagged (range, roll_set, ratingrange);
else
- photos = store.Query (terms, extra_condition, range, roll_set);
+ photos = store.Query (terms, extra_condition, range, roll_set, ratingrange);
//this event will allow resorting the query content
if (PreChanged != null)
Modified: trunk/src/PhotoStore.cs
==============================================================================
--- trunk/src/PhotoStore.cs (original)
+++ trunk/src/PhotoStore.cs Tue Jan 15 16:07:30 2008
@@ -27,6 +27,14 @@
using Banshee.Database;
+namespace FSpot{
+ public class NotRatedException : System.ApplicationException
+ {
+ public NotRatedException (string message) : base (message)
+ {}
+ }
+}
+
public class PhotoVersion : FSpot.IBrowsableItem
{
Photo photo;
@@ -77,6 +85,10 @@
get { return is_protected; }
}
+ public uint Rating {
+ get { return photo.Rating; }
+ }
+
public PhotoVersion (Photo photo, uint version_id, System.Uri uri, string name, bool is_protected)
{
this.photo = photo;
@@ -235,6 +247,29 @@
set { roll_id = value; }
}
+ private uint rating;
+ private bool rated = false;
+ public uint Rating {
+ get {
+ if (!rated)
+ throw new NotRatedException ("This photo is not rated yet");
+ else
+ return rating;
+ }
+ set {
+ if (value >= 0 && value <= 5) {
+ rating = value;
+ rated = true;
+ } else
+ rated = false;
+ }
+ }
+
+ public void RemoveRating ()
+ {
+ rated = false;
+ }
+
// Version management
public const int OriginalVersionId = 1;
private uint highest_version_id;
@@ -591,6 +626,14 @@
names [i] = tags [i].Name;
xmp.Store.Update ("dc:subject", "rdf:Bag", names);
+ try {
+ xmp.Store.Update ("xmp:Rating", (item as Photo).Rating.ToString());
+// FIXME - Should we also store/overwrite the Urgency field?
+// uint urgency_value = (item as Photo).Rating + 1; // Urgency valid values 1 - 8
+// xmp.Store.Update ("photoshop:Urgency", urgency_value.ToString());
+ } catch (NotRatedException) {
+ xmp.Store.Delete ("xmp:Rating");
+ }
xmp.Dump ();
return xmp;
@@ -667,6 +710,7 @@
time = DbUtils.DateTimeFromUnixTime (unix_time);
description = String.Empty;
+ rated = false;
// Note that the original version is never stored in the photo_versions table in the
// database.
@@ -784,7 +828,8 @@
" uri STRING NOT NULL, " +
" description TEXT NOT NULL, " +
" roll_id INTEGER NOT NULL, " +
- " default_version_id INTEGER NOT NULL " +
+ " default_version_id INTEGER NOT NULL, " +
+ " rating INTEGER NULL " +
")");
@@ -833,13 +878,14 @@
string description = img.Description != null ? img.Description.Split ('\0') [0] : String.Empty;
uint id = (uint) Database.Execute (new DbCommand (
- "INSERT INTO photos (time, uri, description, roll_id, default_version_id) " +
- "VALUES (:time, :uri, :description, :roll_id, :default_version_id)",
+ "INSERT INTO photos (time, uri, description, roll_id, default_version_id, rating) " +
+ "VALUES (:time, :uri, :description, :roll_id, :default_version_id, :rating)",
"time", unix_time,
"uri", new_uri.ToString (),
"description", description,
"roll_id", roll_id,
- "default_version_id", Photo.OriginalVersionId));
+ "default_version_id", Photo.OriginalVersionId,
+ "rating", null));
photo = new Photo (id, unix_time, new_uri);
AddToCache (photo);
@@ -969,7 +1015,7 @@
if (photo != null)
return photo;
- SqliteDataReader reader = Database.Query(new DbCommand("SELECT time, uri, description, roll_id, default_version_id "
+ SqliteDataReader reader = Database.Query(new DbCommand("SELECT time, uri, description, roll_id, default_version_id, rating "
+ "FROM photos WHERE id = :id", "id", id));
if (reader.Read ()) {
@@ -980,6 +1026,10 @@
photo.Description = reader[2].ToString ();
photo.RollId = Convert.ToUInt32 (reader[3]);
photo.DefaultVersionId = Convert.ToUInt32 (reader[4]);
+ if (reader [5] != null)
+ photo.Rating = Convert.ToUInt32 (reader [5]);
+ else
+ photo.RemoveRating();
AddToCache (photo);
}
reader.Close();
@@ -1003,7 +1053,7 @@
{
Photo photo = null;
- SqliteDataReader reader = Database.Query (new DbCommand ("SELECT id, time, description, roll_id, default_version_id FROM photos "
+ SqliteDataReader reader = Database.Query (new DbCommand ("SELECT id, time, description, roll_id, default_version_id, rating FROM photos "
+ "WHERE uri = :uri", "uri", uri.ToString ()));
if (reader.Read ()) {
@@ -1014,6 +1064,10 @@
photo.Description = reader[2].ToString ();
photo.RollId = Convert.ToUInt32 (reader[3]);
photo.DefaultVersionId = Convert.ToUInt32 (reader[4]);
+ if (reader [5] != null)
+ photo.Rating = Convert.ToUInt32 (reader [5]);
+ else
+ photo.RemoveRating();
}
reader.Close();
@@ -1096,16 +1150,25 @@
private void Update (Photo photo) {
// Update photo.
+ uint rate = 0;
+ bool rated = false;
+ try {
+ rate = photo.Rating;
+ rated = true;
+ } catch {
+ }
Database.ExecuteNonQuery (new DbCommand (
"UPDATE photos SET description = :description, " +
"default_version_id = :default_version_id, " +
"time = :time, " +
- "uri = :uri " +
+ "uri = :uri, " +
+ "rating = :rating " +
"WHERE id = :id ",
"description", photo.Description,
"default_version_id", photo.DefaultVersionId,
"time", DbUtils.UnixTimeFromDateTime (photo.Time),
"uri", photo.VersionUri (Photo.OriginalVersionId).ToString (),
+ "rating", (rated ? String.Format ("{0}", rate) : null),
"id", photo.Id));
// Update tags.
@@ -1192,6 +1255,78 @@
ItemsRemovedOverDBus (this, new DbItemEventArgs (photos));
}
+ public class RatingRange
+ {
+ public enum RatingType {
+ Unrated,
+ Rated
+ };
+
+ private RatingType ratetype;
+ public RatingType RateType {
+ get {
+ return ratetype;
+ }
+ set {
+ ratetype = value;
+ }
+ }
+
+ private uint minRating;
+ public uint MinRating {
+ get {
+ return minRating;
+ }
+ set {
+ minRating = value;
+ }
+ }
+
+ private uint maxRating;
+ public uint MaxRating {
+ get {
+ return maxRating;
+ }
+ set {
+ maxRating = value;
+ }
+ }
+
+ public RatingRange (RatingType ratetype) {
+ this.ratetype = ratetype;
+ }
+
+ public RatingRange (uint newRating)
+ {
+ this.ratetype = RatingType.Rated;
+ this.minRating = newRating;
+ this.maxRating = System.UInt32.MaxValue;
+ }
+
+ public RatingRange (uint newRating1, uint newRating2)
+ {
+ this.ratetype = RatingType.Rated;
+ this.minRating = newRating1;
+ this.maxRating = newRating2;
+ }
+
+ public string SqlClause ()
+ {
+ switch (this.ratetype) {
+ case (RatingType.Unrated) :
+ return String.Format (" photos.rating = NULL");
+ break;
+ case (RatingType.Rated) :
+ return String.Format (" photos.rating >= {0} AND photos.rating <= {1} ", minRating, maxRating);
+ break;
+ default :
+ return String.Empty;
+ break;
+ }
+ }
+
+ }
+
// Queries.
[Obsolete ("drop this, use IQueryCondition correctly instead")]
@@ -1202,26 +1337,29 @@
return String.Format (" {0}{1}", added_where ? " AND " : " WHERE ", roll_set.SqlClause () );
}
-
-
- public Photo [] Query (Tag [] tags, DateTime start, DateTime end, Roll [] rolls)
+ public Photo [] Query (Tag [] tags, DateTime start, DateTime end, Roll [] rolls, uint minRating, uint maxRating)
{
- return Query (tags, null, new DateRange (start, end), new RollSet (rolls));
+ return Query (tags, null, new DateRange (start, end), new RollSet (rolls), new RatingRange (minRating, maxRating));
+ }
+
+ public Photo [] Query (Tag [] tags, DateTime start, DateTime end, Roll [] rolls, uint minRating)
+ {
+ return Query (tags, null, new DateRange (start, end), new RollSet (rolls), new RatingRange (minRating));
}
public Photo [] Query (Tag [] tags, Roll [] rolls)
{
- return Query (tags, null, null, rolls == null ? null : new RollSet (rolls));
+ return Query (tags, null, null, rolls == null ? null : new RollSet (rolls), null);
}
public Photo [] Query (Tag [] tags, DateTime start, DateTime end)
{
- return Query (tags, null, new DateRange (start, end), null);
+ return Query (tags, null, new DateRange (start, end), null, null);
}
public Photo [] Query (Tag [] tags) {
- return Query (tags, null, null, null);
+ return Query (tags, null, null, null, null);
}
public Photo [] Query (string query)
@@ -1242,6 +1380,10 @@
photo.Description = reader[3].ToString ();
photo.RollId = Convert.ToUInt32 (reader[4]);
photo.DefaultVersionId = Convert.ToUInt32 (reader[5]);
+ if (reader [6] != null)
+ photo.Rating = Convert.ToUInt32 (reader [6]);
+ else
+ photo.RemoveRating ();
version_list.Add (photo);
}
@@ -1278,7 +1420,8 @@
"photos.uri, " +
"photos.description, " +
"photos.roll_id, " +
- "photos.default_version_id " +
+ "photos.default_version_id, " +
+ "photos.rating " +
"FROM photos " +
"WHERE uri LIKE \"file://{0}%\" " +
"AND uri NOT LIKE \"file://{0}/%/%\"" , dir.FullName);
@@ -1288,6 +1431,11 @@
public Photo [] QueryUntagged (DateRange range, RollSet importidrange)
{
+ return QueryUntagged (range, importidrange, null);
+ }
+
+ public Photo [] QueryUntagged (DateRange range, RollSet importidrange, RatingRange ratingrange)
+ {
StringBuilder query_builder = new StringBuilder ();
query_builder.Append ("SELECT * FROM photos WHERE id NOT IN " +
@@ -1306,6 +1454,12 @@
added_where = true;
}
+ if (ratingrange != null) {
+ query_builder.Append (" AND");
+ query_builder.Append (ratingrange.SqlClause ());
+ added_where = true;
+ }
+
query_builder.Append("ORDER BY time");
return Query (query_builder.ToString ());
@@ -1313,10 +1467,15 @@
public Photo [] Query (Tag [] tags, string extra_condition, DateRange range, RollSet importidrange)
{
- return Query (OrTerm.FromTags(tags), extra_condition, range, importidrange);
+ return Query (OrTerm.FromTags(tags), extra_condition, range, importidrange, null);
}
- public Photo [] Query (Term searchexpression, string extra_condition, DateRange range, RollSet importidrange)
+ public Photo [] Query (Tag [] tags, string extra_condition, DateRange range, RollSet importidrange, RatingRange ratingrange)
+ {
+ return Query (OrTerm.FromTags(tags), extra_condition, range, importidrange, ratingrange);
+ }
+
+ public Photo [] Query (Term searchexpression, string extra_condition, DateRange range, RollSet importidrange, RatingRange ratingrange)
{
bool hide = (extra_condition == null);
@@ -1328,61 +1487,60 @@
// photos.description,
// photos.roll_id,
// photos.default_version_id
+ // photos.rating
// FROM photos, photo_tags
- // WHERE photos.id = photo_tags.photo_id
- // AND (photo_tags.tag_id = cat1tag1
- // OR photo_tags.tag_id = cat1tag2 )
- // AND (photo_tags.tag_id = cat2tag1
- // OR photo_tags.tag_id = cat2tag2 )
- // AND (photos.roll_id = roll_id1
- // OR photos.roll_id = roll_id2 ...)
+ // WHERE photos.time >= time1 AND photos.time <= time2
+ // AND photos.rating >= rat1 AND photos.rating <= rat2
+ // AND photos.id NOT IN (select photo_id FROM photo_tags WHERE tag_id = HIDDEN)
+ // AND photos.id IN (select photo_id FROM photo_tags where tag_id IN (tag1, tag2..)
+ // AND extra_condition_string
// GROUP BY photos.id
StringBuilder query_builder = new StringBuilder ();
+ ArrayList where_clauses = new ArrayList ();
query_builder.Append ("SELECT photos.id, " +
"photos.time, " +
"photos.uri, " +
"photos.description, " +
"photos.roll_id, " +
- "photos.default_version_id " +
+ "photos.default_version_id, " +
+ "photos.rating " +
"FROM photos ");
- bool where_statement_added = false;
-
if (range != null) {
- query_builder.Append (String.Format ("WHERE photos.time >= {0} AND photos.time <= {1} ",
- DbUtils.UnixTimeFromDateTime (range.Start),
- DbUtils.UnixTimeFromDateTime (range.End)));
- where_statement_added = true;
+ where_clauses.Add (String.Format ("photos.time >= {0} AND photos.time <= {1}",
+ DbUtils.UnixTimeFromDateTime (range.Start),
+ DbUtils.UnixTimeFromDateTime (range.End)));
+
+ }
+
+ if (ratingrange != null) {
+ where_clauses.Add (ratingrange.SqlClause ());
}
if (importidrange != null) {
- query_builder.Append (AddLastImportFilter (importidrange, where_statement_added));
- where_statement_added = true;
+ where_clauses.Add (importidrange.SqlClause ());
}
if (hide && Core.Database.Tags.Hidden != null) {
- query_builder.Append (String.Format ("{0} photos.id NOT IN (SELECT photo_id FROM photo_tags WHERE tag_id = {1}) ",
- where_statement_added ? " AND " : " WHERE ", Core.Database.Tags.Hidden.Id));
- where_statement_added = true;
+ where_clauses.Add (String.Format ("photos.id NOT IN (SELECT photo_id FROM photo_tags WHERE tag_id = {0})",
+ FSpot.Core.Database.Tags.Hidden.Id));
}
if (searchexpression != null) {
- query_builder.Append (String.Format ("{0} {1}",
- where_statement_added ? " AND " : " WHERE ",
- searchexpression.SqlCondition()));
- where_statement_added = true;
+ where_clauses.Add (searchexpression.SqlCondition ());
}
- if (extra_condition != null && extra_condition.Length != 0) {
- query_builder.Append (String.Format ("{0} {1} ",
- where_statement_added ? " AND " : " WHERE ",
- extra_condition));
- where_statement_added = true;
+ if (extra_condition != null) {
+ where_clauses.Add (extra_condition);
}
- query_builder.Append ("ORDER BY photos.time");
- Console.WriteLine("Query: {0}", query_builder.ToString());
+ if (where_clauses.Count > 0) {
+ query_builder.Append (" WHERE ");
+ query_builder.Append (String.Join (" AND ", ((String []) where_clauses.ToArray (typeof(String)))));
+ }
+ query_builder.Append (" ORDER BY photos.time");
+ Console.WriteLine ("Query: {0}", query_builder.ToString());
return Query (query_builder.ToString ());
}
Modified: trunk/src/PhotoView.cs
==============================================================================
--- trunk/src/PhotoView.cs (original)
+++ trunk/src/PhotoView.cs Tue Jan 15 16:07:30 2008
@@ -8,7 +8,7 @@
namespace FSpot {
public class PhotoView : EventBox {
- FSpot.Delay description_delay;
+ FSpot.Delay commit_delay;
private bool has_selection = false;
private FSpot.PhotoImageView photo_view;
@@ -20,6 +20,7 @@
private Gtk.ToolButton display_next_button, display_previous_button;
private Label count_label;
private Entry description_entry;
+ private Widgets.Rating rating;
private Gtk.ToolButton crop_button;
private Gtk.ToolButton redeye_button;
@@ -195,6 +196,18 @@
description_entry.Changed += HandleDescriptionChanged;
}
+ public void UpdateRating ()
+ {
+ rating.Changed -= HandleRatingChanged;
+ if (Item.IsValid)
+ try {
+ rating.Value = (int)Item.Current.Rating;
+ } catch (FSpot.NotRatedException) {
+ rating.Value = -1;
+ }
+ rating.Changed += HandleRatingChanged;
+ }
+
private void Update ()
{
if (UpdateStarted != null)
@@ -203,6 +216,7 @@
UpdateButtonSensitivity ();
UpdateCountLabel ();
UpdateDescriptionEntry ();
+ UpdateRating ();
if (UpdateFinished != null)
UpdateFinished (this);
@@ -368,12 +382,12 @@
ColorDialog.CreateForView (photo_view);
}
- int description_photo;
+ int changed_photo;
private bool CommitPendingChanges ()
{
- if (description_delay.IsPending) {
- description_delay.Stop ();
- ((PhotoQuery)query).Commit (description_photo);
+ if (commit_delay.IsPending) {
+ commit_delay.Stop ();
+ ((PhotoQuery)query).Commit (changed_photo);
}
return true;
}
@@ -385,17 +399,36 @@
((Photo)Item.Current).Description = description_entry.Text;
- if (description_delay.IsPending)
- if (description_photo == Item.Index)
- description_delay.Stop ();
+ if (commit_delay.IsPending)
+ if (changed_photo == Item.Index)
+ commit_delay.Stop ();
else
CommitPendingChanges ();
tips.SetTip (description_entry, description_entry.Text, "This is a tip");
- description_photo = Item.Index;
- description_delay.Start ();
+ changed_photo = Item.Index;
+ commit_delay.Start ();
}
+ private void HandleRatingChanged (object o, EventArgs e)
+ {
+ if (!Item.IsValid)
+ return;
+
+ if ((o as Widgets.Rating).Value < 0)
+ ((Photo)Item.Current).RemoveRating();
+ else
+ ((Photo)Item.Current).Rating = (uint)(o as Widgets.Rating).Value;
+
+ if (commit_delay.IsPending)
+ if (changed_photo == Item.Index)
+ commit_delay.Stop();
+ else
+ CommitPendingChanges ();
+ changed_photo = Item.Index;
+ commit_delay.Start ();
+ }
+
private void HandlePhotoChanged (FSpot.PhotoImageView view)
{
if (query is PhotoQuery) {
@@ -431,7 +464,7 @@
{
this.query = query;
- description_delay = new FSpot.Delay (1000, new GLib.IdleHandler (CommitPendingChanges));
+ commit_delay = new FSpot.Delay (1000, new GLib.IdleHandler (CommitPendingChanges));
this.Destroyed += HandleDestroy;
Name = "ImageContainer";
@@ -474,6 +507,10 @@
description_entry = new Entry ();
inner_hbox.PackStart (description_entry, true, true, 0);
description_entry.Changed += HandleDescriptionChanged;
+
+ rating = new Widgets.Rating();
+ inner_hbox.PackStart (rating, false, false, 0);
+ rating.Changed += HandleRatingChanged;
inner_vbox.PackStart (inner_hbox, false, true, 0);
Modified: trunk/src/Preferences.cs
==============================================================================
--- trunk/src/Preferences.cs (original)
+++ trunk/src/Preferences.cs Tue Jan 15 16:07:30 2008
@@ -33,6 +33,7 @@
public const string SHOW_TAGS = "/apps/f-spot/ui/show_tags";
public const string SHOW_DATES = "/apps/f-spot/ui/show_dates";
public const string EXPANDED_TAGS = "/apps/f-spot/ui/expanded_tags";
+ public const string SHOW_RATINGS = "/apps/f-spot/ui/show_ratings";
public const string TAG_ICON_SIZE = "/apps/f-spot/ui/tag_icon_size";
public const string GLASS_POSITION = "/apps/f-spot/ui/glass_position";
@@ -161,6 +162,7 @@
case SHOW_TIMELINE:
case SHOW_TAGS:
case SHOW_DATES:
+ case SHOW_RATINGS:
case VIEWER_SHOW_FILENAMES:
case EXPORT_GALLERY_ROTATE:
case EXPORT_PICASAWEB_SCALE:
Modified: trunk/src/QueryWidget.cs
==============================================================================
--- trunk/src/QueryWidget.cs (original)
+++ trunk/src/QueryWidget.cs Tue Jan 15 16:07:30 2008
@@ -8,10 +8,13 @@
public class QueryWidget : HighlightedBox {
PhotoQuery query;
LogicWidget logic_widget;
- Gtk.HBox box;
+ Gtk.HBox box;
Gtk.Label label;
Gtk.Label untagged;
- Gtk.Label comma_label;
+ Gtk.Label unrated;
+ Gtk.Label rated;
+ Gtk.Label comma1_label;
+ Gtk.Label comma2_label;
Gtk.Label rollfilter;
Gtk.HBox warning_box;
Gtk.Button clear_button;
@@ -25,9 +28,9 @@
public QueryWidget (PhotoQuery query, Db db, TagSelectionWidget selector) : base(new HBox())
{
- box = Child as HBox;
+ box = Child as HBox;
box.Spacing = 6;
- box.BorderWidth = 2;
+ box.BorderWidth = 2;
tips.Enable ();
@@ -43,9 +46,21 @@
untagged.Visible = false;
box.PackStart (untagged, false, false, 0);
- comma_label = new Gtk.Label (", ");
- comma_label.Visible = false;
- box.PackStart (comma_label, false, false, 0);
+ comma1_label = new Gtk.Label (", ");
+ comma1_label.Visible = false;
+ box.PackStart (comma1_label, false, false, 0);
+
+ unrated = new Gtk.Label (Catalog.GetString ("Unrated photos"));
+ unrated.Visible = false;
+ box.PackStart (unrated, false, false, 0);
+
+ rated = new Gtk.Label (Catalog.GetString ("Rated photos"));
+ rated.Visible = false;
+ box.PackStart (rated, false, false, 0);
+
+ comma2_label = new Gtk.Label (", ");
+ comma2_label.Visible = false;
+ box.PackStart (comma2_label, false, false, 0);
rollfilter = new Gtk.Label (Catalog.GetString ("Import roll"));
rollfilter.Visible = false;
@@ -82,7 +97,7 @@
public void HandleClearButtonClicked (object sender, System.EventArgs args)
{
- Close ();
+ Close ();
}
public void Close ()
@@ -93,6 +108,8 @@
if (query.Untagged)
return;
+ query.Unrated = false;
+ query.RatingRange = null;
logic_widget.Clear = true;
logic_widget.UpdateQuery ();
}
@@ -114,16 +131,20 @@
if (query.ExtraCondition == null)
logic_widget.Clear = true;
- if (!logic_widget.Clear || query.Untagged || (query.RollSet != null)) {
- ShowBar ();
+ if (!logic_widget.Clear || query.Untagged || (query.RollSet != null) || query.Unrated || (query.RatingRange != null)) {
+ ShowBar ();
} else {
HideBar ();
}
untagged.Visible = query.Untagged;
+ unrated.Visible = query.Unrated;
+ rated.Visible = (query.RatingRange != null) && !query.Unrated;
warning_box.Visible = (query.Count < 1);
- comma_label.Visible = query.Untagged && (query.RollSet != null);
rollfilter.Visible = (query.RollSet != null);
+ comma1_label.Visible = (untagged.Visible && (unrated.Visible || rated.Visible));
+ comma2_label.Visible = (!untagged.Visible && (unrated.Visible || rated.Visible) && rollfilter.Visible) ||
+ (untagged.Visible && rollfilter.Visible);
}
Added: trunk/src/RatingFilter.cs
==============================================================================
--- (empty file)
+++ trunk/src/RatingFilter.cs Tue Jan 15 16:07:30 2008
@@ -0,0 +1,54 @@
+/*
+ * Rating.cs
+ *
+ * Author[s]
+ * Bengt Thuree <bengt thuree com>
+ *
+ */
+
+using Gtk;
+using Gnome;
+
+public class RatingFilter {
+ public class Set : FSpot.GladeDialog {
+ FSpot.PhotoQuery query;
+ Gtk.Window parent_window;
+
+ [Glade.Widget] private Button ok_button;
+ [Glade.Widget] private SpinButton minrating;
+ [Glade.Widget] private SpinButton maxrating;
+
+ public Set (FSpot.PhotoQuery query, Gtk.Window parent_window)
+ {
+ this.query = query;
+ this.parent_window = parent_window;
+ }
+
+ public bool Execute ()
+ {
+ this.CreateDialog ("set_rating_filter");
+
+ if (query.RatingRange != null) {
+ minrating.Value = query.RatingRange.MinRating;
+ maxrating.Value = query.RatingRange.MaxRating;
+ }
+
+ Dialog.TransientFor = parent_window;
+ Dialog.DefaultResponse = ResponseType.Ok;
+
+ ResponseType response = (ResponseType) this.Dialog.Run ();
+
+ bool success = false;
+
+ if (response == ResponseType.Ok) {
+ query.RatingRange = new PhotoStore.RatingRange ((uint) minrating.Value, (uint) maxrating.Value);
+ success = true;
+ }
+
+ this.Dialog.Destroy ();
+ return success;
+ }
+ }
+}
+
+
Added: trunk/src/RatingMenu.cs
==============================================================================
--- (empty file)
+++ trunk/src/RatingMenu.cs Tue Jan 15 16:07:30 2008
@@ -0,0 +1,93 @@
+/*
+ * RatingMenu.cs
+ *
+ * Author(s)
+ * Bengt Thuree <bengt thuree com>
+ * Stephane Delcroix <stephane delcroix org>
+ *
+ * See COPYING for licence terms
+ *
+ */
+
+using Gtk;
+using System;
+
+public class RatingMenu : Menu {
+ private MenuItem parent_item;
+
+ public delegate void RatingSelectedHandler (int r);
+ public event RatingSelectedHandler RatingSelected;
+
+ public class RatingMenuItem : Gtk.MenuItem {
+ private int rating;
+
+ public int Rating {
+ get { return rating; }
+ set { rating = value; }
+ }
+
+ public RatingMenuItem (string label): base (label)
+ {
+ Rating = -1;
+ }
+
+ public RatingMenuItem (int r)
+ {
+ Rating = r;
+ if (r >= 0) {
+ FSpot.Widgets.RatingSmall rating_small = new FSpot.Widgets.RatingSmall(r,false);
+ Add(rating_small);
+ } else {
+ Label unrated = new Label(Mono.Unix.Catalog.GetString("Not rated"));
+ Add(unrated);
+ }
+ }
+ }
+
+ public RatingMenu (MenuItem item)
+ {
+ if (item != null) {
+ item.Submenu = this;
+ item.Activated += HandlePopulate;
+ parent_item = item;
+ }
+ }
+
+ protected RatingMenu (IntPtr raw) : base (raw) {}
+
+ private void HandlePopulate (object obj, EventArgs args)
+ {
+ Populate(this);
+ }
+
+ bool populated = false;
+
+ public void Populate ()
+ {
+ Populate (this);
+ }
+
+ public void Populate (Gtk.Menu parent)
+ {
+ if (!populated) {
+ for (int k = -1; k <= 5; k ++) {
+ RatingMenuItem item = new RatingMenuItem (k);
+ parent.Append (item);
+ item.ShowAll ();
+ item.Activated += HandleActivate;
+ }
+ populated = true;
+ }
+ }
+
+ void HandleActivate (object obj, EventArgs args)
+ {
+ if (RatingSelected != null) {
+ RatingMenuItem t = obj as RatingMenuItem;
+ if (t != null)
+ RatingSelected (t.Rating);
+ else
+ Console.WriteLine ("Item was not rating usable");
+ }
+ }
+}
Modified: trunk/src/SingleView.cs
==============================================================================
--- trunk/src/SingleView.cs (original)
+++ trunk/src/SingleView.cs Tue Jan 15 16:07:30 2008
@@ -104,6 +104,7 @@
DragAction.Copy | DragAction.Move);
directory_view.DisplayTags = false;
directory_view.DisplayDates = false;
+ directory_view.DisplayRatings = false;
directory_scrolled.Add (directory_view);
ThumbnailGenerator.Default.OnPixbufLoaded += delegate { directory_view.QueueDraw (); };
Modified: trunk/src/TimeAdaptor.cs
==============================================================================
--- trunk/src/TimeAdaptor.cs (original)
+++ trunk/src/TimeAdaptor.cs Tue Jan 15 16:07:30 2008
@@ -195,7 +195,7 @@
{
years.Clear ();
- Photo [] photos = query.Store.Query ((Tag [])null, null, null, null);
+ Photo [] photos = query.Store.Query ((Tag [])null, null, null, null, null);
Array.Sort (query.Photos);
Array.Sort (photos);
Modified: trunk/src/Updater.cs
==============================================================================
--- trunk/src/Updater.cs (original)
+++ trunk/src/Updater.cs Tue Jan 15 16:07:30 2008
@@ -210,7 +210,27 @@
"FROM {0} ", tmp_photos));
}, false);
- // Update to version 11.0
+ // Update to version 11.0, rating
+ AddUpdate (new Version (11,0),delegate () {
+ string tmp_photos = MoveTableToTemp ("photos");
+ ExecuteNonQuery (
+ "CREATE TABLE photos ( " +
+ " id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
+ " time INTEGER NOT NULL, " +
+ " uri STRING NOT NULL, " +
+ " description TEXT NOT NULL, " +
+ " roll_id INTEGER NOT NULL, " +
+ " default_version_id INTEGER NOT NULL, " +
+ " rating INTEGER NULL " +
+ ")");
+
+ ExecuteNonQuery (String.Format (
+ "INSERT INTO photos (id, time, uri, description, roll_id, default_version_id, rating) " +
+ "SELECT id, time, uri, description, roll_id, default_version_id, null " +
+ "FROM {0} ", tmp_photos));
+ });
+
+ // Update to version 12.0
//AddUpdate (new Version (0,0),delegate () {
// do update here
//});
Modified: trunk/src/Widgets/IconView.cs
==============================================================================
--- trunk/src/Widgets/IconView.cs (original)
+++ trunk/src/Widgets/IconView.cs Tue Jan 15 16:07:30 2008
@@ -124,6 +124,21 @@
}
}
}
+
+ private bool display_ratings = true;
+ public bool DisplayRatings {
+ get {
+ if (cell_width > 100)
+ return display_ratings;
+ else
+ return false;
+ }
+
+ set {
+ display_ratings = value;
+ QueueResize ();
+ }
+ }
// Size of the frame around the thumbnail.
protected int cell_border_width = 10;
@@ -865,6 +880,16 @@
thumbnail.Dispose ();
}
Gdk.Rectangle layout_bounds = Gdk.Rectangle.Zero;
+ if (DisplayRatings) {
+ FSpot.Widgets.RatingSmall rating;
+ try {
+ rating = new FSpot.Widgets.RatingSmall ((int) photo.Rating, false);
+ } catch (NotRatedException) {
+ rating = new FSpot.Widgets.RatingSmall (-1, false);
+ }
+ rating.DisplayPixbuf.RenderToDrawable (BinWindow, Style.WhiteGC,
+ 0, 0, region.X, region.Y, -1, -1, RgbDither.None, 0, 0);
+ }
if (DisplayDates) {
string date;
if (cell_width > 200) {
Added: trunk/src/Widgets/Rating.cs
==============================================================================
--- (empty file)
+++ trunk/src/Widgets/Rating.cs Tue Jan 15 16:07:30 2008
@@ -0,0 +1,397 @@
+/*
+ * Rating.cs
+ *
+ * Author[s]
+ * Gabriel Burt (original widget in Banshee)
+ * Cosme Sevestre (original porting to F-Spot)
+ * Stephane Delcroix
+ *
+ * Copyright (C) 2006 by the respective authors.
+ *
+ * This is free software, see COPYING for details
+ *
+ */
+
+using Gtk;
+using Gdk;
+using System;
+
+namespace FSpot.Widgets
+{
+ public class Rating : Gtk.EventBox
+ {
+ int rating;
+ Pixbuf display_pixbuf;
+ public object RatedObject;
+ bool mouse_over;
+ bool editable;
+
+ protected static int max_rating = 5;
+ protected static int min_rating = 1;
+ static Pixbuf icon_rated;
+ static Pixbuf icon_blank;
+ static Pixbuf icon_throw;
+ static Pixbuf icon_throwed;
+ static Pixbuf icon_unrated;
+
+ public event EventHandler Changed;
+
+ public Rating () : this (-1, true) {} //Default value is NotRated, editable
+ public Rating (bool editable) : this (-1, editable) {}
+ public Rating (int rating) : this (rating, true) {}
+
+ public Rating (int rating, bool editable)
+ {
+ this.rating = rating;
+ this.editable = editable;
+
+ MouseOver = false;
+ EnterNotifyEvent += HandleMouseEnter;
+ LeaveNotifyEvent += HandleMouseLeave;
+
+ CanFocus = true;
+
+ display_pixbuf = new Pixbuf (Gdk.Colorspace.Rgb, true, 8, Width, Height);
+
+ // Start display transparent
+ display_pixbuf.Fill (0xffffff00);
+
+ DrawRating (DisplayPixbuf, Value);
+
+ // DirectionChanged
+ Add (new Gtk.Image (display_pixbuf));
+
+ ShowAll ();
+ }
+
+ ~Rating ()
+ {
+ display_pixbuf.Dispose ();
+ display_pixbuf = null;
+
+ icon_rated = null;
+ icon_blank = null;
+ }
+
+ public Pixbuf DrawRating (int val)
+ {
+ Pixbuf buf = new Pixbuf (Gdk.Colorspace.Rgb, true, 8, Width, Height);
+ DrawRating (buf, val);
+ return buf;
+ }
+
+ public virtual void DrawRating (Pixbuf pbuf, int val)
+ {
+ // Clean pixbuf
+ pbuf.Fill (0xffffff00);
+
+ if (val == -1 || (mouse_over && val != 0)) //NotRated or MouseOver
+ IconThrow.CopyArea (0, 0, IconRated.Width, IconRated.Height,
+ pbuf, 0, 0);
+ if (val == 0) //Throwed
+ IconThrowed.CopyArea (0, 0, IconRated.Width, IconRated.Height,
+ pbuf, 0, 0);
+ //Stars
+ for (int i = 0; i < MaxRating; i ++)
+ if (i <= val - MinRating)
+ IconRated.CopyArea (0, 0, IconRated.Width, IconRated.Height,
+ pbuf, (i + 1) * IconRated.Width, 0);
+ else {
+ if (!mouse_over && val != -1)
+ continue;
+ IconNotRated.CopyArea (0, 0, IconRated.Width, IconRated.Height,
+ pbuf, (i + 1) * IconRated.Width, 0);
+ }
+ //Unrate button
+ IconUnrated.CopyArea (0, 0, IconUnrated.Width, IconUnrated.Height,
+ pbuf, (max_rating - min_rating + 2) * IconUnrated.Width, 0);
+ }
+
+ private int RatingFromPosition (double x)
+ {
+ //System.Console.WriteLine ("Rating from position >>{0}<<", (int) (x / (double)(IconRated.Width)));
+ int pos = (int) (x / (double) IconRated.Width);
+
+ if (pos == NumLevels - 1)
+ return -1;
+ else
+ return pos;
+ }
+
+ private void HandleMouseEnter (object sender, EventArgs args)
+ {
+ mouse_over = true;
+ Redraw ();
+ }
+
+ private void HandleMouseLeave (object sender, EventArgs args)
+ {
+ mouse_over = false;
+ Redraw ();
+ }
+
+ // Event Handlers
+ [GLib.ConnectBefore]
+ protected override bool OnButtonPressEvent (Gdk.EventButton eb)
+ {
+ if (editable) {
+ if (eb.Button != 1)
+ return false;
+
+ Value = RatingFromPosition (eb.X);
+ }
+ return true;
+ }
+
+ public bool HandleKeyPress (Gdk.EventKey ek)
+ {
+ return this.OnKeyPressEvent (ek);
+ }
+
+ [GLib.ConnectBefore]
+ protected override bool OnKeyPressEvent (Gdk.EventKey ek)
+ {
+ if (editable) {
+ switch (ek.Key) {
+ case Gdk.Key.Up:
+ case Gdk.Key.Right:
+ case Gdk.Key.plus:
+ case Gdk.Key.equal:
+ Value ++;
+ return true;
+
+ case Gdk.Key.Down:
+ case Gdk.Key.Left:
+ case Gdk.Key.minus:
+ Value --;
+ return true;
+ }
+
+ if (ek.KeyValue >= (48 + MinRating) &&
+ ek.KeyValue <= (48 + MaxRating) &&
+ ek.KeyValue <= 59) {
+ Value = (int) ek.KeyValue - 48;
+ return true;
+ }
+
+ return false;
+ } else
+ return true;
+ }
+
+ [GLib.ConnectBefore]
+ protected override bool OnScrollEvent (EventScroll args)
+ {
+ if (editable) {
+ switch (args.Direction) {
+ case Gdk.ScrollDirection.Up:
+ case Gdk.ScrollDirection.Right:
+ Value ++;
+ return true;
+
+ case Gdk.ScrollDirection.Down:
+ case Gdk.ScrollDirection.Left:
+ Value --;
+ return true;
+ }
+
+ return false;
+ } else
+ return true;
+ }
+
+ [GLib.ConnectBefore]
+ protected override bool OnMotionNotifyEvent (Gdk.EventMotion evnt)
+ {
+ if (editable) {
+ System.Console.WriteLine ("OnMotionNotifyEvent");
+ // TODO draw highlights onmouseover a rating? (and clear on leaveNotify)
+ if (evnt.State != Gdk.ModifierType.Button1Mask)
+ return false;
+
+ Value = RatingFromPosition (evnt.X);
+ }
+ return true;
+ }
+
+ [GLib.ConnectBefore]
+ protected override bool OnFocusInEvent (Gdk.EventFocus evnt)
+ {
+ System.Console.WriteLine ("OnFocusInEvent");
+ return true;
+ }
+
+ [GLib.ConnectBefore]
+ protected override bool OnFocused (DirectionType direction)
+ {
+ System.Console.WriteLine ("OnFocus");
+ return true;
+ }
+
+ private void Redraw()
+ {
+ DrawRating (DisplayPixbuf, Value);
+ QueueDraw ();
+ }
+
+ // Event Changed Dispatcher
+ private void OnChanged ()
+ {
+ Redraw();
+ EventHandler changed = Changed;
+
+ if (changed != null)
+ changed (this, new EventArgs ());
+ }
+
+ // Properties
+ public int Value {
+ get { return rating; }
+
+ set {
+ // Same rating
+ if (rating == value)
+ return;
+ // Remove.trash.1-5 rating
+ if (value >= -1 && value <= max_rating) {
+ rating = value;
+ OnChanged ();
+ }
+ }
+ }
+
+ public Pixbuf DisplayPixbuf {
+ get { return display_pixbuf; }
+ }
+
+ public bool MouseOver {
+ get { return mouse_over; }
+ set { mouse_over = value; }
+ }
+
+ public int MaxRating {
+ get { return max_rating; }
+ }
+
+ public int MinRating {
+ get { return min_rating; }
+ }
+
+ public virtual int NumLevels {
+ get { return max_rating - min_rating + 3; }
+ }
+
+ public Pixbuf IconUnrated {
+ get {
+ if (icon_unrated == null)
+ icon_unrated = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "rating-unrated", 16, (Gtk.IconLookupFlags)0);
+
+ return icon_unrated;
+ }
+
+ set { icon_unrated = value; }
+ }
+
+ public virtual Pixbuf IconRated {
+ get {
+ if (icon_rated == null)
+ icon_rated = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "rating-rated", 16, (Gtk.IconLookupFlags)0);
+
+ return icon_rated;
+ }
+
+ set { icon_rated = value; }
+ }
+
+ public virtual Pixbuf IconNotRated {
+ get {
+ if (icon_blank == null)
+ icon_blank = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "rating-blank", 16, (Gtk.IconLookupFlags)0);
+
+ return icon_blank;
+ }
+
+ set { icon_blank = value; }
+ }
+
+ public virtual Pixbuf IconThrow {
+ get {
+ if (icon_throw == null)
+ icon_throw = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "rating-junk", 16, (Gtk.IconLookupFlags)0);
+
+ return icon_throw;
+ }
+
+ set { icon_throw = value; }
+ }
+
+ public virtual Pixbuf IconThrowed {
+ get {
+ if (icon_throwed == null)
+ icon_throwed = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "rating-junk-bold", 16, (Gtk.IconLookupFlags)0);
+
+ return icon_throwed;
+ }
+
+ set { icon_throw = value; }
+ }
+
+ public virtual int Width {
+ get { return IconRated.Width * NumLevels; }
+ }
+
+ public virtual int Height {
+ get { return IconRated.Height; }
+ }
+ }
+
+ public class RatingSmall : Rating
+ {
+ static Pixbuf icon_rated_small;
+ static Pixbuf icon_blank_small;
+
+ public RatingSmall () : base (-1) {}
+ public RatingSmall (int rating) : base (rating) {}
+ public RatingSmall (bool editable) : base (editable) {}
+ public RatingSmall (int rating, bool editable) : base (rating, editable) {}
+
+ public override void DrawRating (Pixbuf pbuf, int val)
+ {
+ // Clean pixbuf
+ pbuf.Fill (0xffffff00);
+
+ if (val == -1) //NotRated
+ return;
+ //Stars
+ for (int i = 0; i < MaxRating; i ++)
+ if (i <= val - MinRating)
+ IconRated.CopyArea (0, 0, IconRated.Width, IconRated.Height,
+ pbuf, i * IconRated.Width, 0);
+ else
+ IconNotRated.CopyArea (0, 0, IconRated.Width, IconRated.Height,
+ pbuf, i * IconRated.Height, 0);
+ }
+
+ public override Pixbuf IconRated {
+ get {
+ if (icon_rated_small == null)
+ icon_rated_small = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "rating-rated", 16, (Gtk.IconLookupFlags)0);
+
+ return icon_rated_small;
+ }
+ }
+
+ public override Pixbuf IconNotRated {
+ get {
+ if (icon_blank_small == null)
+ icon_blank_small = GtkUtil.TryLoadIcon (FSpot.Global.IconTheme, "rating-blank", 16, (Gtk.IconLookupFlags)0);
+
+ return icon_blank_small;
+ }
+ }
+
+ public override int NumLevels {
+ get { return max_rating - min_rating + 1; }
+ }
+ }
+}
Modified: trunk/src/XmpTagsImporter.cs
==============================================================================
--- trunk/src/XmpTagsImporter.cs (original)
+++ trunk/src/XmpTagsImporter.cs Tue Jan 15 16:07:30 2008
@@ -43,6 +43,8 @@
const string People = MetadataStore.IViewNS + "People";
const string Subject = MetadataStore.DcNS + "subject";
const string RdfType = MetadataStore.RdfNS + "type";
+ const string Rating = MetadataStore.XmpNS + "Rating";
+ const string Urgency = MetadataStore.PhotoshopNS + "Urgency";
private class TagInfo {
// This class contains the Root tag name, and its Icon name (if any)
@@ -149,6 +151,8 @@
public void ProcessStore (MetadataStore store, Photo photo)
{
Hashtable descriptions = new Hashtable ();
+ uint rating = System.UInt32.MaxValue;
+ uint urgency = System.UInt32.MaxValue;
foreach (Statement stmt in store) {
//StatementList list = null;
@@ -186,6 +190,28 @@
}
break;
+ case Urgency: // Used if Rating was not found
+ case Rating:
+ Literal l = stmt.Object as Literal;
+ if (l != null && l.Value != null && l.Value.Length > 0) {
+ uint tmp_ui;
+ try {
+ tmp_ui = System.Convert.ToUInt32 (l.Value);
+ } catch {
+ // Set rating to 0, and continue
+ System.Console.WriteLine ("Found illegal rating >{0}< in predicate {1}. Rating cleared",
+ l.Value, stmt.Predicate.Uri);
+ tmp_ui = 0;
+ }
+ if (tmp_ui > 5) // Max rating allowed in F-Spot
+ tmp_ui = 5;
+ if (stmt.Predicate.Uri == Rating)
+ rating = tmp_ui;
+ else
+ urgency = tmp_ui == 0 ? 0 : tmp_ui - 1; // Urgency valid values 1 - 8
+ }
+ break;
+
case State:
case City:
case Country:
@@ -213,6 +239,12 @@
if (descriptions.Contains (UserComment))
photo.Description = descriptions [UserComment] as String;
+ // Use the old urgency, only if rating was not available.
+ if (urgency < System.UInt32.MaxValue)
+ photo.Rating = urgency;
+ if (rating < System.UInt32.MaxValue)
+ photo.Rating = rating;
+
#if false
//FIXME: looks like we are doing some questionable repurposing of tags here...
Modified: trunk/src/f-spot.glade
==============================================================================
--- trunk/src/f-spot.glade (original)
+++ trunk/src/f-spot.glade Tue Jan 15 16:07:30 2008
@@ -5604,6 +5604,15 @@
</child>
</widget>
</child>
+ <child>
+ <widget class="GtkCheckMenuItem" id="display_ratings_menu_item">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Display _Ratings</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <signal name="activate" handler="HandleDisplayRatings"/>
+ </widget>
+ </child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator17">
<property name="visible">True</property>
@@ -5788,6 +5797,42 @@
<property name="visible">True</property>
</widget>
</child>
+
+ <child>
+ <widget class="GtkMenuItem" id="set_rating_filter1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Set Rating filter...</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="HandleSetRatingFilter"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="clear_rating_filter">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Clear Rating Filter</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="HandleClearRatingFilter"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkCheckMenuItem" id="find_unrated">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Unrated Photos</property>
+ <property name="use_underline">True</property>
+ <property name="active">False</property>
+ <signal name="activate" handler="HandleFindUnrated"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separator15">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+
<child>
<widget class="GtkMenuItem" id="set_date_range1">
<property name="visible">True</property>
@@ -10287,6 +10332,218 @@
</widget>
</child>
</widget>
+
+
+<widget class="GtkDialog" id="set_rating_filter">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Set Rating Filter</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">False</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="vbox84">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="hbuttonbox13">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="button28">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button29">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox87">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkFrame" id="frame48">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment64">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkSpinButton" id="minrating">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">False</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">4 0 5 1 10 10</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label214">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Min Rating</b></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkFrame" id="frame49">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment65">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkSpinButton" id="maxrating">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">False</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">5 0 5 1 10 10</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label215">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Max Rating</b></property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+
+
<widget class="GtkDialog" id="repair_dialog">
<property name="visible">True</property>
<property name="title" translatable="yes">Repair</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]