2
* Widgets.MetadataDisplay.cs
5
* Mike Gemuende <mike@gemuende.de>
6
* Ruben Vermeersch <ruben@savanne.be>
8
* This is free software. See COPYING for details.
14
using System.Collections.Generic;
20
using FSpot.Extensions;
23
namespace FSpot.Widgets {
24
public class MetadataDisplayPage : SidebarPage {
25
public MetadataDisplayPage() : base(new MetadataDisplayWidget(),
26
Catalog.GetString ("Metadata"),
28
(SidebarWidget as MetadataDisplayWidget).Page = this;
31
protected override void AddedToSidebar ()
33
MetadataDisplayWidget widget = SidebarWidget as MetadataDisplayWidget;
34
(Sidebar as Sidebar).SelectionChanged += widget.HandleSelectionChanged;
35
(Sidebar as Sidebar).SelectionItemsChanged += widget.HandleSelectionItemsChanged;
39
public class MetadataDisplayWidget : ScrolledWindow {
42
/* This VBox only contains exif-data,
43
so it is seperated from other information */
47
Label metadata_message;
50
private MetadataDisplayPage page;
51
public MetadataDisplayPage Page {
56
// stores list of the expanded expanders
57
List<string> open_list;
59
ListStore extended_metadata;
61
bool up_to_date = false;
68
public MetadataDisplayWidget ()
70
main_vbox = new VBox ();
71
main_vbox.Spacing = 6;
73
metadata_message = new Label (String.Empty);
74
metadata_message.UseMarkup = true;
75
metadata_message.LineWrap = true;
76
metadata_vbox = new VBox ();
77
metadata_vbox.Spacing = 6;
79
main_vbox.PackStart (metadata_vbox, false, false, 0);
80
AddWithViewport (metadata_message);
81
((Viewport) Child).ShadowType = ShadowType.None;
84
display = State.message;
85
ExposeEvent += HandleExposeEvent;
87
open_list = new List<string> ();
89
// Create Expander and TreeView for
91
TreeView tree_view = new TreeView ();
92
tree_view.HeadersVisible = false;
93
tree_view.RulesHint = true;
95
TreeViewColumn col = new TreeViewColumn ();
96
col.Sizing = TreeViewColumnSizing.Autosize;
97
CellRenderer colr = new CellRendererText ();
98
col.PackStart (colr, false);
100
col.AddAttribute (colr, "markup", 0);
102
tree_view.AppendColumn (col);
104
extended_metadata = new ListStore (typeof(string));
105
tree_view.Model = extended_metadata;
107
Expander expander = new Expander (String.Format("<span weight=\"bold\"><small>{0}</small></span>", Catalog.GetString ("Extended Metadata")));
108
expander.UseMarkup = true;
109
expander.Add (tree_view);
110
expander.Expanded = true;
112
main_vbox.PackStart (expander, false, false, 6);
115
update_delay = new Delay (Update);
116
update_delay.Start ();
119
private IBrowsableItem photo;
120
public IBrowsableItem Photo {
121
get { return photo; }
128
update_delay.Start ();
133
private void HandleExposeEvent (object sender, ExposeEventArgs args)
136
update_delay.Start ();
140
internal void HandleSelectionChanged (IBrowsableCollection collection) {
141
// Don't show metadata when multiple photos are selected.
142
Photo = (collection != null && collection.Count == 1) ? collection [0] : null;
145
internal void HandleSelectionItemsChanged (IBrowsableCollection collection, BrowsableEventArgs args) {
146
if (!args.Changes.MetadataChanged)
152
update_delay.Start ();
156
private bool Visible {
158
return (Page.Sidebar as Sidebar).IsActive (Page);
162
private ListStore AddExpander (string name, int pos)
164
TreeView tree_view = new TreeView ();
165
tree_view.HeadersVisible = false;
166
tree_view.RulesHint = true;
168
TreeViewColumn col = new TreeViewColumn ();
169
col.Sizing = TreeViewColumnSizing.Autosize;
170
CellRenderer colr = new CellRendererText ();
171
col.PackStart (colr, false);
173
col.AddAttribute (colr, "markup", 0);
175
tree_view.AppendColumn (col);
177
ListStore model = new ListStore (typeof(string));
178
tree_view.Model = model;
180
Expander expander = new Expander (String.Format ("<span weight=\"bold\"><small>{0}</small></span>", name));
181
expander.UseMarkup = true;
182
expander.Add (tree_view);
183
expander.Expanded = true;
185
metadata_vbox.PackStart (expander, false, false, 6);
186
metadata_vbox.ReorderChild (expander, pos);
188
if (open_list.Contains (name))
189
expander.Expanded = true;
191
expander.Activated += HandleExpanderActivated;
198
public void HandleExpanderActivated (object sender, EventArgs e)
200
Expander expander = (Expander) sender;
201
if (expander.Expanded)
202
open_list.Add (expander.Label);
204
open_list.Remove (expander.Label);
207
private bool Update ()
210
int index_of_expander = 0;
211
bool missing = false;
212
System.Exception error = null;
215
// FIXME: The stuff below needs to be ported to Taglib#.
225
if (exif_info != null) {
226
foreach (ExifContent content in exif_info.GetContents ()) {
227
ExifEntry [] entries = content.GetEntries ();
231
if (entries.Length < 1)
236
name = ExifUtil.GetIfdNameExtended ((Ifd)i - 1);
238
if (index_of_expander >= metadata_vbox.Children.Length)
239
model = AddExpander (name, index_of_expander);
241
Expander expander = (Expander)metadata_vbox.Children[index_of_expander];
242
if (expander.Label == name)
243
model = (ListStore)((TreeView)expander.Child).Model;
245
model = AddExpander (name, index_of_expander);
249
model.GetIterFirst(out iter);
251
foreach (ExifEntry entry in entries) {
254
if (entry.Title != null)
255
s = String.Format ("{0}\n\t<small>{1}</small>", entry.Title, entry.Value);
257
s = String.Format ("Unknown Tag ID={0}\n\t<small>{1}</small>", entry.Tag.ToString (), entry.Value);
259
if (model.IterIsValid(iter)) {
260
model.SetValue (iter, 0, s);
261
model.IterNext(ref iter);
263
model.AppendValues (s);
266
// remove rows, that are not used
267
while (model.IterIsValid(iter)) {
268
model.Remove (ref iter);
276
// Write Extended Metadata
278
MetadataStore store = new MetadataStore ();
280
using (var img = ImageFile.Create (photo.DefaultVersion.Uri)) {
281
if (img is SemWeb.StatementSource) {
282
StatementSource source = (StatementSource)img;
283
source.Select (store);
286
} catch (System.IO.FileNotFoundException) {
288
} catch (System.Exception e){
289
// Sometimes we don't get the right exception, check for the file
290
if (!System.IO.File.Exists (photo.DefaultVersion.Uri.LocalPath)) {
293
// if the file is there but we still got an exception display it.
298
model = extended_metadata;
299
model.GetIterFirst(out iter);
301
if (store.StatementCount > 0) {
305
foreach (Statement stmt in store) {
306
// Skip anonymous subjects because they are
307
// probably part of a collection
308
if (stmt.Subject.Uri == null && store.SelectSubjects (null, stmt.Subject).Length > 0)
315
Description.GetDescription (store, stmt, out title, out value);
319
MemoryStore substore = store.Select (new Statement ((Entity)stmt.Object, null, null, null)).Load();
320
StringBuilder collection = new StringBuilder ();
321
collection.Append (title);
322
WriteCollection (substore, collection);
323
if (model.IterIsValid(iter))
325
model.SetValue (iter, 0, collection.ToString ());
326
model.IterNext(ref iter);
328
model.AppendValues (collection.ToString ());
330
s = String.Format ("{0}\n\t<small>{1}</small>", title, value);
331
if (model.IterIsValid(iter))
333
model.SetValue (iter, 0, s);
334
model.IterNext(ref iter);
336
model.AppendValues (s);
341
// clear Extended Metadata
342
String s = String.Format ("<small>{0}</small>", Catalog.GetString ("No Extended Metadata Available"));
343
if (model.IterIsValid(iter))
345
model.SetValue (iter, 0, s);
346
model.IterNext(ref iter);
348
model.AppendValues (s);
351
// remove rows, that are not used
352
while (model.IterIsValid(iter)) {
353
model.Remove (ref iter);
360
msg = Catalog.GetString ("No active photo");
361
} else if (missing) {
362
msg = String.Format (Catalog.GetString ("The photo \"{0}\" does not exist"), photo.DefaultVersion.Uri);
364
msg = Catalog.GetString ("No metadata available");
367
msg = String.Format ("<i>{0}</i>", error);
371
metadata_message.Markup = "<span weight=\"bold\">" + msg + "</span>";
373
if (display == State.metadata) {
374
// Child is a Viewport, (AddWithViewport in ctor)
375
((Viewport)Child).Remove (main_vbox);
376
((Viewport)Child).Add (metadata_message);
377
display = State.message;
378
metadata_message.Show ();
381
// remove Expanders, that are not used
382
while (index_of_expander < metadata_vbox.Children.Length)
383
metadata_vbox.Remove (metadata_vbox.Children[index_of_expander]);
385
if (display == State.message) {
386
// Child is a Viewport, (AddWithViewport in ctor)
387
((Viewport)Child).Remove (metadata_message);
388
((Viewport)Child).Add (main_vbox);
389
display = State.metadata;
390
main_vbox.ShowAll ();
398
private void WriteCollection (MemoryStore substore, StringBuilder collection)
402
foreach (Statement stmt in substore) {
403
if (stmt.Predicate.Uri == MetadataStore.Namespaces.Resolve ("rdf:type")) {
405
MetadataStore.Namespaces.Normalize (stmt.Object.Uri, out prefix, out type);
409
foreach (Statement sub in substore) {
410
if (sub.Object is SemWeb.Literal) {
412
string value = ((SemWeb.Literal)sub.Object).Value;
414
Description.GetDescription (substore, sub, out title, out value);
417
collection.AppendFormat ("\n\t<small>{0}: {1}</small>", title, value);
419
collection.AppendFormat ("\n\t<small>{0}</small>", value);
423
MemoryStore substore2 = substore.Select (new Statement ((Entity)sub.Object, null, null, null)).Load();
424
if (substore.StatementCount > 0)
425
WriteCollection (substore2, collection);