// // Copyright (C) 2008-2009 Jordi Mas i Hernandez, jmas@softcatala.org // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gtk; using System.IO; using System.Text; using Gdk; using Mistelix.DataModel; using System.ComponentModel; using System.Collections.Generic; using Mistelix.Core; namespace Mistelix.Widgets { // // This is a generic fileview used later derived for image and video preview // public class FileView : IconView, IDisposable { virtual public void OnDirChanged (string new_dir) {} virtual public bool IsValidExtension (string filename) {return false;} virtual public void DoThumbnail (object sender, EventArgs e) {} protected ListStore store; protected BackgroundWorker thumbnailing; protected Pixbuf def_image; protected DirectoryInfo parent = new DirectoryInfo ("/"); protected const int COL_PATH = 0; protected const int COL_DISPLAY_NAME = 1; protected const int COL_PIXBUF = 2; protected const int COL_IS_DIRECTORY = 3; protected int thumbnail_height; protected int thumbnail_width; TaskDispatcher dispatcher; protected FileView () { dispatcher = new TaskDispatcher (); store = CreateStore (); SelectionMode = SelectionMode.Multiple; TextColumn = COL_DISPLAY_NAME; PixbufColumn = COL_PIXBUF; thumbnail_height = ThumbnailSizeManager.Current.Height; thumbnail_width = ThumbnailSizeManager.Current.Width; CreateDefaultImage (); LoadElements (); Model = store; } ~FileView () { Dispose (false); } public List SelectedFiles { get { List files = new List (); TreeIter iter; TreePath[] items = SelectedItems; for (int i = 0; i < items.Length; i++) { store.GetIter (out iter, items [i]); files.Add ((string) store.GetValue (iter, COL_PATH)); } return files; } } ListStore CreateStore () { // path, name, pixbuf, is_dir ListStore store = new ListStore (typeof (string), typeof (string), typeof (Gdk.Pixbuf), typeof (bool)); return store; } public override void Dispose () { Console.WriteLine ("FileView.Dispose"); Dispose (true); System.GC.SuppressFinalize (this); } protected virtual void Dispose (bool disposing) { Logger.Debug ("Fileview.Disposing"); Clean (); if (thumbnailing != null) { thumbnailing.CancelAsync (); thumbnailing.Dispose (); } def_image.Dispose (); store.Dispose (); } public void LoadElements () { Logger.Debug ("FileView.LoadElements"); // Now go through the directory and extract all the file information if (!parent.Exists) return; // first clear the store Clean (); if (thumbnailing != null) thumbnailing.Dispose (); thumbnailing = new BackgroundWorker (); thumbnailing.WorkerSupportsCancellation = true; thumbnailing.DoWork += new DoWorkEventHandler (DoWork); // TODO: Optimize for directories with images videos foreach (FileInfo di in parent.GetFiles ()) { Task task; Gtk.TreeIter iter; if (di.Name.StartsWith (".") || IsValidExtension (di.Name) == false) continue; iter = store.AppendValues (di.FullName, di.Name, def_image, true); task = new Task (iter); task.DoEventHandler += DoThumbnail; dispatcher.AddTask (task); } thumbnailing.RunWorkerAsync (store); } void Clean () { store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter) { Gdk.Pixbuf im = (Gdk.Pixbuf) store.GetValue (iter, COL_PIXBUF); if (def_image != im) im.Dispose (); return false; }); store.Clear (); } void DoWork (object sender, DoWorkEventArgs e) { Task task; Logger.Debug ("FileView.Dowork start"); while (true) { if (thumbnailing.CancellationPending) break; task = dispatcher.GetNextTask (); if (task == null) break; task.Do (); } Logger.Debug ("FileView.Dowork end"); } void CreateDefaultImage () { const int channels = 4; Cairo.ImageSurface image; image = Utils.CreateNoPreviewImage (thumbnail_width, thumbnail_height); byte[] data = DataImageSurface.FromCairo32ToPixBuf (image.Data, thumbnail_width, thumbnail_height, channels); def_image = new Pixbuf (data, true, 8, thumbnail_width, thumbnail_height, thumbnail_width * channels, null); image.Destroy (); } } }