[f-spot] split big files, rename FolderTreeWidget to FolderTreeView
- From: Stephane Delcroix <sdelcroix src gnome org>
- To: svn-commits-list gnome org
- Subject: [f-spot] split big files, rename FolderTreeWidget to FolderTreeView
- Date: Mon, 6 Jul 2009 09:57:05 +0000 (UTC)
commit fcae03fa1716032b0fc04085a03c54c7b378e018
Author: Stephane Delcroix <stephane delcroix org>
Date: Mon Jul 6 11:53:05 2009 +0200
split big files, rename FolderTreeWidget to FolderTreeView
src/Makefile.am | 3 +
src/Widgets/CellRendererTextProgress.cs | 198 ++++++++++++
src/Widgets/FolderTreeModel.cs | 192 ++++++++++++
src/Widgets/FolderTreePage.cs | 514 +------------------------------
src/Widgets/FolderTreeView.cs | 174 +++++++++++
5 files changed, 569 insertions(+), 512 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index e31b793..8feee44 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -280,6 +280,9 @@ F_SPOT_CSDISTFILES = \
$(srcdir)/Widgets/Filmstrip.cs \
$(srcdir)/Widgets/FindBar.cs \
$(srcdir)/Widgets/FolderTreePage.cs \
+ $(srcdir)/Widgets/FolderTreeView.cs \
+ $(srcdir)/Widgets/FolderTreeModel.cs \
+ $(srcdir)/Widgets/CellRendererTextProgress.cs\
$(srcdir)/Widgets/IEffect.cs \
$(srcdir)/Widgets/ITransition.cs \
$(srcdir)/Widgets/IconView.cs \
diff --git a/src/Widgets/CellRendererTextProgress.cs b/src/Widgets/CellRendererTextProgress.cs
new file mode 100644
index 0000000..4a53f65
--- /dev/null
+++ b/src/Widgets/CellRendererTextProgress.cs
@@ -0,0 +1,198 @@
+/*
+ * FSpot.Widgets.CellRendererTextProgress.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+
+using System;
+using System.Collections.Generic;
+
+using Gtk;
+using GLib;
+
+using FSpot;
+using FSpot.Utils;
+
+using Banshee.Database;
+
+using Mono.Unix;
+using Mono.Data.SqliteClient;
+
+namespace FSpot.Widgets
+{
+ /*
+ * Because subclassing of CellRendererText does not to work, we
+ * use a new cellrenderer, which renderes a simple text and a
+ * progress bar below the text similar to the one used in baobab (gnome-utils)
+ */
+ public class CellRendererTextProgress : CellRenderer
+ {
+ readonly int progress_width;
+ readonly int progress_height;
+
+ Gdk.Color green;
+ Gdk.Color yellow;
+ Gdk.Color red;
+
+ public CellRendererTextProgress (int progress_width, int progress_height)
+ {
+ this.progress_width = progress_width;
+ this.progress_height = progress_height;
+
+ Xalign = 0.0f;
+ Yalign = 0.5f;
+
+ Xpad = 2;
+ Ypad = 2;
+
+ green = new Gdk.Color (0xcc, 0x00, 0x00);
+ yellow = new Gdk.Color (0xed, 0xd4, 0x00);
+ red = new Gdk.Color (0x73, 0xd2, 0x16);
+ }
+
+ public CellRendererTextProgress () : this (70, 8)
+ {
+ }
+
+ int progress_value;
+
+ [GLib.PropertyAttribute ("value")]
+ public int Value {
+ get { return progress_value; }
+ set {
+ /* normalize value */
+ progress_value = Math.Max (Math.Min (value, 100), 0);
+ }
+ }
+
+ Pango.Layout text_layout;
+ string text;
+
+ [GLib.PropertyAttribute ("text")]
+ public string Text {
+ get { return text; }
+ set {
+ if (text == value)
+ return;
+
+ text = value;
+ text_layout = null;
+ }
+ }
+
+ bool use_markup;
+ public bool UseMarkup {
+ get { return use_markup; }
+ set {
+ if (use_markup == value)
+ return;
+
+ use_markup = value;
+ text_layout = null;
+ }
+ }
+
+ private void UpdateLayout (Widget widget)
+ {
+ text_layout = new Pango.Layout (widget.PangoContext);
+
+ if (UseMarkup)
+ text_layout.SetMarkup (text);
+ else
+ text_layout.SetText (text);
+ }
+
+ private Gdk.Color GetValueColor ()
+ {
+ if (progress_value <= 33)
+ return green;
+
+ if (progress_value <= 66)
+ return yellow;
+
+ return red;
+ }
+
+ public override void GetSize (Gtk.Widget widget, ref Gdk.Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
+ {
+ if (text_layout == null)
+ UpdateLayout (widget);
+
+ int text_width, text_height;
+
+ text_layout.GetPixelSize (out text_width, out text_height);
+
+ width = (int) (2 * Xpad + Math.Max (progress_width, text_width));
+ height = (int) (3 * Ypad + progress_height + text_height);
+
+ x_offset = Math.Max ((int) (Xalign * (cell_area.Width - width)), 0);
+ y_offset = Math.Max ((int) (Yalign * (cell_area.Height - height)), 0);
+ }
+
+ protected override void Render (Gdk.Drawable window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags)
+ {
+ base.Render (window, widget, background_area, cell_area, expose_area, flags);
+
+ if (text_layout == null)
+ UpdateLayout (widget);
+
+ int x, y, width, height, text_width, text_height;
+
+ /* first render the text */
+ text_layout.GetPixelSize (out text_width, out text_height);
+
+ x = (int) (cell_area.X + Xpad + Math.Max ((int) (Xalign * (cell_area.Width - 2 * Xpad - text_width)), 0));
+ y = (int) (cell_area.Y + Ypad);
+
+ Style.PaintLayout (widget.Style,
+ window,
+ StateType.Normal,
+ true,
+ cell_area,
+ widget,
+ "cellrenderertextprogress",
+ x, y,
+ text_layout);
+
+ y += (int) (text_height + Ypad);
+ x = (int) (cell_area.X + Xpad + Math.Max ((int) (Xalign * (cell_area.Width - 2 * Xpad - progress_width)), 0));
+
+
+ /* second render the progress bar */
+
+ /* dispose cairo object after usage */
+ using (Cairo.Context cairo_context = Gdk.CairoHelper.Create (window)) {
+
+ width = progress_width;
+ height = progress_height;
+
+ cairo_context.Rectangle (x, y, width, height);
+ Gdk.CairoHelper.SetSourceColor (cairo_context, widget.Style.Dark (StateType.Normal));
+ cairo_context.Fill ();
+
+ x += widget.Style.XThickness;
+ y += widget.Style.XThickness;
+ width -= 2* widget.Style.XThickness;
+ height -= 2 * widget.Style.Ythickness;
+
+ cairo_context.Rectangle (x, y, width, height);
+ Gdk.CairoHelper.SetSourceColor (cairo_context, widget.Style.Light (StateType.Normal));
+ cairo_context.Fill ();
+
+ /* scale the value and ensure, that at least one pixel is drawn, if the value is greater than zero */
+ int scaled_width =
+ (int) Math.Max (((progress_value * width) / 100.0),
+ (progress_value == 0)? 0 : 1);
+
+ cairo_context.Rectangle (x, y, scaled_width, height);
+ Gdk.CairoHelper.SetSourceColor (cairo_context, GetValueColor ());
+ cairo_context.Fill ();
+ }
+ }
+
+ }
+}
diff --git a/src/Widgets/FolderTreeModel.cs b/src/Widgets/FolderTreeModel.cs
new file mode 100644
index 0000000..53f1688
--- /dev/null
+++ b/src/Widgets/FolderTreeModel.cs
@@ -0,0 +1,192 @@
+/*
+ * FSpot.Widgets.FolderTreeModel.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+using System;
+using System.Collections.Generic;
+
+using Gtk;
+using GLib;
+
+using FSpot;
+using FSpot.Utils;
+
+using Banshee.Database;
+
+using Mono.Unix;
+using Mono.Data.SqliteClient;
+
+namespace FSpot.Widgets
+{
+ public class FolderTreeModel : TreeStore
+ {
+ Db database;
+
+ const string query_string =
+ "SELECT base_uri, COUNT(*) AS count " +
+ "FROM photos " +
+ "GROUP BY base_uri " +
+ "ORDER BY base_uri DESC";
+
+
+ public FolderTreeModel ()
+ : base (typeof (string), typeof (int), typeof (Uri))
+ {
+ database = MainWindow.Toplevel.Database;
+ database.Photos.ItemsChanged += HandlePhotoItemsChanged;
+
+ UpdateFolderTree ();
+ }
+
+ void HandlePhotoItemsChanged (object sender, DbItemEventArgs<Photo> e)
+ {
+ UpdateFolderTree ();
+ }
+
+ public string GetFolderNameByIter (TreeIter iter)
+ {
+ if ( ! IterIsValid (iter))
+ return null;
+
+ return (string) GetValue (iter, 0);
+ }
+
+ public int GetPhotoCountByIter (TreeIter iter)
+ {
+ if ( ! IterIsValid (iter))
+ return -1;
+
+ return (int) GetValue (iter, 1);
+ }
+
+ public Uri GetUriByIter (TreeIter iter)
+ {
+ if ( ! IterIsValid (iter))
+ return null;
+
+ return (Uri) GetValue (iter, 2);
+ }
+
+ public Uri GetUriByPath (TreePath row)
+ {
+ TreeIter iter;
+
+ GetIter (out iter, row);
+
+ return GetUriByIter (iter);
+ }
+
+ int count_all;
+ public int Count {
+ get { return count_all; }
+ }
+
+ /*
+ * UpdateFolderTree queries for directories in database and updates
+ * a possibly existing folder-tree to the queried structure
+ */
+ private void UpdateFolderTree ()
+ {
+ Clear ();
+
+ count_all = 0;
+
+ /* points at start of each iteration to the leaf of the last inserted uri */
+ TreeIter iter = TreeIter.Zero;
+
+ /* stores the segments of the last inserted uri */
+ string[] last_segments = new string[] {};
+
+ int last_count = 0;
+
+ SqliteDataReader reader = database.Database.Query (query_string);
+
+ while (reader.Read ()) {
+ Uri base_uri = new Uri (reader["base_uri"].ToString ());
+
+ if ( ! base_uri.IsAbsoluteUri) {
+ FSpot.Utils.Log.Error ("Uri must be absolute: {0}", base_uri.ToString ());
+ continue;
+ }
+
+ int count = Convert.ToInt32 (reader["count"]);
+
+ string[] segments = base_uri.Segments;
+
+ /*
+ * since we have an absolute uri, first segement starts with "/" according
+ * to the msdn doc. So we can overwrite the first segment for our needs and
+ * put the scheme here.
+ */
+ segments[0] = base_uri.Scheme;
+
+ int i = 0;
+
+ /* find first difference of last inserted an current uri */
+ while (i < last_segments.Length && i < segments.Length) {
+
+ /* remove suffix '/', which are appended to every directory (see msdn-doc) */
+ segments[i] = segments[i].TrimEnd ('/');
+
+ if (segments[i] != last_segments[i])
+ break;
+
+ i++;
+ }
+
+ /* points to the parent node of the current iter */
+ TreeIter parent_iter = iter;
+
+ /* step back to the level, where the difference occur */
+ for (int j = 0; j + i < last_segments.Length; j++) {
+
+ iter = parent_iter;
+
+ if (IterParent (out parent_iter, iter)) {
+ last_count += (int)GetValue (parent_iter, 1);
+ SetValue (parent_iter, 1, last_count);
+ } else
+ count_all += (int)last_count;
+ }
+
+ while (i < segments.Length) {
+ segments[i] = segments[i].TrimEnd ('/');
+
+ if (IterIsValid (parent_iter))
+ iter =
+ AppendValues (parent_iter,
+ segments[i],
+ (segments.Length - 1 == i)? count : 0,
+ new Uri ((Uri) GetValue (parent_iter, 2),
+ String.Format ("{0}/", segments[i]))
+ );
+ else
+ iter =
+ AppendValues (segments[i],
+ (segments.Length - 1 == i)? count : 0,
+ new Uri (base_uri, "/"));
+
+ parent_iter = iter;
+
+ i++;
+ }
+
+ last_count = count;
+ last_segments = segments;
+
+ }
+
+ /* and at least, step back and update photo count */
+ while (IterParent (out iter, iter)) {
+ last_count += (int)GetValue (iter, 1);
+ SetValue (iter, 1, last_count);
+ }
+ count_all += (int)last_count;
+ }
+ }
+}
diff --git a/src/Widgets/FolderTreePage.cs b/src/Widgets/FolderTreePage.cs
index e552c74..f99faa8 100644
--- a/src/Widgets/FolderTreePage.cs
+++ b/src/Widgets/FolderTreePage.cs
@@ -7,532 +7,22 @@
* This is free software. See COPYING for details.
*/
-
using System;
-using System.Collections.Generic;
-
using Gtk;
-
-using GLib;
-
-using FSpot;
-using FSpot.Utils;
-
-using Banshee.Database;
-
using Mono.Unix;
-using Mono.Data.SqliteClient;
-
-
namespace FSpot.Widgets
{
-
-
public class FolderTreePage : SidebarPage
{
- private readonly FolderTreeWidget folder_tree_widget;
-
-
+ readonly FolderTreeView folder_tree_widget;
public FolderTreePage ()
: base (new ScrolledWindow (), Catalog.GetString ("Folders"), "gtk-directory")
{
ScrolledWindow scrolled_window = SidebarWidget as ScrolledWindow;
- folder_tree_widget = new FolderTreeWidget ();
+ folder_tree_widget = new FolderTreeView ();
scrolled_window.Add (folder_tree_widget);
}
-
- protected override void AddedToSidebar () {
- }
- }
-
- public class FolderTreeWidget : SaneTreeView
- {
- FolderTreeModel folder_tree_model;
-
- public FolderTreeWidget () : this (new FolderTreeModel ())
- {
- }
-
- public FolderTreeWidget (FolderTreeModel tree_model) : base (tree_model)
- {
- folder_tree_model = tree_model;
-
- HeadersVisible = false;
-
- TreeViewColumn column = new TreeViewColumn ();
-
- CellRendererPixbuf pixbuf_renderer = new CellRendererPixbuf ();
- column.PackStart (pixbuf_renderer, false);
- column.SetCellDataFunc (pixbuf_renderer, PixbufDataFunc as TreeCellDataFunc);
-
- CellRendererTextProgress folder_renderer = new CellRendererTextProgress ();
- column.PackStart (folder_renderer, true);
- column.SetCellDataFunc (folder_renderer, FolderDataFunc as TreeCellDataFunc);
-
- AppendColumn (column);
-
- Gtk.Drag.SourceSet (this, Gdk.ModifierType.Button1Mask | Gdk.ModifierType.Button3Mask,
- folder_tree_source_target_table, Gdk.DragAction.Copy | Gdk.DragAction.Move);
- }
-
- public UriList SelectedUris {
- get {
- UriList list = new UriList ();
-
- TreePath[] selected_rows = Selection.GetSelectedRows ();
-
- foreach (TreePath row in selected_rows)
- list.Add (folder_tree_model.GetUriByPath (row));
-
- return list;
- }
- }
-
- private void PixbufDataFunc (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
- {
- CellRendererPixbuf renderer = cell as CellRendererPixbuf;
- string text = folder_tree_model.GetFolderNameByIter (iter);
-
- string stock;
- File file = FileFactory.NewForUri (folder_tree_model.GetUriByIter (iter));
- try {
- FileInfo info =
- file.QueryInfo ("standard::icon", FileQueryInfoFlags.None, null);
-
- ThemedIcon themed_icon = info.Icon as ThemedIcon;
- if (themed_icon != null && themed_icon.Names.Length > 0)
- stock = themed_icon.Names[0];
- else
- stock = "gtk-directory";
-
- } catch (Exception e) {
- stock = "gtk-directory";
- }
-
- TreeIter tmp;
- if (tree_model.IterParent (out tmp, iter)) {
- renderer.IconName = stock;
- renderer.CellBackground = null;
- } else {
- renderer.IconName = stock;
- renderer.CellBackgroundGdk = Style.Background (StateType.Selected);
- }
- }
-
- private void FolderDataFunc (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
- {
- CellRendererTextProgress renderer = cell as CellRendererTextProgress;
-
- int progress_value = 0;
- int count = (tree_model as FolderTreeModel).Count;
-
- if (count != 0)
- progress_value = (int) ((100.0 * folder_tree_model.GetPhotoCountByIter (iter)) / count);
-
- renderer.Value = progress_value;
-
- string text = folder_tree_model.GetFolderNameByIter (iter);
-
- TreeIter tmp;
- if (tree_model.IterParent (out tmp, iter)) {
- renderer.UseMarkup = false;
- renderer.Text = text;
- renderer.CellBackground = null;
- } else {
- renderer.UseMarkup = true;
-
- /* since import do not use GIO at the moment, no other prefix than file:/// is
- * possible.
- */
- if (text == Uri.UriSchemeFile)
- renderer.Text = String.Format ("<b>{0}</b>", Catalog.GetString ("Filesystem"));
- else
- renderer.Text = String.Format ("<b>{0}</b>", text);
-
- renderer.CellBackgroundGdk = Style.Background (StateType.Selected);
- }
- }
-
- private string GetStock (string scheme)
- {
- /* not very usefull at the moment */
- if (scheme == Uri.UriSchemeFile)
- return "gtk-directory";
-
- return "gtk-directory";
- }
-
- private static TargetEntry [] folder_tree_source_target_table =
- new TargetEntry [] {
- DragDropTargets.UriQueryEntry,
- DragDropTargets.UriListEntry,
- DragDropTargets.PlainTextEntry
- };
-
-
- protected override void OnDragDataGet (Gdk.DragContext context, Gtk.SelectionData selection_data, uint info, uint time_)
- {
- if (info == DragDropTargets.UriQueryEntry.Info
- || info == DragDropTargets.UriListEntry.Info
- || info == DragDropTargets.PlainTextEntry.Info) {
-
- selection_data.SetUriListData (SelectedUris, context.Targets[0]);
- return;
- }
- }
-
- protected override bool OnDragDrop (Gdk.DragContext context, int x, int y, uint time_)
- {
- return true;
- }
-
- protected override void OnRowActivated (Gtk.TreePath path, Gtk.TreeViewColumn column)
- {
- MainWindow.Toplevel.SetFolderQuery (SelectedUris);
- }
-
- }
-
-
- /*
- * Because subclassing of CellRendererText does not to work, we
- * use a new cellrenderer, which renderes a simple text and a
- * progress bar below the text similar to the one used in baobab (gnome-utils)
- */
- public class CellRendererTextProgress : CellRenderer
- {
- readonly int progress_width;
- readonly int progress_height;
-
- Gdk.Color green;
- Gdk.Color yellow;
- Gdk.Color red;
-
- public CellRendererTextProgress (int progress_width, int progress_height)
- {
- this.progress_width = progress_width;
- this.progress_height = progress_height;
-
- Xalign = 0.0f;
- Yalign = 0.5f;
-
- Xpad = 2;
- Ypad = 2;
-
- green = new Gdk.Color (0xcc, 0x00, 0x00);
- yellow = new Gdk.Color (0xed, 0xd4, 0x00);
- red = new Gdk.Color (0x73, 0xd2, 0x16);
- }
-
- public CellRendererTextProgress () : this (70, 8)
- {
- }
-
- int progress_value;
-
- [GLib.PropertyAttribute ("value")]
- public int Value {
- get { return progress_value; }
- set {
- /* normalize value */
- progress_value = Math.Max (Math.Min (value, 100), 0);
- }
- }
-
- Pango.Layout text_layout;
- string text;
-
- [GLib.PropertyAttribute ("text")]
- public string Text {
- get { return text; }
- set {
- if (text == value)
- return;
-
- text = value;
- text_layout = null;
- }
- }
-
- bool use_markup;
- public bool UseMarkup {
- get { return use_markup; }
- set {
- if (use_markup == value)
- return;
-
- use_markup = value;
- text_layout = null;
- }
- }
-
- private void UpdateLayout (Widget widget)
- {
- text_layout = new Pango.Layout (widget.PangoContext);
-
- if (UseMarkup)
- text_layout.SetMarkup (text);
- else
- text_layout.SetText (text);
- }
-
- private Gdk.Color GetValueColor ()
- {
- if (progress_value <= 33)
- return green;
-
- if (progress_value <= 66)
- return yellow;
-
- return red;
- }
-
- public override void GetSize (Gtk.Widget widget, ref Gdk.Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
- {
- if (text_layout == null)
- UpdateLayout (widget);
-
- int text_width, text_height;
-
- text_layout.GetPixelSize (out text_width, out text_height);
-
- width = (int) (2 * Xpad + Math.Max (progress_width, text_width));
- height = (int) (3 * Ypad + progress_height + text_height);
-
- x_offset = Math.Max ((int) (Xalign * (cell_area.Width - width)), 0);
- y_offset = Math.Max ((int) (Yalign * (cell_area.Height - height)), 0);
- }
-
- protected override void Render (Gdk.Drawable window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags)
- {
- base.Render (window, widget, background_area, cell_area, expose_area, flags);
-
- if (text_layout == null)
- UpdateLayout (widget);
-
- int x, y, width, height, text_width, text_height;
-
- /* first render the text */
- text_layout.GetPixelSize (out text_width, out text_height);
-
- x = (int) (cell_area.X + Xpad + Math.Max ((int) (Xalign * (cell_area.Width - 2 * Xpad - text_width)), 0));
- y = (int) (cell_area.Y + Ypad);
-
- Style.PaintLayout (widget.Style,
- window,
- StateType.Normal,
- true,
- cell_area,
- widget,
- "cellrenderertextprogress",
- x, y,
- text_layout);
-
- y += (int) (text_height + Ypad);
- x = (int) (cell_area.X + Xpad + Math.Max ((int) (Xalign * (cell_area.Width - 2 * Xpad - progress_width)), 0));
-
-
- /* second render the progress bar */
-
- /* dispose cairo object after usage */
- using (Cairo.Context cairo_context = Gdk.CairoHelper.Create (window)) {
-
- width = progress_width;
- height = progress_height;
-
- cairo_context.Rectangle (x, y, width, height);
- Gdk.CairoHelper.SetSourceColor (cairo_context, widget.Style.Dark (StateType.Normal));
- cairo_context.Fill ();
-
- x += widget.Style.XThickness;
- y += widget.Style.XThickness;
- width -= 2* widget.Style.XThickness;
- height -= 2 * widget.Style.Ythickness;
-
- cairo_context.Rectangle (x, y, width, height);
- Gdk.CairoHelper.SetSourceColor (cairo_context, widget.Style.Light (StateType.Normal));
- cairo_context.Fill ();
-
- /* scale the value and ensure, that at least one pixel is drawn, if the value is greater than zero */
- int scaled_width =
- (int) Math.Max (((progress_value * width) / 100.0),
- (progress_value == 0)? 0 : 1);
-
- cairo_context.Rectangle (x, y, scaled_width, height);
- Gdk.CairoHelper.SetSourceColor (cairo_context, GetValueColor ());
- cairo_context.Fill ();
- }
- }
-
- }
-
-
- public class FolderTreeModel : TreeStore
- {
- Db database;
-
- const string query_string =
- "SELECT base_uri, COUNT(*) AS count " +
- "FROM photos " +
- "GROUP BY base_uri " +
- "ORDER BY base_uri DESC";
-
-
- public FolderTreeModel ()
- : base (typeof (string), typeof (int), typeof (Uri))
- {
- database = MainWindow.Toplevel.Database;
- database.Photos.ItemsChanged += HandlePhotoItemsChanged;
-
- UpdateFolderTree ();
- }
-
- void HandlePhotoItemsChanged (object sender, DbItemEventArgs<Photo> e)
- {
- UpdateFolderTree ();
- }
-
- public string GetFolderNameByIter (TreeIter iter)
- {
- if ( ! IterIsValid (iter))
- return null;
-
- return (string) GetValue (iter, 0);
- }
-
- public int GetPhotoCountByIter (TreeIter iter)
- {
- if ( ! IterIsValid (iter))
- return -1;
-
- return (int) GetValue (iter, 1);
- }
-
- public Uri GetUriByIter (TreeIter iter)
- {
- if ( ! IterIsValid (iter))
- return null;
-
- return (Uri) GetValue (iter, 2);
- }
-
- public Uri GetUriByPath (TreePath row)
- {
- TreeIter iter;
-
- GetIter (out iter, row);
-
- return GetUriByIter (iter);
- }
-
- int count_all;
- public int Count {
- get { return count_all; }
- }
-
- /*
- * UpdateFolderTree queries for directories in database and updates
- * a possibly existing folder-tree to the queried structure
- */
- private void UpdateFolderTree ()
- {
- Clear ();
-
- count_all = 0;
-
- /* points at start of each iteration to the leaf of the last inserted uri */
- TreeIter iter = TreeIter.Zero;
-
- /* stores the segments of the last inserted uri */
- string[] last_segments = new string[] {};
-
- int last_count = 0;
-
- SqliteDataReader reader = database.Database.Query (query_string);
-
- while (reader.Read ()) {
- Uri base_uri = new Uri (reader["base_uri"].ToString ());
-
- if ( ! base_uri.IsAbsoluteUri) {
- FSpot.Utils.Log.Error ("Uri must be absolute: {0}", base_uri.ToString ());
- continue;
- }
-
- int count = Convert.ToInt32 (reader["count"]);
-
- string[] segments = base_uri.Segments;
-
- /*
- * since we have an absolute uri, first segement starts with "/" according
- * to the msdn doc. So we can overwrite the first segment for our needs and
- * put the scheme here.
- */
- segments[0] = base_uri.Scheme;
-
- int i = 0;
-
- /* find first difference of last inserted an current uri */
- while (i < last_segments.Length && i < segments.Length) {
-
- /* remove suffix '/', which are appended to every directory (see msdn-doc) */
- segments[i] = segments[i].TrimEnd ('/');
-
- if (segments[i] != last_segments[i])
- break;
-
- i++;
- }
-
- /* points to the parent node of the current iter */
- TreeIter parent_iter = iter;
-
- /* step back to the level, where the difference occur */
- for (int j = 0; j + i < last_segments.Length; j++) {
-
- iter = parent_iter;
-
- if (IterParent (out parent_iter, iter)) {
- last_count += (int)GetValue (parent_iter, 1);
- SetValue (parent_iter, 1, last_count);
- } else
- count_all += (int)last_count;
- }
-
- while (i < segments.Length) {
- segments[i] = segments[i].TrimEnd ('/');
-
- if (IterIsValid (parent_iter))
- iter =
- AppendValues (parent_iter,
- segments[i],
- (segments.Length - 1 == i)? count : 0,
- new Uri ((Uri) GetValue (parent_iter, 2),
- String.Format ("{0}/", segments[i]))
- );
- else
- iter =
- AppendValues (segments[i],
- (segments.Length - 1 == i)? count : 0,
- new Uri (base_uri, "/"));
-
- parent_iter = iter;
-
- i++;
- }
-
- last_count = count;
- last_segments = segments;
-
- }
-
- /* and at least, step back and update photo count */
- while (IterParent (out iter, iter)) {
- last_count += (int)GetValue (iter, 1);
- SetValue (iter, 1, last_count);
- }
- count_all += (int)last_count;
- }
}
}
diff --git a/src/Widgets/FolderTreeView.cs b/src/Widgets/FolderTreeView.cs
new file mode 100644
index 0000000..609935d
--- /dev/null
+++ b/src/Widgets/FolderTreeView.cs
@@ -0,0 +1,174 @@
+/*
+ * FSpot.Widgets.FolderTreeView.cs
+ *
+ * Author(s)
+ * Mike Gemuende <mike gemuende de>
+ *
+ * This is free software. See COPYING for details.
+ */
+
+
+using System;
+using System.Collections.Generic;
+
+using Gtk;
+using GLib;
+
+using FSpot;
+using FSpot.Utils;
+
+using Banshee.Database;
+
+using Mono.Unix;
+using Mono.Data.SqliteClient;
+
+namespace FSpot.Widgets
+{
+ public class FolderTreeView : SaneTreeView
+ {
+ FolderTreeModel folder_tree_model;
+
+ public FolderTreeView () : this (new FolderTreeModel ())
+ {
+ }
+
+ public FolderTreeView (FolderTreeModel tree_model) : base (tree_model)
+ {
+ folder_tree_model = tree_model;
+
+ HeadersVisible = false;
+
+ TreeViewColumn column = new TreeViewColumn ();
+
+ CellRendererPixbuf pixbuf_renderer = new CellRendererPixbuf ();
+ column.PackStart (pixbuf_renderer, false);
+ column.SetCellDataFunc (pixbuf_renderer, PixbufDataFunc as TreeCellDataFunc);
+
+ CellRendererTextProgress folder_renderer = new CellRendererTextProgress ();
+ column.PackStart (folder_renderer, true);
+ column.SetCellDataFunc (folder_renderer, FolderDataFunc as TreeCellDataFunc);
+
+ AppendColumn (column);
+
+ Gtk.Drag.SourceSet (this, Gdk.ModifierType.Button1Mask | Gdk.ModifierType.Button3Mask,
+ folder_tree_source_target_table, Gdk.DragAction.Copy | Gdk.DragAction.Move);
+ }
+
+ public UriList SelectedUris {
+ get {
+ UriList list = new UriList ();
+
+ TreePath[] selected_rows = Selection.GetSelectedRows ();
+
+ foreach (TreePath row in selected_rows)
+ list.Add (folder_tree_model.GetUriByPath (row));
+
+ return list;
+ }
+ }
+
+ private void PixbufDataFunc (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
+ {
+ CellRendererPixbuf renderer = cell as CellRendererPixbuf;
+ string text = folder_tree_model.GetFolderNameByIter (iter);
+
+ string stock;
+ File file = FileFactory.NewForUri (folder_tree_model.GetUriByIter (iter));
+ try {
+ FileInfo info =
+ file.QueryInfo ("standard::icon", FileQueryInfoFlags.None, null);
+
+ ThemedIcon themed_icon = info.Icon as ThemedIcon;
+ if (themed_icon != null && themed_icon.Names.Length > 0)
+ stock = themed_icon.Names[0];
+ else
+ stock = "gtk-directory";
+
+ } catch (Exception e) {
+ stock = "gtk-directory";
+ }
+
+ TreeIter tmp;
+ if (tree_model.IterParent (out tmp, iter)) {
+ renderer.IconName = stock;
+ renderer.CellBackground = null;
+ } else {
+ renderer.IconName = stock;
+ renderer.CellBackgroundGdk = Style.Background (StateType.Selected);
+ }
+ }
+
+ private void FolderDataFunc (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
+ {
+ CellRendererTextProgress renderer = cell as CellRendererTextProgress;
+
+ int progress_value = 0;
+ int count = (tree_model as FolderTreeModel).Count;
+
+ if (count != 0)
+ progress_value = (int) ((100.0 * folder_tree_model.GetPhotoCountByIter (iter)) / count);
+
+ renderer.Value = progress_value;
+
+ string text = folder_tree_model.GetFolderNameByIter (iter);
+
+ TreeIter tmp;
+ if (tree_model.IterParent (out tmp, iter)) {
+ renderer.UseMarkup = false;
+ renderer.Text = text;
+ renderer.CellBackground = null;
+ } else {
+ renderer.UseMarkup = true;
+
+ /* since import do not use GIO at the moment, no other prefix than file:/// is
+ * possible.
+ */
+ if (text == Uri.UriSchemeFile)
+ renderer.Text = String.Format ("<b>{0}</b>", Catalog.GetString ("Filesystem"));
+ else
+ renderer.Text = String.Format ("<b>{0}</b>", text);
+
+ renderer.CellBackgroundGdk = Style.Background (StateType.Selected);
+ }
+ }
+
+ private string GetStock (string scheme)
+ {
+ /* not very usefull at the moment */
+ if (scheme == Uri.UriSchemeFile)
+ return "gtk-directory";
+
+ return "gtk-directory";
+ }
+
+ private static TargetEntry [] folder_tree_source_target_table =
+ new TargetEntry [] {
+ DragDropTargets.UriQueryEntry,
+ DragDropTargets.UriListEntry,
+ DragDropTargets.PlainTextEntry
+ };
+
+
+ protected override void OnDragDataGet (Gdk.DragContext context, Gtk.SelectionData selection_data, uint info, uint time_)
+ {
+ if (info == DragDropTargets.UriQueryEntry.Info
+ || info == DragDropTargets.UriListEntry.Info
+ || info == DragDropTargets.PlainTextEntry.Info) {
+
+ selection_data.SetUriListData (SelectedUris, context.Targets[0]);
+ return;
+ }
+ }
+
+ protected override bool OnDragDrop (Gdk.DragContext context, int x, int y, uint time_)
+ {
+ return true;
+ }
+
+ protected override void OnRowActivated (Gtk.TreePath path, Gtk.TreeViewColumn column)
+ {
+ MainWindow.Toplevel.SetFolderQuery (SelectedUris);
+ }
+
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]