Logo Search packages:      
Sourcecode: hipo version File versions

HipoMainWindow.cs

/* Hipo - iPod management tool
 *
 * Pedro Villavicencio Garrido <pvillavi@gnome.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * (C) Copyright 2006-2007 Pedro Villavicencio Garrido <pvillavi@gnome.org>.
 */

using System;
using System.IO;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using Gtk;
using Gdk;
using Glade;
using Gnome;
using IPod;
using Mono.Unix;

namespace Hipo
{
      internal class EditableCellRenderer : CellRendererText
      {
            private int column;
            
            public EditableCellRenderer ()
            {
                  base.Editable = true;
            }
            
            public int Column
            {
                  get { return column; }
                  set { column = value; }
            }
      }
      
      public class HipoMainWindow
      {

            [Widget] private Gtk.Window hipoWindow;
            [Widget] private Gtk.VBox vbox1;
            [Widget] private Gtk.TreeView tracksView;
            [Widget] private Gtk.TreeView plistView;
            [Widget] private Gtk.Entry filterEntry;
            [Widget] private Gtk.ProgressBar ipodCapacityBar;
            [Widget] private Gtk.Statusbar statusbar1;
            
            private Glade.XML gxml;
            private Gnome.Program program;
            private DeviceCombo combo;
            private IPod.Device device = null;
            private TrackDatabase db = null;
            private TracksView  tracks;
            private PlaylistView playlists;
            private Label numTracks;
            private ThreadNotify notify;
            private string[] uris;
            private UIManager uim = null;
            private Gtk.Menu menu;
            private Hashtable menuTable;
            private Gtk.Image coverpreview;
            private ProgressDialog pdialog;
            
            ActionGroup group = null;
                   
            private static TargetEntry [] tracksview_source_entries = {
                        new TargetEntry ("text/uri-list", 0, 0)
                };

                private static TargetEntry [] playlist_dest_entries = {
                        new TargetEntry ("text/uri-list", 0, 0)
                };

            public void CreateWindow (string [] args)
            {
                  program = new Program (Defines.PACKAGE, Defines.VERSION, Modules.UI, args);

                  gxml = new Glade.XML (null, "hipo.glade", "hipoWindow", null);
                  gxml.Autoconnect (this);

                  combo = new DeviceCombo ();
                  tracks = new TracksView ();
                  playlists = new PlaylistView ();
                  
                  ActionEntry[] entries =  {

                        new ActionEntry ("FileMenu", null, Catalog.GetString ("_File"), null, null, null),
                        new ActionEntry ("EditMenu", null, Catalog.GetString ("_Edit"), null, null, null),
                        new ActionEntry ("HelpMenu", null, Catalog.GetString ("_Help"), null, null, null),
                        new ActionEntry ("AddFile", Gtk.Stock.Add, Catalog.GetString ("_Add File..."), null,
                                     Catalog.GetString ("Add a file to your iPod"), OnAddActivated),
                        new ActionEntry ("AddFolder", Gtk.Stock.Add, Catalog.GetString ("Add Folder..."),  "<control>O",
                                     Catalog.GetString ("Add a folder to your iPod"), OnAddFolder),
                        new ActionEntry ("Remove", Gtk.Stock.Remove, Catalog.GetString ("_Remove"), null,
                                     Catalog.GetString ("Remove a file from your iPod"), OnRemoveActivated),
                        new ActionEntry ("AddToPlaylist", Gtk.Stock.Add, Catalog.GetString ("Add to Playlist..."), null,
                                     Catalog.GetString ("Add file to a Playlist"), null),

                        new ActionEntry ("TrackProperties", Gtk.Stock.Properties, Catalog.GetString ("Track Properties"), null,
                                     Catalog.GetString ("Track Properties"), OnTrackProperties),
                        
                        new ActionEntry ("RemoveFromPlaylist", Gtk.Stock.Remove, Catalog.GetString ("_Remove from Playlist"), null,
                                     Catalog.GetString ("Remove the track from the Playlist"), OnRemoveFromPlaylist),
                        new ActionEntry ("Eject", null, Catalog.GetString ("_Eject"), null, null, OnEjectActivated),
                        new ActionEntry ("Quit", Gtk.Stock.Quit, Catalog.GetString ("_Quit"), null, null, OnQuitActivated),
                        new ActionEntry ("Preferences", Gtk.Stock.Preferences, Catalog.GetString ("Prefere_nces"), null,
                                     null, OnPreferences),
                        new ActionEntry ("Help", Gtk.Stock.Help, Catalog.GetString ("_Contents"), "F1",
                                     null, OnHelp),
                        new ActionEntry ("About", Gnome.Stock.About, Catalog.GetString ("_About"), null,
                                     null, OnAboutActivated),

                        new ActionEntry ("NewPlaylist", Gtk.Stock.New, Catalog.GetString ("New Playlist"), null,
                                     Catalog.GetString ("Create a new Playlist"), OnNewPlaylist),
                        new ActionEntry ("DeletePlaylist", Gtk.Stock.Remove, Catalog.GetString ("Delete Playlist"), null,
                                     Catalog.GetString ("Delete the Playlist"), OnDeletePlaylist),

                        new ActionEntry ("OnDeviceProperties", Gtk.Stock.Properties, Catalog.GetString ("Device Properties"), null,
                                     Catalog.GetString ("Device Properties"), OnDeviceProperties)
                  };

                  group = new ActionGroup ("Hipo");
                  group.Add (entries);

                  uim = new UIManager ();
                  uim.InsertActionGroup (group, 0);
                  uim.AddUiFromResource ("hipo.xml");
                  
                  numTracks = new Gtk.Label ("(0)");
                  numTracks.UseMarkup = true;
                  
                  hipoWindow.Icon = Gnome.IconTheme.Default.LoadIcon ("gnome-dev-ipod", 16, 0);
                  
                  vbox1.PackStart (uim.GetWidget ("/HipoMenu"), false, false, 0);
                  vbox1.ReorderChild (uim.GetWidget ("/HipoMenu"), 0);
                  menu = (Gtk.Menu) uim.GetWidget ("/ui/TracksPopup");
                  
                  CreateTreeView ();
                  
                  tracksView.Model = tracks.GetModel ();
                  plistView.Model = playlists.GetModel ();

                  tracksView.EnableSearch = true;
                  tracksView.SearchEntry = filterEntry;
                  
                  combo.Changed += OnDeviceChanged;
                  
                  tracksView.ButtonPressEvent += OnTracksButtonPress;
                  tracksView.PopupMenu += OnTracksPopupMenu;

                  tracksView.EnableModelDragSource (Gdk.ModifierType.Button1Mask,
                                            tracksview_source_entries, Gdk.DragAction.Copy);

                  tracksView.DragDataGet += OnTracksDragDataGet;
                  tracksView.Selection.Mode = SelectionMode.Multiple;
                  
                  plistView.ButtonPressEvent += OnPlaylistButtonPress;
                  plistView.PopupMenu += OnPlaylistPopupMenu;
                  
                  plistView.EnableModelDragDest (playlist_dest_entries, Gdk.DragAction.Copy);

                  plistView.DragDataReceived += OnPlistDragDataReceived;
                  
                  hipoWindow.DeleteEvent += OnDeleteEvent;
                  plistView.Selection.Changed += OnPlaylistSelectionChanged;
                  
                  menuTable = new Hashtable ();
                  coverpreview = new Gtk.Image ();

                  pdialog = new ProgressDialog (hipoWindow);

                  hipoWindow.ShowAll ();

                  SetDevice ();

                  program.Run ();
            }

            private void CreateTreeView ()
            {
                  EditableCellRenderer cell = new EditableCellRenderer ();
                  cell.Edited += OnEdit;
                  cell.Column = 0;
                  
                  TreeViewColumn column = new Gtk.TreeViewColumn (Catalog.GetString ("Artist"),
                                                      cell, "text", 0);
                  column.Resizable = true;
                  column.Expand = false;
                  column.SortIndicator = true;
                  column.SortColumnId = 0;
                  
                  tracksView.AppendColumn (column);
                  
                  cell = new EditableCellRenderer ();
                  cell.Edited += OnEdit;
                  cell.Column = 1;
                  
                  column = new Gtk.TreeViewColumn (Catalog.GetString ("Album"),
                                           cell, "text", 1);
                  column.Resizable = true;
                  column.Expand = false;
                  column.SortIndicator = true;
                  column.SortColumnId = 1;
                  
                  tracksView.AppendColumn (column);
                  
                  cell = new EditableCellRenderer ();
                  cell.Edited += OnEdit;
                  cell.Column = 2;
                  
                  column = new Gtk.TreeViewColumn (Catalog.GetString ("Title"),
                                           cell, "text", 2);
                  column.Resizable = true;
                  column.Expand = false;
                  column.SortIndicator = true;
                  column.SortColumnId = 2;
                  
                  tracksView.AppendColumn (column);
                  
                  cell = new EditableCellRenderer ();
                  cell.Edited += OnEdit;
                  cell.Column = 3;

                  column = new Gtk.TreeViewColumn (Catalog.GetString ("Genre"),
                                           cell, "text", 3);
                  column.Resizable = true;
                  column.Expand = false;
                  column.SortIndicator = true;
                  column.SortColumnId = 3;
                  
                  tracksView.AppendColumn (column);
                  
                  tracksView.HeadersVisible = true;
                  tracksView.HeadersClickable = true;

                  column = new Gtk.TreeViewColumn ("Icon", new Gtk.CellRendererPixbuf (), "pixbuf", 0);
                  plistView.AppendColumn (column);

                  column = new Gtk.TreeViewColumn ("Name", new Gtk.CellRendererText (), "text", 1);
                  plistView.AppendColumn (column);
                  
                  column = new Gtk.TreeViewColumn ("Counts", new Gtk.CellRendererText (), "text", 2);
                  plistView.AppendColumn (column);

                  plistView.HeadersVisible = false;
            }

            [GLib.ConnectBefore]
            private void OnTracksButtonPress (object o, ButtonPressEventArgs args)
            {
                  switch (args.Event.Button)
                  {
                  case 3:
                        if (this.device != null) {
                              TracksPopupMenu (args.Event);
                              args.RetVal = true;
                        }
                        break;
                  }
            }

            private void TracksPopupMenu (Gdk.EventButton ev)
            {
                  if (tracksView.Selection.CountSelectedRows () != 0) {
                        
                        Gtk.Menu playlistMenu = new Gtk.Menu ();
                        Gtk.MenuItem addToPlaylistItem = (MenuItem) uim.GetWidget ("/ui/TracksPopup/AddToPlaylist");
                        
                        menuTable.Clear ();
                  
                        foreach (Playlist playlist in db.Playlists) {
                              ImageMenuItem item = new ImageMenuItem (playlist.Name);
                              item.Image = new Gtk.Image (Gnome.IconTheme.Default.LoadIcon ("stock_playlist", 16, 0));
                              item.Activated += OnAddToPlaylist;
                              menuTable[item] = playlist;
                              playlistMenu.Append (item);
                        }
                  
                        addToPlaylistItem.Submenu = playlistMenu;
                        
                        menu.ShowAll ();
                        playlistMenu.ShowAll ();
                  
                        menu.Popup (null, null, null, (ev != null) ? ev.Button : 0,
                                  (ev != null) ? ev.Time : 0);
                  }
            }

            private void OnTracksPopupMenu (object o, PopupMenuArgs args)
            {
                  TracksPopupMenu (null);
            }

            [GLib.ConnectBefore]
            private void OnPlaylistButtonPress (object o, ButtonPressEventArgs args)
            {
                  switch (args.Event.Button)
                  {
                  case 3:
                        if (this.device != null) {
                              PlaylistPopupMenu (args.Event);
                        }
                        break;
                  }             
            }
            
            private void OnEdit (object o, EditedArgs args)
            {
                  TreeIter iter = TreeIter.Zero;
                  ListStore store = tracks.GetModel ();
                  EditableCellRenderer cell = (EditableCellRenderer) o;
                  bool modified = false;
                  

                  if (!store.GetIter (out iter, new TreePath (args.Path)))
                        return;
                  
                  long trackId = (long) store.GetValue (iter, 4);
                  Track track = tracks.GetTrackbyId (this.db, trackId);

                  switch (cell.Column)
                  {
                        case 0:
                              if (args.NewText != track.Artist)
                              {
                                    track.Artist = args.NewText;
                                    modified = true;
                              }
                              break;
                        case 1:
                              if (args.NewText != track.Album)
                              {
                                    track.Album = args.NewText;
                                    modified = true;
                              }
                              break;
                        case 2:
                              if (args.NewText != track.Title)
                              {
                                    track.Title = args.NewText;
                                    modified = true;
                              }
                              break;
                        case 3:
                              if (args.NewText != track.Genre)
                              {
                                    track.Genre = args.NewText;
                                    modified = true;
                              }
                              break;
                        default:
                              break;
                  }
                  
                  if (modified)
                  {
                        tracks.UpdateStore (track, iter);
                        
                        Thread thr = new Thread (new ThreadStart (SaveDB));
                        thr.Start ();
                  }
            }

            private void PlaylistPopupMenu (Gdk.EventButton ev)
            {
                  TreeModel model;
                  TreeIter iter;
                  
                  Gtk.Menu menupl;

                  if (plistView.Selection.GetSelected (out model, out iter)) {
                        
                        string plistName = (string) model.GetValue (iter, 1);
                        Playlist plist = null;
                        
                        if ((plist = this.db.LookupPlaylist (plistName)) != null) {
                              menupl = (Gtk.Menu) uim.GetWidget ("/ui/PlaylistPopup");
                              menupl.ShowAll ();

                              menupl.Popup (null, null, null, (ev != null) ? ev.Button : 0,
                                          (ev != null) ? ev.Time : 0);
                        } else {
                              if (plistName == device.Name) {
                                    menupl = (Gtk.Menu) uim.GetWidget ("/ui/DevicePopup");
                                    menupl.ShowAll ();

                                    menupl.Popup (null, null, null, (ev != null) ? ev.Button : 0,
                                                (ev != null) ? ev.Time : 0);
                              }
                        }     
                  }
            }

            private void OnPlaylistPopupMenu (object o, PopupMenuArgs args)
            {
                  PlaylistPopupMenu (null);
            }

            private void OnDeletePlaylist (object o, EventArgs args)
            {
                  TreeModel model;
                  TreeIter iter;
                  
                  if (plistView.Selection.GetSelected (out model, out iter)) 
                  {
                        string plistName = (string) model.GetValue (iter, 1);
                        
                        Playlist plist = this.db.LookupPlaylist (plistName);
                        this.db.RemovePlaylist (plist);

                        RefreshPlaylistView ();
                        playlists.RefreshDevice (this.device);
                        playlists.RemovePlaylist (iter);
                  }

                  Thread thr = new Thread (new ThreadStart (SaveDB));
                  thr.Start ();
            }


            private void OnNewPlaylist (object o, EventArgs args)
            {
                  Gtk.HBox hbox = new Gtk.HBox ();
                  Gtk.Label name = new Gtk.Label (Catalog.GetString ("Name: "));
                  Gtk.Entry entry = new Gtk.Entry ();
                  
                  Gtk.Dialog dialog = new Gtk.Dialog (Catalog.GetString ("New Playlist"), this.hipoWindow,
                                              DialogFlags.DestroyWithParent,
                                              Gtk.Stock.Cancel, ResponseType.Cancel,
                                              Gtk.Stock.Ok, ResponseType.Accept);

                  hbox.BorderWidth = 5;
                  hbox.Add (name);
                  hbox.Add (entry);
                  hbox.ShowAll ();
                  dialog.VBox.Add (hbox);

                  ResponseType res = (ResponseType) dialog.Run ();
                  dialog.Destroy ();
                  
                  if (res == ResponseType.Accept)
                  {
                        Playlist plist = null;
                        if ((plist = this.db.CreatePlaylist (entry.Text)) != null)
                        {
                              Thread thr = new Thread (new ThreadStart (SaveDB));
                              thr.Start ();

                              playlists.AddListToStore (plist);
                        }
                  }
            }

            private void SaveDB ()
            {
                  lock (this.db) {
                        this.db.Save ();
                  }

                  notify.WakeupMain ();
            }
            
            private void OnDeviceChanged (object o, EventArgs args)
            {
                  this.device = combo.ActiveDevice;
                  SetDevice (this.device);
            }
            
            private void SetDevice (IPod.Device device)
            {
                  if (device == null)
                  {
                        SetGreyedObjects (false);
                        return;
                  }
                  
                  SetGreyedObjects (true);
                  
                  this.device = device;

                  Thread thr = new Thread (new ThreadStart (PopulateView));
                  thr.Start ();
                  notify = new ThreadNotify (new ReadyEvent (RefreshPlaylistView));
            }
            
            private void SetDevice ()
            {
                  try {
                        SetDevice (combo.ActiveDevice);
                  } catch (Exception e) {
                        Console.Error.WriteLine (e);
                  }
            }

            private void SetGreyedObjects (bool greyed)
            {
                  if (!greyed) {
                        ipodCapacityBar.Text = Catalog.GetString ("No iPod Found");
                        ipodCapacityBar.Fraction = 0.0;
                        playlists.Clear ();
                        tracks.Clear ();
                  }

                  group["AddFile"].Sensitive = greyed;
                  group["AddFolder"].Sensitive = greyed;
                  group["Remove"].Sensitive = greyed;
                  group["Eject"].Sensitive = greyed;
                  group["NewPlaylist"].Sensitive = greyed;
                  group["OnDeviceProperties"].Sensitive = greyed;
            }
            
            private void PopulateView ()
            {
                  this.db = this.device.TrackDatabase;
                  pdialog.TrackDatabase = this.db;
                  
                  playlists.AddDeviceToStore (this.device);
                  
                  foreach (Playlist plist in this.db.Playlists)
                  {
                        playlists.AddListToStore (plist);
                  }
                  
                  Thread thrb = new Thread (new ThreadStart (PopulateTracksView));
                  thrb.Start ();
            }

            private void PopulateTracksView ()
            {
                  foreach (Track track in this.db.Tracks)
                  {
                        tracks.AddTrackToStore (track);
                  }

                  notify.WakeupMain ();
            }

            private void OnAddFolder (System.Object o, EventArgs args)
            {
                  Gtk.FileChooserDialog fileChooser = new Gtk.FileChooserDialog (Catalog.GetString ("Select a folder to add"),
                                                                   hipoWindow,
                                                                   FileChooserAction.SelectFolder,
                                                                   Gtk.Stock.Cancel, ResponseType.Cancel,
                                                                   Gtk.Stock.Add, ResponseType.Accept);
                  
                  fileChooser.LocalOnly = true;
                  
                  ResponseType res = (ResponseType) fileChooser.Run ();
                  uris = fileChooser.Uris;
                  fileChooser.Destroy ();
                  
                  if (res == ResponseType.Accept)
                  {
                        Thread thr = new Thread (new ThreadStart (AddFolder));
                        thr.Start ();
                  }
            }

            private void AddFolder ()
            {
                  Gtk.Application.Invoke (delegate {
                              statusbar1.Push (1, Catalog.GetString ("Adding Track/s"));
                        });
                  
                  tracks.AddFolder (db, uris);

                  Gtk.Application.Invoke (delegate {
                              statusbar1.Push (1, "");
                        });

                  playlists.RefreshDevice (this.device);
                  SaveDB ();
                  notify.WakeupMain ();
            }
            
            private void OnAddActivated (System.Object o, EventArgs args)
            {
                  FileFilter filter = new Gtk.FileFilter ();
                  
                  Gtk.FileChooserDialog fileChooser  = new Gtk.FileChooserDialog (Catalog.GetString ("Select the file to add"),
                                                                  hipoWindow,
                                                                  FileChooserAction.Open,
                                                                  Gtk.Stock.Cancel, ResponseType.Cancel,
                                                                  Gtk.Stock.Add, ResponseType.Accept);
                  
                  fileChooser.SelectMultiple = true;
                  fileChooser.LocalOnly = true;

                  filter.Name = "audio files";
                  filter.AddMimeType ("audio/mpeg");
                  filter.AddMimeType ("audio/x-m4a");
                  fileChooser.AddFilter (filter);
                  
                  ResponseType res = (ResponseType) fileChooser.Run ();
                  uris = fileChooser.Uris;
                  
                  fileChooser.Destroy ();
                  
                  if (res == ResponseType.Accept)
                  {
                        Thread thr = new Thread (new ThreadStart (AddTrack));
                        thr.Start ();
                  }
            }

            private void AddTrack ()
            {
                  Gtk.Application.Invoke (delegate {
                              statusbar1.Push (1, Catalog.GetString ("Adding Track/s"));
                        });
                  
                  foreach (string urin in uris)
                  {
                        Uri uri = new Uri (urin);
                        tracks.AddTrack (this.db, uri.LocalPath);
                  }

                  Thread thr = new Thread (new ThreadStart (SaveDB));
                  thr.Start ();

                  Gtk.Application.Invoke (delegate {
                              statusbar1.Push (1, "");
                        });

                  playlists.RefreshDevice (this.device);
                  notify.WakeupMain ();
            }

            private void OnAddToPlaylist (System.Object o, EventArgs args)
            {
                  Playlist playlist = (Playlist) menuTable[o];

                  if (playlist == null)
                        return;

                  TreeIter iter;
                  TreeModel model;

                  Array treePaths = tracksView.Selection.GetSelectedRows (out model);

                  foreach (TreePath tPath in treePaths)
                  {
                        if (model.GetIter (out iter, tPath))
                        {
                              long trackId = (long) model.GetValue (iter, 4);
                        
                              foreach (Track track in this.db.Tracks)
                              {
                                    if (track.Id == trackId)
                                          playlist.AddTrack (track);
                              }
                        }
                  }

                  Thread thr = new Thread (new ThreadStart (SaveDB));
                  thr.Start ();

                  playlists.UpdateTrackNumber (this.db, playlist);
            }
            
                  private void OnRemoveActivated (System.Object o, EventArgs args)
            {
                  TreeIter iter;
                  TreeModel model;
                  ListStore store;
                  Gtk.HBox hbox;
                  Gtk.ScrolledWindow scroll;
                  TreeView view;
                  Queue iterQueue;

                  iterQueue = new Queue ();
                  hbox = new Gtk.HBox ();
                  hbox.BorderWidth = 5;

                  scroll = new Gtk.ScrolledWindow ();
                  scroll.ShadowType = ShadowType.In;
                  scroll.VscrollbarPolicy = PolicyType.Automatic;
                  scroll.HscrollbarPolicy = PolicyType.Automatic;

                  store = new Gtk.ListStore (typeof (string));
                  view = new Gtk.TreeView ();
                  view.AppendColumn ("Songs", new Gtk.CellRendererText (), "text", 0);

                  Array treePaths = tracksView.Selection.GetSelectedRows (out model);
                  
                  MessageDialog dialog = new MessageDialog (hipoWindow,
                                                  DialogFlags.DestroyWithParent,
                                                  MessageType.Question,
                                                  ButtonsType.OkCancel,
                                                  String.Format ("<b>{0}</b>",
                                                             Catalog.GetString ("Do you really want to remove the song/s?"))
                        );
                  
                  dialog.Resizable = true;
                  
                  foreach (TreePath tPath in treePaths)
                  {
                        if (model.GetIter (out iter, tPath)) {
                              
                              string Artist = (string) model.GetValue (iter, 0);
                              string Album = (string) model.GetValue (iter, 1);
                              string Title = (string) model.GetValue (iter, 2);
                              
                              store.AppendValues (String.Format ("{0} - {1} - {2}", Artist, Album, Title));
                        }
                  }

                  view.Model = store;

                  scroll.Add (view);
                  hbox.Add (scroll);
                  hbox.ShowAll ();
                  dialog.VBox.Add (hbox);
                  
                  ResponseType response = (ResponseType) dialog.Run ();
                  dialog.Destroy ();
                  
                  if (response == ResponseType.Ok)
                  {
                        foreach (TreePath tPath in treePaths)
                        {
                              if (model.GetIter (out iter, tPath)) {
                                    iterQueue.Enqueue (iter);
                                    
                                    long trackId = (long) model.GetValue (iter, 4);
                                    tracks.RemoveTracks (this.db, trackId);
                              }
                                }

                        while (iterQueue.Count > 0)
                        {
                              TreeIter iterator = (TreeIter) iterQueue.Dequeue ();
                              tracks.RemoveTracks (iterator);
                        }

                        lock (this.db)
                              this.db.Save ();

                        RefreshPlaylistView ();
                        playlists.RefreshDevice (this.device);

                  }
            }

            [Widget] private Gtk.Dialog trackProperties;
            [Widget] private Gtk.Entry artistEntry;
            [Widget] private Gtk.Entry albumEntry;
            [Widget] private Gtk.Entry titleEntry;
            [Widget] private Gtk.Entry genreEntry;
            [Widget] private Gtk.SpinButton numberSpin;
            [Widget] private Gtk.Image artwork;
            [Widget] private Gtk.Button openArtwork;
            
            private void OnTrackProperties (object o, EventArgs args)
            {
                  if (tracksView.Selection.CountSelectedRows() > 1)
                        return;

                  Glade.XML xml = new Glade.XML (null, "hipo.glade", "trackProperties", null);
                  xml.Autoconnect (this);

                  bool modified = false;
                  Track track = null;
                  TreeIter iter;
                  TreeModel model;
                  Gdk.Pixbuf newCover = null;
                  
                  Array treePaths = tracksView.Selection.GetSelectedRows (out model);

                  if (model.GetIter (out iter, (Gtk.TreePath) treePaths.GetValue(0)))
                  {
                        long trackId = (long) model.GetValue (iter, 4);
                        
                        track = tracks.GetTrackbyId (this.db, trackId);
                        
                        trackProperties.Title = String.Format (Catalog.GetString ("{0} {1} Properties"),
                                                       track.Artist, track.Title);
                        artistEntry.Text = track.Artist;
                        albumEntry.Text = track.Album;
                        titleEntry.Text = track.Title;
                        genreEntry.Text = track.Genre;
                        numberSpin.Value = track.TrackNumber;
                        
                        foreach (ArtworkFormat format in this.device.LookupArtworkFormats (ArtworkUsage.Cover)) {

                              if (format != null) {
                                    if (track.HasCoverArt (format)) 
                                          artwork.FromPixbuf = ArtworkHelpers.ToPixbuf (format, track.GetCoverArt (format));
                              }
                        }
                  }

                  openArtwork.Clicked += delegate {

                        FileFilter filter = new Gtk.FileFilter ();
                        
                        Gtk.FileChooserDialog fileChooser  = new Gtk.FileChooserDialog (Catalog.GetString ("Select an image"),
                                                                        trackProperties,
                                                                        FileChooserAction.Open,
                                                                        Gtk.Stock.Cancel, ResponseType.Cancel,
                                                                        Gtk.Stock.Add, ResponseType.Accept);
                        
                        fileChooser.LocalOnly = true;
                        filter.AddMimeType ("image/png");
                        filter.AddMimeType ("image/jpeg");
                        fileChooser.AddFilter (filter);
                        fileChooser.UpdatePreview += OnUpdatePreview;
                        fileChooser.PreviewWidget = coverpreview;
                        
                        ResponseType res = (ResponseType) fileChooser.Run ();
                        string uri = fileChooser.Uri;
                        
                        if (res == ResponseType.Accept)
                        {
                              Uri ur = new Uri (uri);
                              newCover = new Gdk.Pixbuf (ur.LocalPath);

                              artwork.FromPixbuf = newCover.ScaleSimple(200, 200, Gdk.InterpType.Bilinear);
                        }

                        fileChooser.Destroy ();
                  };

                  ResponseType response = (ResponseType) trackProperties.Run ();
                        
                  if (response == ResponseType.Ok)
                  {                 
                        if (artistEntry.Text != track.Artist) {
                              modified = true;
                              track.Artist = artistEntry.Text;
                        }

                        if (albumEntry.Text != track.Album) {
                              modified = true;
                              track.Album = albumEntry.Text;
                        }

                        if (titleEntry.Text != track.Title) {
                              modified = true;
                              track.Title = titleEntry.Text;
                        }

                        if (genreEntry.Text != track.Genre) {
                              modified = true;
                              track.Genre = genreEntry.Text;
                        }

                        if (numberSpin.Value != track.TrackNumber) {
                              modified = true;
                              track.TrackNumber = (int) numberSpin.Value;
                        }

                        if (newCover != null) {
                              
                              foreach (ArtworkFormat format in this.device.LookupArtworkFormats (ArtworkUsage.Cover)) {

                                    // maybe is a good idea to set all the album of the current selected track with the new cover.
                                    // we can set this on a gconf key.
                                    
                                    track.SetCoverArt (format, ArtworkHelpers.ToBytes (format, newCover));
                              }
                              
                              modified = true;
                        }
                  }

                  if (modified) {
                        tracks.UpdateStore (track, iter);
                        
                        Thread thr = new Thread (new ThreadStart (SaveDB));
                        thr.Start ();
                  }

                  trackProperties.Destroy ();
            }

            [Widget] Gtk.Dialog deviceProperties;
            [Widget] Gtk.Label serialLabel;
            [Widget] Gtk.Label modelLabel;
            [Widget] Gtk.Label generationLabel;
            [Widget] Gtk.Label capacityLabel;
            [Widget] Gtk.Label mountLabel;
            [Widget] Gtk.Label spaceLabel;
            [Widget] Gtk.Label firmwareLabel;
            [Widget] Gtk.Entry nameEntry;
            
            private void OnDeviceProperties (object o, EventArgs args)
            {
                  Glade.XML xml = new Glade.XML (null, "hipo.glade", "deviceProperties", null);
                  xml.Autoconnect (this);

                  deviceProperties.Title = String.Format (Catalog.GetString ("{0} Properties"), this.device.Name);
                  nameEntry.Text = this.device.Name;

                  serialLabel.Text = this.device.SerialNumber;
                  modelLabel.Text = this.device.ModelString;
                  generationLabel.Text = String.Format ("{0}", this.device.Generation);
                  capacityLabel.Text = FormatString ((double) this.device.VolumeSize);
                  mountLabel.Text = this.device.MountPoint;
                  spaceLabel.Text = String.Format ("{0}%", (int) ((double) device.VolumeUsed / (double) device.VolumeSize * 100));
                  firmwareLabel.Text = this.device.FirmwareVersion;


                  ResponseType res = (ResponseType) deviceProperties.Run ();
                        
                  if (res == ResponseType.Ok)
                  {
                        if (this.device.Name != nameEntry.Text.Trim ())
                        {
                              this.device.Name = nameEntry.Text;
                              
                              SaveDB ();
                              playlists.RefreshDevice (this.device);
                        }
                  }

                  deviceProperties.Destroy ();
            }

            private void OnUpdatePreview (object o, EventArgs args)
            {
                  try {
                        if (((FileChooser)o).PreviewFilename != null) {
                              Gdk.Pixbuf cover = new Gdk.Pixbuf (((FileChooser)o).PreviewFilename);
                              
                              coverpreview.Pixbuf = cover.ScaleSimple(150, 150, Gdk.InterpType.Bilinear);
                              
                              coverpreview.Show ();
                        }
                  } catch (Exception e) {
                        coverpreview.Hide ();
                        Console.WriteLine (e.Message);
                  }
            }
            
            private void OnPlaylistSelectionChanged (object o, EventArgs args)
            {
                  TreeModel model;
                  TreeIter iter;
                  Playlist plist;
                  
                  if (((TreeSelection)o).GetSelected (out model, out iter)) {
                        string plistName = (string) model.GetValue (iter, 1);

                        if ((plist = this.db.LookupPlaylist (plistName)) == null) {
                              menu = (Gtk.Menu) uim.GetWidget ("/ui/TracksPopup");
                              tracksView.Model = tracks.GetModel ();
                        } else {
                              menu = (Gtk.Menu) uim.GetWidget ("/ui/TracksPlaylistPopup");
                              tracksView.Model = playlists.GetModel (plist);
                        }
                  }
            }

            private void OnRemoveFromPlaylist (object o, EventArgs args)
            {
                  TreeModel model;
                  TreeModel modelpl;
                  TreeIter iterpl;
                  Playlist plist = null;

                  Queue iterQueue = new Queue ();

                  Array treePaths = tracksView.Selection.GetSelectedRows (out model);
                  
                  if (plistView.Selection.GetSelected (out modelpl, out iterpl))
                  {
                        string playlistName = (string) plistView.Model.GetValue (iterpl, 1);
                        plist = this.db.LookupPlaylist (playlistName);
                  }

                  foreach (TreePath tPath in treePaths)
                  {
                        TreeIter iter;

                        if (model.GetIter (out iter, tPath))
                        {
                              long trackId = (long) model.GetValue (iter, 4);
                              iterQueue.Enqueue (iter);

                              Track t = tracks.GetTrackbyId (this.db, trackId);

                              if (t != null)
                                    plist.RemoveTrack (t);
                        }
                  }

                  while (iterQueue.Count > 0)
                  {
                        TreeIter iter = (TreeIter) iterQueue.Dequeue ();
                        playlists.RemoveFromPlaylist (iter);
                  }

                  SaveDB ();

                  playlists.UpdateTrackNumber (this.db, plist);
            }

            private void OnDeleteEvent (object o, DeleteEventArgs args)
            {
                  OnQuitActivated (o, null);
            }

            private void OnQuitActivated (object o, EventArgs args)
            {
                  Application.Quit ();
            }

            private void OnEjectActivated (object o, EventArgs args)
            {
                  try {
                        device.Eject ();
                        Application.Quit ();
                  } catch (Exception e) {
                        MessageDialog error = new MessageDialog (hipoWindow,
                                                       DialogFlags.DestroyWithParent,
                                                       MessageType.Error,
                                                       ButtonsType.Close,
                                                       Catalog.GetString ("There was an error ejecting the iPod:")
                              );
                        
                        error.SecondaryText = e.Message;
                        
                        error.Run ();
                        error.Destroy ();
                  }
            }

            private void OnPreferences (object o, EventArgs args)
            {
                  // FIXME
            }

            private void OnHelp (object o, EventArgs args)
            {
                  // FIXME
            }            

            private void OnAboutActivated (object o, EventArgs args)
            {
                  Gtk.AboutDialog aboutDialog = new Gtk.AboutDialog ();
                  string[] authors = { "Pedro Villavicencio Garrido <pvillavi@gnome.org>",
                                   "Felipe Barros S. <felipeb@gnome.cl>" };
                  string[] artists = { "Carlos Candia Flores <cerealk@vtr.net>",
                                   "Gabriel Bustos Farret  <lemut@lemut.com>" };
                  
                  aboutDialog.Authors = authors;
                  aboutDialog.Copyright = "Copyright © 2006-2007 Pedro Villavicencio Garrido";
                  aboutDialog.Name = Defines.PACKAGE;
                  aboutDialog.Comments = Catalog.GetString ("iPod Management Tool");
                  aboutDialog.Version = Defines.VERSION;
                  aboutDialog.Artists = artists;
                  aboutDialog.Logo = new Gdk.Pixbuf (null, "hipo-logo.png");

                  aboutDialog.TranslatorCredits = Catalog.GetString ("translator-credits");

                  aboutDialog.Website = "http://www.gnome.org/projects/hipo/";
                  
                  aboutDialog.Run ();
                  aboutDialog.Destroy ();
            }

            private void RefreshPlaylistView ()
            {
                  ScanCapacity ();
            }                       

            private void ScanCapacity ()
            {
                  string capacity = null;
                  string used = null;
                  double percent;

                  capacity = FormatString ((double) this.device.VolumeSize);
                  used = FormatString ((double) this.device.VolumeUsed);
                  percent = (((double) this.device.VolumeUsed / 1073741824) * 100) / System.Convert.ToDouble (capacity);

                  ipodCapacityBar.Text = String.Format (Catalog.GetString ("Used {0} of {1}"), used, capacity);
                  ipodCapacityBar.Fraction = (percent * 1.0) / 100;
            }

            private string FormatString (double value)
            {
                  if (value < 1073741824) {
                        return String.Format ("{0:0.0} MB", (value / 1048576));
                  } else {
                        return String.Format ("{0:0.0} GB", (value / 1073741824));
                  }
            }

            public static Gdk.Pixbuf GetDeviceIcon (IPod.Device device)
            {
                  string deviceId = null;
                  
                  switch (device.Model) {

                  case DeviceModel.Color:
                        deviceId = "multimedia-player-ipod-standard-color";
                        break;
                  case DeviceModel.ColorU2:
                        deviceId = "multimedia-player-ipod-U2-color";
                        break;
                  case DeviceModel.RegularU2:
                        deviceId = "multimedia-player-ipod-U2-monochrome";
                        break;
                  case DeviceModel.Mini:
                        deviceId = "multimedia-player-ipod-mini-silver";
                        break;
                  case DeviceModel.MiniBlue:
                        deviceId = "multimedia-player-ipod-mini-blue";
                        break;
                  case DeviceModel.MiniPink:
                        deviceId = "multimedia-player-ipod-mini-pink";
                        break;
                  case DeviceModel.MiniGreen:
                        deviceId = "multimedia-player-ipod-mini-green";
                        break;
                  case DeviceModel.MiniGold:
                        deviceId = "multimedia-player-ipod-mini-gold";
                        break;
                  case DeviceModel.Shuffle:
                        deviceId = "multimedia-player-ipod-shuffle";
                        break;
                  case DeviceModel.NanoWhite:
                        deviceId = "multimedia-player-ipod-nano-white";
                        break;
                  case DeviceModel.NanoBlack:
                        deviceId = "multimedia-player-ipod-nano-black";
                        break;
                  case DeviceModel.VideoWhite:
                        deviceId = "multimedia-player-ipod-video-white";
                        break;
                  case DeviceModel.VideoBlack:
                        deviceId = "multimedia-player-ipod-video-black";
                        break;
                  default:
                        deviceId = "multimedia-player-ipod-standard-monochrome";
                        break;
                  }

                  Gdk.Pixbuf deviceIcon = Gtk.IconTheme.Default.LoadIcon (deviceId, 16, 0);
                  
                  return (deviceIcon);
            }

            private void OnTracksDragDataGet (object o, DragDataGetArgs args)
                {
                        TreeIter iter;
                        TreeModel model;
                        Atom[] targets = args.Context.Targets; 
                        byte[] bytes;

                        if (tracksView.Selection.GetSelected (out model, out iter))
                        {
                        long trackId = (long) model.GetValue (iter, 4);

                        Track track = tracks.GetTrackbyId (this.db, trackId);

                        if (track == null)
                              return;
                                        
                        bytes = System.Text.Encoding.UTF8.GetBytes (trackId.ToString ());
                        args.SelectionData.Set (targets[0], 8, bytes);
                        }
                }

            private void OnPlistDragDataReceived (object o, DragDataReceivedArgs args)
                {
                        TreePath treepath;
                        TreeViewDropPosition position;
                        TreeModel model = plistView.Model;
                        TreeIter iter;
                        Playlist plist;

                        plistView.GetDestRowAtPos (args.X, args.Y, out treepath, out position);
                        model.GetIter (out iter, treepath);

                        string plistName = (string) model.GetValue (iter, 1);

                        if ((plist = this.db.LookupPlaylist (plistName)) != null) {
                        string data = System.Text.Encoding.UTF8.GetString (args.SelectionData.Data);

                        Track track = tracks.GetTrackbyId (this.db, long.Parse (data));

                        if (track == null)
                              return;
                        
                        plist.AddTrack (track);

                        Thread thr = new Thread (new ThreadStart (SaveDB));
                        thr.Start ();

                        playlists.UpdateTrackNumber (this.db, plist);
                        
                        Gtk.Drag.Finish (args.Context, true, false, args.Time);
                        }
                }
      }
}


Generated by  Doxygen 1.6.0   Back to index