hipo r143 - in branches/bgarret: . src
- From: bgarret svn gnome org
- To: svn-commits-list gnome org
- Subject: hipo r143 - in branches/bgarret: . src
- Date: Thu, 31 Jan 2008 21:38:52 +0000 (GMT)
Author: bgarret
Date: Thu Jan 31 21:38:51 2008
New Revision: 143
URL: http://svn.gnome.org/viewvc/hipo?rev=143&view=rev
Log:
2008-01-31 Benoit Garret <benoit garret_gnome gadz org>
* configure.ac:
* src/CapacityBar.cs:
* src/DeviceSource.cs:
* src/EditableCellRenderer.cs:
* src/HipoMain.cs:
* src/HipoMainWindow.cs:
* src/Makefile.am:
* src/PlaylistSource.cs:
* src/PlaylistView.cs:
* src/Saviour.cs:
* src/Source.cs:
* src/SourceList.cs:
* src/Tools.cs:
* src/TracksContainer.cs:
* src/TracksSource.cs:
* src/TracksView.cs:
* src/devicepopup.xml:
* src/errordialog.glade:
* src/hipo.glade:
* src/hipo.xml:
* src/menubar.xml:
* src/playlistpopup.xml:
* src/trackpopup.xml:
Big Bad Redesign
Added:
branches/bgarret/src/CapacityBar.cs
branches/bgarret/src/DeviceSource.cs
branches/bgarret/src/EditableCellRenderer.cs
branches/bgarret/src/PlaylistSource.cs
branches/bgarret/src/Saviour.cs
branches/bgarret/src/Source.cs
branches/bgarret/src/SourceList.cs
branches/bgarret/src/Tools.cs
branches/bgarret/src/TracksContainer.cs
branches/bgarret/src/TracksSource.cs
branches/bgarret/src/devicepopup.xml
branches/bgarret/src/menubar.xml
branches/bgarret/src/playlistpopup.xml
branches/bgarret/src/trackpopup.xml
Removed:
branches/bgarret/src/PlaylistView.cs
branches/bgarret/src/TracksView.cs
branches/bgarret/src/hipo.xml
Modified:
branches/bgarret/ChangeLog
branches/bgarret/configure.ac
branches/bgarret/src/Defines.cs.in
branches/bgarret/src/HipoMain.cs
branches/bgarret/src/HipoMainWindow.cs
branches/bgarret/src/Makefile.am
branches/bgarret/src/errordialog.glade
branches/bgarret/src/hipo.glade
Modified: branches/bgarret/configure.ac
==============================================================================
--- branches/bgarret/configure.ac (original)
+++ branches/bgarret/configure.ac Thu Jan 31 21:38:51 2008
@@ -15,13 +15,15 @@
GTK_SHARP_REQUIRED=2.10
IPOD_SHARP_REQUIRED=0.6.3
+NDESK_DBUS_GLIB_REQUIRED=0.3
PKG_CHECK_MODULES(HIPO,
gtk-sharp-2.0 >= $GTK_SHARP_REQUIRED \
gnome-sharp-2.0 >= $GTK_SHARP_REQUIRED \
glade-sharp-2.0 >= $GTK_SHARP_REQUIRED \
ipod-sharp >= $IPOD_SHARP_REQUIRED \
- ipod-sharp-ui >= $IPOD_SHARP_REQUIRED)
+ ipod-sharp-ui >= $IPOD_SHARP_REQUIRED \
+ ndesk-dbus-glib-1.0 >= $NDESK_DBUS_GLIB_REQUIRED)
AC_SUBST(HIPO_LIBS)
Added: branches/bgarret/src/CapacityBar.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/CapacityBar.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,89 @@
+// CapacityBar.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using IPod;
+using Gtk;
+using Mono.Unix;
+
+namespace Hipo
+{
+ public class CapacityBar : ProgressBar
+ {
+ private Device device = null;
+
+ public Device Device
+ {
+ set {
+ if (device != null)
+ {
+ device.Changed -= OnChanged;
+ device.TrackDatabase.SaveEnded -= OnChanged;
+ }
+
+ device = value;
+
+ if (device != null)
+ {
+ device.Changed += OnChanged;
+ device.TrackDatabase.SaveEnded += OnChanged;
+ Refresh ();
+ }
+ else
+ {
+ Clear ();
+ }
+ }
+ }
+
+ private void Refresh ()
+ {
+ string capacity = null;
+ string used = null;
+ double percent;
+
+ capacity = Tools.FormatString ((double) device.VolumeInfo.Size);
+ used = Tools.FormatString ((double) device.VolumeInfo.SpaceUsed);
+
+ percent = ((double) device.VolumeInfo.SpaceUsed * 100) / ((double) device.VolumeInfo.Size);
+
+ Gtk.Application.Invoke (delegate {
+
+ /* space used in the device, example: used 15G of 60G */
+ this.Text = String.Format (Catalog.GetString ("Using {0} of {1}"), used, capacity);
+ this.Fraction = percent / 100;
+ });
+ }
+
+ private void Clear ()
+ {
+ Gtk.Application.Invoke (delegate {
+
+ this.Text = Catalog.GetString ("No iPod Found");
+ this.Fraction = 0.0;
+ });
+ }
+
+ private void OnChanged (object o, EventArgs args)
+ {
+ Refresh ();
+ }
+ }
+}
Modified: branches/bgarret/src/Defines.cs.in
==============================================================================
--- branches/bgarret/src/Defines.cs.in (original)
+++ branches/bgarret/src/Defines.cs.in Thu Jan 31 21:38:51 2008
@@ -4,8 +4,8 @@
{
public const string PACKAGE = "@PACKAGE@";
public const string VERSION = "@VERSION@";
- public const string LOCALE_DIR = "@prefix@/share/locale";
+ public const string LOCALE_DIR = "@prefix@/share/locale";
public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@";
- public const string GNOME_HELP_DIR = "@prefix@/share/gnome/help/hipo";
+ public const string GNOME_HELP_DIR = "@prefix@/share/gnome/help/hipo";
}
}
Added: branches/bgarret/src/DeviceSource.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/DeviceSource.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,145 @@
+// DeviceSource.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using System.Collections.ObjectModel;
+using Glade;
+using Gtk;
+using IPod;
+using Mono.Unix;
+
+namespace Hipo
+{
+ public class DeviceSource : SourceBase
+ {
+ [Widget] Window deviceProperties;
+ [Widget] Viewport deviceViewport;
+ [Widget] Label serialLabel;
+ [Widget] Label modelLabel;
+ [Widget] Label generationLabel;
+ [Widget] Label capacityLabel;
+ [Widget] Label mountLabel;
+ [Widget] Label spaceLabel;
+ [Widget] Label firmwareLabel;
+
+ private Device device;
+
+ public DeviceSource (Device device)
+ {
+ this.device = device;
+
+ this.Type = SourceType.Device;
+ this.Parent = SourceType.None;
+ this.Icon = IconTheme.Default.LoadIcon (device.ModelInfo.IconName, 16, 0);
+
+ Glade.XML xml = new Glade.XML (null, "hipo.glade", "deviceProperties", null);;
+ xml.Autoconnect (this);
+
+ serialLabel.Text = this.device.ProductionInfo.SerialNumber;
+ modelLabel.Text = this.device.ModelInfo.DeviceClass;
+ generationLabel.Text = String.Format ("{0}", this.device.ModelInfo.Generation);
+ capacityLabel.Text = Tools.FormatString ((double) this.device.VolumeInfo.Size);
+ mountLabel.Text = this.device.VolumeInfo.MountPoint;
+ spaceLabel.Text = String.Format ("{0}%", (int) ((double) device.VolumeInfo.SpaceUsed / (double) device.VolumeInfo.Size * 100));
+
+ // remove the viewport from the window so we can add it elsewhere
+ deviceProperties.Remove (deviceViewport);
+
+ // source list right click menu
+ ActionEntry[] entries = {
+
+ new ActionEntry ("RenameDevice",
+ Gtk.Stock.Copy,
+ Catalog.GetString ("Rename"),
+ null,
+ Catalog.GetString ("Rename the device"),
+ OnRename)
+ };
+
+ ActionGroup group = new ActionGroup ("DevicePopup");
+ group.Add (entries);
+ firmwareLabel.Text = this.device.FirmwareVersion;
+
+ UIManager.Instance.InsertActionGroup (group, 0);
+ UIManager.Instance.AddUiFromResource ("devicepopup.xml");
+ }
+
+ public override string Name
+ {
+ get {
+ return device.Name;
+ }
+ set {
+ if (device.Name != value)
+ {
+ device.Name = value;
+ Saviour.Instance.Save ();
+ }
+ }
+ }
+
+ public override Widget View
+ {
+ get {
+ return deviceViewport;
+ }
+ }
+
+ public override Menu Menu
+ {
+ get {
+ return (Menu)UIManager.Instance.GetWidget ("/ui/DevicePopup");
+ }
+ }
+
+ public void Eject ()
+ {
+ this.device.Eject ();
+ }
+
+ public ReadOnlyCollection<ArtworkFormat> LookupArtworkFormats (ArtworkUsage usage)
+ {
+ return this.device.LookupArtworkFormats (usage);
+ }
+
+ private void OnRename (object o, EventArgs args)
+ {
+ Dialog dialog = new Dialog (Catalog.GetString ("Rename the device"), null, Gtk.DialogFlags.DestroyWithParent);
+
+ dialog.Modal = true;
+ dialog.AddButton ("Cancel", ResponseType.Close);
+ dialog.AddButton ("OK", ResponseType.Ok);
+
+ Gtk.Entry entry = new Gtk.Entry (this.Name);
+ dialog.VBox.PackStart (entry, false, false, 5);
+ dialog.DefaultResponse = ResponseType.Ok;
+
+ dialog.ShowAll ();
+ ResponseType r = (ResponseType) dialog.Run ();
+
+ if (r == ResponseType.Ok)
+ {
+ this.Name = entry.Text;
+ }
+
+ dialog.Destroy ();
+ }
+ }
+}
Added: branches/bgarret/src/EditableCellRenderer.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/EditableCellRenderer.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,54 @@
+// EditableCellRenderer.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using Gtk;
+
+namespace Hipo
+{
+ public enum Column {
+ Icon,
+ Name,
+ Count,
+ SourceType,
+ Artist,
+ Album,
+ Title,
+ Genre,
+ Id
+ }
+
+ internal class EditableCellRenderer : CellRendererText
+ {
+ private Column column;
+
+ public EditableCellRenderer ()
+ {
+ base.Editable = true;
+ base.Ellipsize = Pango.EllipsizeMode.End;
+ }
+
+ public Column Column
+ {
+ get { return column; }
+ set { column = value; }
+ }
+ }
+}
Modified: branches/bgarret/src/HipoMain.cs
==============================================================================
--- branches/bgarret/src/HipoMain.cs (original)
+++ branches/bgarret/src/HipoMain.cs Thu Jan 31 21:38:51 2008
@@ -3,6 +3,7 @@
using Mono.Unix;
using Gtk;
using Glade;
+using GLib;
namespace Hipo
{
@@ -22,27 +23,61 @@
public void Run (string[] args)
{
- AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
+ AppDomain.CurrentDomain.UnhandledException += AppUnhandledExceptionHandler;
+ GLib.ExceptionManager.UnhandledException += GlibUnhandledExceptionHandler;
- HipoMainWindow hmw = new HipoMainWindow ();
- hmw.CreateWindow (args);
+ new HipoMainWindow (args);
}
- public void UnhandledExceptionHandler (object o, UnhandledExceptionEventArgs args)
+ public void AppUnhandledExceptionHandler (object o, UnhandledExceptionEventArgs args)
{
- Glade.XML gxml = new Glade.XML ("errordialog.glade", "errorDialog");
+ UnhandledExceptionHandler ((Exception)args.ExceptionObject);
+ }
+
+ public void GlibUnhandledExceptionHandler (GLib.UnhandledExceptionArgs args)
+ {
+ UnhandledExceptionHandler ((Exception)args.ExceptionObject);
+ }
+
+ public void UnhandledExceptionHandler (Exception e)
+ {
+ string stack = GetStackTrace (e);
+ string msg = GetMessage (e);
- stackTrace = (TextView)gxml.GetWidget ("stackTrace");
- message = (Label)gxml.GetWidget ("message");
- errorDialog = (Dialog)gxml.GetWidget ("errorDialog");
+ Tools.Log (this, "Uh oh, something went wrong...");
- Exception e = (Exception) args.ExceptionObject;
+ Gtk.Application.Invoke (delegate (object o, EventArgs args) {
+
+ Glade.XML gxml = new Glade.XML ("errordialog.glade", "errorDialog");
+
+ stackTrace = (TextView)gxml.GetWidget ("stackTrace");
+ message = (Label)gxml.GetWidget ("message");
+ errorDialog = (Dialog)gxml.GetWidget ("errorDialog");
+
+ stackTrace.Buffer.Text = stack;
+ message.Text = msg;
+ errorDialog.Run ();
+
+ errorDialog.Destroy ();
+ });
- stackTrace.Buffer.Text = e.StackTrace;
- message.Text = e.Message;
- errorDialog.Run ();
+ Application.RunIteration ();
}
+ public string GetMessage (Exception e)
+ {
+ if (e.InnerException != null)
+ return String.Concat (e.Message, " : ", GetMessage (e.InnerException));
+ else
+ return e.Message;
+ }
+ public string GetStackTrace (Exception e)
+ {
+ if (e.InnerException != null)
+ return String.Concat (GetStackTrace (e.InnerException), "\n::End of inner stack trace::\n", e.StackTrace);
+ else
+ return e.StackTrace;
+ }
}
}
Modified: branches/bgarret/src/HipoMainWindow.cs
==============================================================================
--- branches/bgarret/src/HipoMainWindow.cs (original)
+++ branches/bgarret/src/HipoMainWindow.cs Thu Jan 31 21:38:51 2008
@@ -1,603 +1,243 @@
-/* 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>.
- */
+// HipoMainWindow.cs
+//
+// Copyright (C) 2008 Bneoit Garret
+//
+// 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
+//
+//
using System;
-using System.IO;
-using System.Threading;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
using Gtk;
-using Gdk;
using Glade;
-using Gnome;
-using IPod;
+using NDesk.DBus;
using Mono.Unix;
+using IPod;
namespace Hipo
{
- internal class EditableCellRenderer : CellRendererText
- {
- private int column;
-
- public EditableCellRenderer ()
- {
- base.Editable = true;
- base.Ellipsize = Pango.EllipsizeMode.End;
- }
-
- public int Column
- {
- get { return column; }
- set { column = value; }
- }
- }
-
- public enum SourceType {
- Ipod,
- Playlist,
- SmartPlaylist
- }
-
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 Window hipoWindow;
+ [Widget] private VBox menuBar;
+ [Widget] private ScrolledWindow sourceListScroll;
+ [Widget] private ScrolledWindow sourceScroll;
+ [Widget] private Viewport defaultSourceWidget;
+ [Widget] private HBox searchBox;
+ [Widget] private Entry defaultSearchEntry;
+ [Widget] private VBox sourceListBox;
+ private SourceList sourceList;
+ private DeviceCombo combo;
private Glade.XML gxml;
private Gnome.Program program;
- private DeviceCombo combo;
- private IPod.Device device = null;
- private TrackDatabase db = null;
- private TracksView tracks;
- private TreeModelFilter store_filter;
- 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 ImportDialog pdialog;
+ private ImportDialog progressDialog;
+ private CapacityBar capacityBar;
- ActionGroup group = null;
-
- private static TargetEntry [] tracksview_source_entries = {
- new TargetEntry ("text/uri-list", 0, 0),
- new TargetEntry ("application/x-hipo", 0, 0)
- };
-
- private static TargetEntry [] playlist_dest_entries = {
- new TargetEntry ("application/x-hipo", 0, 0)
- };
-
- public void CreateWindow (string [] args)
+ private Widget sourceWidget;
+ private Entry searchEntry;
+
+ public HipoMainWindow (string[] args)
{
- program = new Program (Defines.PACKAGE, Defines.VERSION, Modules.UI, args);
-
+ // disable logging
+ Tools.LogEnabled = false;
+
+ program = new Gnome.Program (Defines.PACKAGE, Defines.VERSION, Gnome.Modules.UI, args);
+
+ // create the device combo and hook up device changed event
combo = new DeviceCombo ();
-
- gxml = new Glade.XML (null, "hipo.glade", "hipoWindow", null);
- gxml.Autoconnect (this);
-
- tracks = new TracksView ();
- playlists = new PlaylistView ();
+ combo.Changed += OnDeviceChanged;
- 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 ("A_dd Folder..."), "<control>O",
- Catalog.GetString ("Add a folder to your iPod"), OnAddFolder),
- new ActionEntry ("Remove", Gtk.Stock.Remove, null, 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, null, "<control>Q", null, OnQuitActivated),
- new ActionEntry ("Preferences", Gtk.Stock.Preferences, null, null,
- null, OnPreferences),
- new ActionEntry ("Help", Gtk.Stock.Help, null, "F1",
- null, OnHelp),
- new ActionEntry ("About", Gnome.Stock.About, null, 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 ("RenamePlaylist", Gtk.Stock.Copy, Catalog.GetString ("Rename Playlist"), null,
- Catalog.GetString ("Rename the Playlist"), OnRenamePlaylist),
-
- 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");
- hipoWindow.AddAccelGroup (uim.AccelGroup);
+ // Even though we don't (currently) use dbus, ipod-sharp does.
+ // Without hooking up the glib main loop, some ipod-sharp functionality breaks.
+ BusG.Init ();
- numTracks = new Gtk.Label ("(0)");
- numTracks.UseMarkup = true;
+ gxml = new Glade.XML (null, "hipo.glade", "hipoWindow", null);
+ gxml.Autoconnect (this);
+ // set window icon
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 ();
+ // hook up window delete event
+ hipoWindow.DeleteEvent += OnDeleteEvent;
- tracksView.Model = tracks.GetModel ();
- plistView.Model = playlists.GetModel ();
-
- store_filter = new Gtk.TreeModelFilter (tracksView.Model, null);
- store_filter.VisibleFunc = SearchFilterFunc;
- filterEntry.Changed += SearchFor;
+ // create action entries
+ ActionEntry[] entries = {
- combo.Changed += OnDeviceChanged;
-
- tracksView.ButtonPressEvent += OnTracksButtonPress;
- tracksView.PopupMenu += OnTracksPopupMenu;
+ new ActionEntry ("FileMenu",
+ null,
+ Catalog.GetString ("_File"),
+ null,
+ null,
+ null),
+ new ActionEntry ("AddFile",
+ Stock.Add, Catalog.GetString ("_Add File..."),
+ null,
+ Catalog.GetString ("Add a file to your iPod"),
+ OnAddActivated),
+ new ActionEntry ("AddFolder",
+ Stock.Add,
+ Catalog.GetString ("A_dd Folder..."),
+ "<control>O",
+ Catalog.GetString ("Add a folder to your iPod"),
+ OnAddFolder),
+ new ActionEntry ("NewPlaylist",
+ Stock.New,
+ Catalog.GetString ("New Playlist"),
+ null,
+ Catalog.GetString ("Create a new Playlist"),
+ OnNewPlaylist),
+ new ActionEntry ("Eject",
+ null,
+ Catalog.GetString ("_Eject"),
+ null,
+ null,
+ OnEjectActivated),
+ new ActionEntry ("Quit",
+ Stock.Quit,
+ null,
+ "<control>Q",
+ null,
+ OnQuitActivated),
+
+ new ActionEntry ("EditMenu",
+ null,
+ Catalog.GetString ("_Edit"),
+ null,
+ null,
+ null),
+ new ActionEntry ("Preferences",
+ Stock.Preferences,
+ null,
+ null,
+ null,
+ OnPreferences),
+
+ new ActionEntry ("HelpMenu",
+ null,
+ Catalog.GetString ("_Help"),
+ null,
+ null,
+ null),
+ new ActionEntry ("Help",
+ Stock.Help,
+ null,
+ "F1",
+ null,
+ OnHelp),
+ new ActionEntry ("About",
+ Gnome.Stock.About,
+ null,
+ null,
+ null,
+ OnAboutActivated)
+ };
+ // create the ui manager and the keyboard shortcuts
+ ActionGroup group = new ActionGroup ("Hipo");
+ group.Add (entries);
- tracksView.EnableModelDragSource (Gdk.ModifierType.Button1Mask,
- tracksview_source_entries, Gdk.DragAction.Copy);
-
- tracksView.DragDataGet += OnTracksDragDataGet;
- tracksView.Selection.Mode = SelectionMode.Multiple;
+ UIManager.Instance.InsertActionGroup (group, 0);
+ UIManager.Instance.AddUiFromResource ("menubar.xml");
+ hipoWindow.AddAccelGroup (UIManager.Instance.AccelGroup);
- plistView.ButtonPressEvent += OnPlaylistButtonPress;
- plistView.PopupMenu += OnPlaylistPopupMenu;
+ // create the menu
+ menuBar.PackStart (UIManager.Instance.GetWidget ("/HipoMenu"), false, false, 0);
+ menuBar.ReorderChild (UIManager.Instance.GetWidget ("/HipoMenu"), 0);
- plistView.EnableModelDragDest (playlist_dest_entries, Gdk.DragAction.Copy);
+ // create the progress dialog
+ progressDialog = new ImportDialog (hipoWindow);
- plistView.DragDataReceived += OnPlistDragDataReceived;
-
- tracksView.EnableModelDragDest (tracksview_source_entries, Gdk.DragAction.Copy);
- tracksView.DragDataReceived += OnTracksDragDataReceived;
+ // create the capacity bar
+ capacityBar = new CapacityBar ();
+ sourceListBox.PackStart (capacityBar, false, false, 0);
- hipoWindow.DeleteEvent += OnDeleteEvent;
- plistView.Selection.Changed += OnPlaylistSelectionChanged;
+ // create the source list
+ sourceList = SourceList.Instance;
+ sourceListScroll.Child = sourceList.View;
+ sourceListScroll.Child.ShowAll ();
- menuTable = new Hashtable ();
- coverpreview = new Gtk.Image ();
-
- pdialog = new ImportDialog (hipoWindow);
-
- hipoWindow.ShowAll ();
-
- SetDevice ();
-
- program.Run ();
- }
-
- private void CreateTreeView ()
- {
- EditableCellRenderer cell = new EditableCellRenderer ();
- cell.Edited += OnTrackEdit;
- cell.Column = (int)TracksView.Column.Artist;
-
- TreeViewColumn column = new Gtk.TreeViewColumn (Catalog.GetString ("Artist"),
- cell, "text", (int)TracksView.Column.Artist);
- column.Resizable = true;
- column.Expand = false;
- column.SortIndicator = true;
- column.SortColumnId = (int)TracksView.Column.Artist;
- column.Sizing = TreeViewColumnSizing.Fixed;
- column.FixedWidth = 200;
- tracksView.AppendColumn (column);
-
- cell = new EditableCellRenderer ();
- cell.Edited += OnTrackEdit;
- cell.Column = (int)TracksView.Column.Album;
-
- column = new Gtk.TreeViewColumn (Catalog.GetString ("Album"),
- cell, "text", (int)TracksView.Column.Album);
- column.Resizable = true;
- column.Expand = false;
- column.SortIndicator = true;
- column.SortColumnId = (int)TracksView.Column.Album;
- column.Sizing = TreeViewColumnSizing.Fixed;
- column.FixedWidth = 200;
-
- tracksView.AppendColumn (column);
-
- cell = new EditableCellRenderer ();
- cell.Edited += OnTrackEdit;
- cell.Column = (int)TracksView.Column.Title;
-
- column = new Gtk.TreeViewColumn (Catalog.GetString ("Title"),
- cell, "text", (int)TracksView.Column.Title);
- column.Resizable = true;
- column.Expand = false;
- column.SortIndicator = true;
- column.SortColumnId = (int)TracksView.Column.Title;
- column.Sizing = TreeViewColumnSizing.Fixed;
- column.FixedWidth = 200;
-
- tracksView.AppendColumn (column);
-
- cell = new EditableCellRenderer ();
- cell.Edited += OnTrackEdit;
- cell.Column = (int)TracksView.Column.Genre;
-
- column = new Gtk.TreeViewColumn (Catalog.GetString ("Genre"),
- cell, "text", (int)TracksView.Column.Genre);
- column.Resizable = true;
- column.Expand = false;
- column.SortIndicator = true;
- column.SortColumnId = (int)TracksView.Column.Genre;
- column.Sizing = TreeViewColumnSizing.Fixed;
- column.FixedWidth = 100;
+ // the initial sourceWidget is the No device detected label
+ sourceWidget = defaultSourceWidget;
- tracksView.AppendColumn (column);
+ // ditto for the search entry
+ searchEntry = defaultSearchEntry;
- tracksView.HeadersVisible = true;
- tracksView.HeadersClickable = true;
-
- column = new Gtk.TreeViewColumn ("Icon", new Gtk.CellRendererPixbuf (), "pixbuf", (int)PlaylistView.Column.Icon);
- column.Expand = false;
- plistView.AppendColumn (column);
-
- cell = new EditableCellRenderer ();
- cell.Edited += OnPlaylistEdit;
- cell.Column = (int)PlaylistView.Column.Name;
-
- column = new Gtk.TreeViewColumn ("Name", cell, "text", (int)PlaylistView.Column.Name);
- column.Expand = true;
- plistView.AppendColumn (column);
-
- Gtk.CellRendererText celltext = new Gtk.CellRendererText ();
- celltext.Foreground = "grey";
- column = new Gtk.TreeViewColumn ("Counts", celltext, "text", (int)PlaylistView.Column.Count);
- column.Expand = false;
- plistView.AppendColumn (column);
+ // hook up the selection changed source list event
+ sourceList.SelectionChanged += OnSourceListSelectionChanged;
- 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 ();
+ Tools.Log (this, "Finished creating the window");
- 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);
- }
+ hipoWindow.ShowAll ();
- addToPlaylistItem.Submenu = playlistMenu;
-
- menu.ShowAll ();
- playlistMenu.ShowAll ();
+ SetDevice ();
- 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;
- }
+ program.Run ();
}
- private void OnTrackEdit (object o, EditedArgs args)
+ public Window Window
{
- 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, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
-
- switch (cell.Column)
- {
- case (int)TracksView.Column.Artist:
- if (args.NewText != track.Artist)
- {
- track.Artist = args.NewText;
- modified = true;
- }
- break;
- case (int)TracksView.Column.Album:
- if (args.NewText != track.Album)
- {
- track.Album = args.NewText;
- modified = true;
- }
- break;
- case (int)TracksView.Column.Title:
- if (args.NewText != track.Title)
- {
- track.Title = args.NewText;
- modified = true;
- }
- break;
- case (int)TracksView.Column.Genre:
- 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 ();
+ get {
+ return hipoWindow;
}
}
- private void OnPlaylistEdit (object o, EditedArgs args)
- {
- TreeIter iter = TreeIter.Zero;
- TreeStore store = playlists.GetModel ();
- bool modified = false;
-
- if (!store.GetIter (out iter, new TreePath (args.Path)))
- return;
- else
- {
- string plistName = (string) store.GetValue (iter, (int)PlaylistView.Column.Name);
-
- if (args.NewText != plistName)
- {
- if (playlists.UpdatePlaylistName (db, iter, args.NewText))
- modified = true;
- }
- }
-
- if (modified)
- {
- Thread thr = new Thread (new ThreadStart (SaveDB));
- thr.Start ();
- }
- }
-
- private void OnRenamePlaylist (object o, EventArgs args)
+ private void SetDevice (IPod.Device device)
{
- TreeModel model;
- TreeIter iter;
- bool modified = false;
+ capacityBar.Device = device;
- if (plistView.Selection.GetSelected (out model, out iter))
+ if (device == null)
{
- string plistName = (string) model.GetValue (iter, (int)PlaylistView.Column.Name);
-
- Dialog dialog = new Dialog (Catalog.GetString ("Rename the Playlist"), hipoWindow, Gtk.DialogFlags.DestroyWithParent);
+ // deactivate the menu options
+ SetGreyedObjects (true);
- dialog.Modal = true;
- dialog.AddButton ("Cancel", ResponseType.Close);
- dialog.AddButton ("OK", ResponseType.Ok);
+ progressDialog.TrackDatabase = null;
- Gtk.Entry entry = new Gtk.Entry (plistName);
- dialog.VBox.PackStart (entry, false, false, 5);
- dialog.DefaultResponse = ResponseType.Ok;
+ sourceList.SelectedSource = null;
+ sourceList.Clear ();
- dialog.ShowAll ();
- ResponseType r = (ResponseType) dialog.Run ();
+ Tools.Log (this, "No device set");
- if (r == ResponseType.Ok)
- {
- if (entry.Text != plistName)
- {
- if (playlists.UpdatePlaylistName (db, iter, entry.Text))
- modified = true;
- }
- }
-
- dialog.Destroy ();
+ return;
}
- if (modified)
- {
- Thread thr = new Thread (new ThreadStart (SaveDB));
- thr.Start ();
- }
- }
-
- private void PlaylistPopupMenu (Gdk.EventButton ev)
- {
- TreeModel model;
- TreeIter iter;
+ // activate the menu options
+ SetGreyedObjects (false);
- Gtk.Menu menupl;
-
- if (plistView.Selection.GetSelected (out model, out iter)) {
-
- string plistName = (string) model.GetValue (iter, (int)PlaylistView.Column.Name);
- Playlist plist = null;
-
- if (model.IterHasChild (iter)) {
- menupl = (Gtk.Menu) uim.GetWidget ("/ui/DevicePopup");
- menupl.ShowAll ();
-
- menupl.Popup (null, null, null, (ev != null) ? ev.Button : 0,
- (ev != null) ? ev.Time : 0);
- } else {
- 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);
- }
- }
- }
- }
-
- private void OnPlaylistPopupMenu (object o, PopupMenuArgs args)
- {
- PlaylistPopupMenu (null);
- }
-
- private void OnDeletePlaylist (object o, EventArgs args)
- {
- TreeModel model;
- TreeIter iter;
+ progressDialog.TrackDatabase = device.TrackDatabase;
- if (plistView.Selection.GetSelected (out model, out iter))
- {
- string plistName = (string) model.GetValue (iter, (int)PlaylistView.Column.Name);
-
- 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 ();
+ // create the Saver instance
+ Saviour.Instantiate (device);
- 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)
+ // create the device source
+ sourceList.Add (new DeviceSource (device));
+
+ // create tracks source and add it to the source list
+ sourceList.Add (new TracksSource (device.TrackDatabase));
+
+ // for each playlist in the track database create a playlist source and add it to the source list
+ foreach (Playlist playlist in device.TrackDatabase.Playlists)
{
- SetGreyedObjects (false);
- return;
+ sourceList.Add (new PlaylistSource (playlist));
}
- SetGreyedObjects (true);
+ // select the tracks source
+ sourceList.SelectedSource = SourceList.Instance.Tracks;
- this.device = device;
-
- Thread thr = new Thread (new ThreadStart (PopulateView));
- thr.Start ();
- notify = new ThreadNotify (new ReadyEvent (RefreshPlaylistView));
+ sourceList.ExpandAll ();
+
+ Tools.Log (this, "Set device {0}", device.Name);
}
private void SetDevice ()
@@ -608,98 +248,32 @@
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 ()
+ private void SetGreyedObjects (bool greyed)
{
- Gtk.TreeIter iter;
-
- this.db = this.device.TrackDatabase;
- pdialog.TrackDatabase = this.db;
-
- playlists.AddDeviceToStore (this.device);
-
- foreach (Playlist plist in this.db.Playlists)
+ foreach (ActionGroup group in UIManager.Instance.ActionGroups)
{
- playlists.AddListToStore (plist);
- }
-
- Thread thrb = new Thread (new ThreadStart (PopulateTracksView));
- thrb.Start ();
-
- if (plistView.Model.GetIterFirst (out iter)) {
-
- if (plistView.Model.IterHasChild (iter)) {
- plistView.ExpandAll ();
+ if (group.Name == "Hipo")
+ {
+ group["AddFile"].Sensitive = !greyed;
+ group["AddFolder"].Sensitive = !greyed;
+ group["Eject"].Sensitive = !greyed;
+ group["NewPlaylist"].Sensitive = !greyed;
}
}
}
-
- 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 ()
- {
- if (tracks.AddFolder (db, uris)) {
- playlists.RefreshDevice (this.device);
- SaveDB ();
- notify.WakeupMain ();
- }
- }
private void OnAddActivated (System.Object o, EventArgs args)
{
- FileFilter filter = new Gtk.FileFilter ();
+ string[] uris;
- Gtk.FileChooserDialog fileChooser = new Gtk.FileChooserDialog (Catalog.GetString ("Select the file to add"),
+ FileFilter filter = new FileFilter ();
+
+ FileChooserDialog fileChooser = new FileChooserDialog (Catalog.GetString ("Select the file to add"),
hipoWindow,
FileChooserAction.Open,
- Gtk.Stock.Cancel, ResponseType.Cancel,
- Gtk.Stock.Add, ResponseType.Accept);
+ Stock.Cancel, ResponseType.Cancel,
+ Stock.Add, ResponseType.Accept);
fileChooser.SelectMultiple = true;
fileChooser.LocalOnly = true;
@@ -709,548 +283,116 @@
filter.AddMimeType ("audio/x-m4a");
fileChooser.AddFilter (filter);
- ResponseType res = (ResponseType) fileChooser.Run ();
+ 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 ()
- {
- bool modified = false;
-
- foreach (string urin in uris)
- {
- Uri uri = new Uri (urin);
- modified = tracks.AddTrack (this.db, uri.LocalPath);
- }
-
- if (modified) {
- Thread thr = new Thread (new ThreadStart (SaveDB));
- thr.Start ();
-
- playlists.RefreshDevice (this.device);
- notify.WakeupMain ();
+ sourceList.Tracks.AddTracks (uris, true);
}
}
-
- 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, (int)TracksView.Column.Id);
-
- 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)
+ private void OnAddFolder (System.Object o, EventArgs args)
{
- TreeIter iter;
- TreeModel model;
- ListStore store;
- Gtk.HBox hbox;
- Gtk.ScrolledWindow scroll;
- TreeView view;
- Queue iterQueue;
-
- if (tracksView.Selection.CountSelectedRows() < 1)
- return;
+ string[] uris;
- 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);
+ FileChooserDialog fileChooser = new FileChooserDialog (Catalog.GetString ("Select a folder to add"),
+ hipoWindow,
+ FileChooserAction.SelectFolder,
+ Stock.Cancel, ResponseType.Cancel,
+ Stock.Add, ResponseType.Accept);
- 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?"))
- );
+ fileChooser.LocalOnly = true;
- dialog.Resizable = true;
+ ResponseType res = (ResponseType) fileChooser.Run ();
+ uris = fileChooser.Uris;
+ fileChooser.Destroy ();
- foreach (TreePath tPath in treePaths)
+ if (res == ResponseType.Accept)
{
- if (model.GetIter (out iter, tPath)) {
-
- string Artist = (string) model.GetValue (iter, (int)TracksView.Column.Artist);
- string Album = (string) model.GetValue (iter, (int)TracksView.Column.Album);
- string Title = (string) model.GetValue (iter, (int)TracksView.Column.Title);
-
- store.AppendValues (String.Format ("{0} - {1} - {2}", Artist, Album, Title));
- }
+ sourceList.Tracks.AddFolder (uris, true);
}
+ }
+
+ private void OnNewPlaylist (object o, EventArgs args)
+ {
+ HBox hbox = new HBox ();
+ Label name = new Label (Catalog.GetString ("Name: "));
+ Entry entry = new Entry ();
+
+ Dialog dialog = new Dialog (Catalog.GetString ("New Playlist"), this.hipoWindow,
+ DialogFlags.DestroyWithParent,
+ Stock.Cancel, ResponseType.Cancel,
+ Stock.Ok, ResponseType.Accept);
- view.Model = store;
-
- scroll.Add (view);
- hbox.Add (scroll);
+ hbox.BorderWidth = 5;
+ hbox.Add (name);
+ hbox.Add (entry);
hbox.ShowAll ();
dialog.VBox.Add (hbox);
-
- ResponseType response = (ResponseType) dialog.Run ();
+
+ ResponseType res = (ResponseType) dialog.Run ();
dialog.Destroy ();
- if (response == ResponseType.Ok)
+ if (res == ResponseType.Accept)
{
- foreach (TreePath tPath in treePaths)
- {
- if (model.GetIter (out iter, tPath)) {
- iterQueue.Enqueue (iter);
-
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- 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);
-
+ Playlist playlist = sourceList.Tracks.CreatePlaylist (entry.Text);
+ sourceList.Add (new PlaylistSource (playlist));
}
}
-
- [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;
- [Widget] private Gtk.Label titleLabel;
- [Widget] private Gtk.Label numberLabel;
-
- private void OnTrackProperties (object o, EventArgs args)
+
+ private void OnSourceListSelectionChanged (object o, SourceList.SelectionChangedArgs args)
{
- Glade.XML xml = new Glade.XML (null, "hipo.glade", "trackProperties", null);
- xml.Autoconnect (this);
-
- bool modified = false;
- TreeModel model;
- Gdk.Pixbuf newCover = null;
- string artist = "";
- string album = "";
- string title = "";
- string genre = "";
- int trackNumber = 0;
- Gdk.Pixbuf image = null;
-
- /*
- This way of doing things seems rather ugly to me (bgarret), as the conversion
- TreeIter -> trackId -> track is done every time I iterate over the treePaths ArrayList.
- */
+ sourceScroll.Remove (sourceWidget);
+ searchBox.Remove (searchEntry);
- ArrayList treePaths = ArrayList.Adapter (tracksView.Selection.GetSelectedRows (out model));
- ArrayList treeIters = new ArrayList ();
-
- foreach (TreePath treePath in treePaths)
+ if (args.Source != null)
{
- TreeIter iter;
- if (model.GetIter (out iter, treePath))
- {
- treeIters.Add (iter);
- }
- }
-
- if (treeIters.Count > 0)
- {
- foreach (TreeIter iter in treeIters)
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
+ sourceWidget = args.Source.View;
+ searchEntry = args.Source.SearchEntry;
- /*
- The values are filled in with the properties of the first track of the list.
- A comparison is made with the subsequent tracks,
- if the values are the same, nothing is changed,
- if they are different, a blank value is put
- */
-
- if (treeIters.IndexOf (iter) == 0)
- {
- artist = track.Artist;
- album = track.Album;
- title = track.Title;
- genre = track.Genre;
- trackNumber = track.TrackNumber;
-
- foreach (ArtworkFormat format in this.device.LookupArtworkFormats (ArtworkUsage.Cover)) {
-
- if (format != null) {
- if (track.HasCoverArt (format))
- image = ArtworkHelpers.ToPixbuf (format, track.GetCoverArt (format));
- }
- }
-
- if (treeIters.Count == 1)
- {
- /* artist name and track title properties */
- trackProperties.Title = String.Format (Catalog.GetString ("{0} {1} Properties"),
- track.Artist, track.Title);
- }
- else
- {
- trackProperties.Title = Catalog.GetString ("Multiple tracks properties");
- titleEntry.Hide ();
- titleLabel.Hide ();
- numberLabel.Hide ();
- numberSpin.Hide ();
- }
- }
- else
- {
- if (!artist.Equals("") && !artist.Equals (track.Artist))
- artist = "";
-
- if (!album.Equals("") && !album.Equals (track.Album))
- album = "";
-
- if (!title.Equals("") && !title.Equals (track.Title))
- title = "";
-
- if (!genre.Equals("") && !genre.Equals (track.Genre))
- genre = "";
-
- if ((trackNumber != 0) && (trackNumber != track.TrackNumber))
- trackNumber = 0;
-
- }
- }
-
- artistEntry.Text = artist;
- albumEntry.Text = album;
- titleEntry.Text = title;
- genreEntry.Text = genre;
- numberSpin.Value = trackNumber;
- artwork.FromPixbuf = image;
}
-
- 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)
+ else
{
- if (artistEntry.Text != artist) {
- modified = true;
- foreach (TreeIter iter in treeIters)
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
- track.Artist = artistEntry.Text;
- }
- }
-
- if (albumEntry.Text != album) {
- modified = true;
- foreach (TreeIter iter in treeIters)
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
- track.Album = albumEntry.Text;
- }
- }
-
- if (titleEntry.Text != title) {
- modified = true;
- foreach (TreeIter iter in treeIters)
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
- track.Title = titleEntry.Text;
- }
- }
-
- if (genreEntry.Text != genre) {
- modified = true;
- foreach (TreeIter iter in treeIters)
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
- track.Genre = genreEntry.Text;
- }
- }
-
- if (numberSpin.Value != trackNumber) {
- modified = true;
- foreach (TreeIter iter in treeIters)
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
- 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.
-
- foreach (TreeIter iter in treeIters)
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
- track.SetCoverArt (format, ArtworkHelpers.ToBytes (format, newCover));
- }
- }
-
- modified = true;
- }
+ sourceWidget = defaultSourceWidget;
+ searchEntry = defaultSearchEntry;
}
-
- if (modified) {
- foreach (TreeIter iter in treeIters)
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
- tracks.UpdateStore (track, iter);
- }
-
- Thread thr = new Thread (new ThreadStart (SaveDB));
- thr.Start ();
- }
-
- trackProperties.Destroy ();
+
+ sourceScroll.Child = sourceWidget;
+ searchBox.PackStart (searchEntry, false, true, 0);
+ sourceWidget.ShowAll ();
+ searchEntry.ShowAll ();
}
-
- [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);
- /* ipod name properties ex: my ipod properties */
- 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)
+ private void OnDeviceChanged (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);
- }
+ SetDevice (combo.ActiveDevice);
}
- private void OnPlaylistSelectionChanged (object o, EventArgs args)
- {
- TreeModel model;
- TreeIter iter;
-
- if (((TreeSelection)o).GetSelected (out model, out iter)) {
- int sourceType = (int) model.GetValue (iter, (int)PlaylistView.Column.SourceType);
- filterEntry.Text = "";
-
- switch (sourceType)
- {
- case (int)SourceType.Ipod:
- menu = (Gtk.Menu) uim.GetWidget ("/ui/TracksPopup");
- tracksView.Model = tracks.GetModel ();
- break;
-
- case (int)SourceType.Playlist:
- IPod.Playlist plist;
- if ((plist = this.db.LookupPlaylist ((string)model.GetValue (iter, (int)PlaylistView.Column.Name))) != null) {
- menu = (Gtk.Menu) uim.GetWidget ("/ui/TracksPlaylistPopup");
- tracksView.Model = playlists.GetModel (plist);
- }
- break;
-
- default:
- break;
- }
- store_filter = new Gtk.TreeModelFilter (tracksView.Model, null);
- store_filter.VisibleFunc = SearchFilterFunc;
- }
- }
-
- 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, (int)PlaylistView.Column.Name);
- plist = this.db.LookupPlaylist (playlistName);
- }
-
- foreach (TreePath tPath in treePaths)
- {
- TreeIter iter;
-
- if (model.GetIter (out iter, tPath))
- {
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- 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 ();
+ SourceList.Instance.Device.Eject ();
+ Gtk.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;
@@ -1258,56 +400,55 @@
error.Destroy ();
}
}
-
+
private void OnPreferences (object o, EventArgs args)
{
// FIXME
}
-
+
private void OnHelp (object o, EventArgs args)
{
ShowHelp ("hipo.xml", null, hipoWindow.Screen, null);
}
-
- // borrowed from tomboy
- public void ShowHelp (string filename, string link_id, Gdk.Screen screen, Gtk.Window parent)
- {
- try {
- Gnome.Help.DisplayDesktopOnScreen (
- Gnome.Program.Get (),
- Defines.GNOME_HELP_DIR,
- filename,
- link_id,
- screen);
- } catch {
- string message =
- Catalog.GetString ("The \"Hipo Manual\" could " +
- "not be found. Please verify " +
- "that your installation has been " +
- "completed successfully.");
- MessageDialog dialog = new MessageDialog (parent,
- Gtk.DialogFlags.DestroyWithParent,
- Gtk.MessageType.Error,
- Gtk.ButtonsType.Ok,
- Catalog.GetString ("Help not found"),
- message);
- dialog.Run ();
- dialog.Destroy ();
- }
- }
-
-
+
+ // borrowed from tomboy
+ private void ShowHelp (string filename, string link_id, Gdk.Screen screen, Window parent)
+ {
+ try {
+ Gnome.Help.DisplayDesktopOnScreen (
+ Gnome.Program.Get (),
+ Defines.GNOME_HELP_DIR,
+ filename,
+ link_id,
+ screen);
+ } catch {
+ string message =
+ Catalog.GetString ("The \"Hipo Manual\" could " +
+ "not be found. Please verify " +
+ "that your installation has been " +
+ "completed successfully.");
+ MessageDialog dialog = new MessageDialog (parent,
+ DialogFlags.DestroyWithParent,
+ MessageType.Error,
+ ButtonsType.Ok,
+ Catalog.GetString ("Help not found"),
+ message);
+ dialog.Run ();
+ dialog.Destroy ();
+ }
+ }
+
private void OnAboutActivated (object o, EventArgs args)
{
- Gtk.AboutDialog aboutDialog = new Gtk.AboutDialog ();
+ AboutDialog aboutDialog = new AboutDialog ();
string[] authors = { "Pedro Villavicencio Garrido <pvillavi gnome org>",
- "Felipe Barros S. <felipeb gnome cl>",
- "Benoit Garret <benoit garret_gnome gadz org>" };
+ "Felipe Barros S. <felipeb gnome cl>",
+ "Benoit Garret <benoit garret_gnome gadz org>" };
string[] artists = { "Carlos Candia Flores <cerealk vtr net>",
- "Gabriel Bustos Farret <lemut lemut com>" };
-
- string[] documenters = { "Gabriel Felipe Cornejo Salas <gfc gnome cl>",
- "Basilio Kublik <basilio gnome cl>" };
+ "Gabriel Bustos Farret <lemut lemut com>" };
+
+ string[] documenters = { "Gabriel Felipe Cornejo Salas <gfc gnome cl>",
+ "Basilio Kublik <basilio gnome cl>" };
aboutDialog.Authors = authors;
aboutDialog.Copyright = "Copyright  2006-2007 Pedro Villavicencio Garrido";
@@ -1315,251 +456,15 @@
aboutDialog.Comments = Catalog.GetString ("iPod Management Tool");
aboutDialog.Version = Defines.VERSION;
aboutDialog.Artists = artists;
- aboutDialog.Documenters = documenters;
+ aboutDialog.Documenters = documenters;
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 * 100) / ((double) this.device.VolumeSize);
- /* space used in the device, example: used 15G of 60G */
- ipodCapacityBar.Text = String.Format (Catalog.GetString ("Used {0} of {1}"), used, capacity);
- ipodCapacityBar.Fraction = percent / 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;
- ArrayList list = new ArrayList ();
- StringBuilder dragData = new StringBuilder ();
-
- Array treePaths = tracksView.Selection.GetSelectedRows (out model);
-
- foreach (TreePath tPath in treePaths)
- {
- if (model.GetIter (out iter, tPath)) {
-
- long trackId = (long) model.GetValue (iter, (int)TracksView.Column.Id);
- Track track = tracks.GetTrackbyId (this.db, trackId);
-
- if (track != null)
- list.Add (track);
- }
- }
-
- Track[] songs = (Track[]) list.ToArray (typeof (Track));
-
- if (args.SelectionData.Target == "text/uri-list") {
- foreach (Track track in songs) {
- dragData.Append (track.FileName + "\r\n");
- }
-
- args.SelectionData.Set (targets[0], 8,
- System.Text.Encoding.UTF8.GetBytes (dragData.ToString()));
-
- } else {
- foreach (Track track in songs) {
- dragData.Append (track.Id + "\n");
- }
-
- args.SelectionData.Set (targets[0], 8,
- System.Text.Encoding.UTF8.GetBytes (dragData.ToString ()));
- }
-
- }
-
- 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);
-
- try {
- string plistName = (string) model.GetValue (iter, (int)PlaylistView.Column.Name);
-
- if ((plist = this.db.LookupPlaylist (plistName)) != null) {
- string data = System.Text.Encoding.UTF8.GetString (args.SelectionData.Data);
-
- foreach (string d in data.Trim ().Split ('\n')) {
- Track track = tracks.GetTrackbyId (this.db, long.Parse (d));
-
- 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);
- }
-
- } catch (Exception e) {
- Console.WriteLine ("{0}", e.Message);
- }
- }
-
- private void OnTracksDragDataReceived (object o, DragDataReceivedArgs args)
- {
- try {
- if ((Gtk.Drag.GetSourceWidget (args.Context) != tracksView) &&
- (args.SelectionData.Length >=0 && args.SelectionData.Format == 8))
- {
- string data = System.Text.Encoding.UTF8.GetString (args.SelectionData.Data);
-
- bool modified = false;
-
- foreach (string ur in data.Trim ().Split ('\n')) {
- string formatUri = ur.Trim ();
-
- Uri uri = new Uri (formatUri);
-
- if (Directory.Exists (uri.LocalPath)) {
- string[] tmp = { uri.LocalPath };
- if (tracks.AddFolder (this.db, tmp))
- if (!modified)
- modified = true;
- } else if (File.Exists (uri.LocalPath)) {
- if (tracks.AddTrack (this.db, uri.LocalPath))
- if (!modified)
- modified = true;
- }
- }
-
- Gtk.Drag.Finish (args.Context, true, false, args.Time);
-
- if (modified) {
- Thread thr = new Thread (new ThreadStart (SaveDB));
- thr.Start ();
-
- playlists.RefreshDevice (this.device);
- }
-
- }
- } catch (Exception e) {
- Console.WriteLine (e.Message);
- }
- }
-
- private bool SearchFilterFunc (Gtk.TreeModel model, Gtk.TreeIter iter)
- {
- if (filterEntry.Text.Trim().Length < 1)
- return true;
- bool ret = true;
- try {
- string search_term = filterEntry.Text.Trim().ToLower();
- string artist = ((string) model.GetValue (iter, (int)TracksView.Column.Artist)).ToLower();
- string album = ((string) model.GetValue (iter, (int)TracksView.Column.Album)).ToLower();
- string title = ((string) model.GetValue (iter, (int)TracksView.Column.Title)).ToLower();
- string genre = ((string) model.GetValue (iter, (int)TracksView.Column.Genre)).ToLower();
- ret = ( artist.Contains(search_term) ||
- album.Contains(search_term) ||
- title.Contains(search_term) ||
- genre.Contains(search_term)
- );
- } catch (Exception e) {
- Console.WriteLine (e.Message);
- }
- return ret;
- }
-
- private void SearchFor (object o, EventArgs args)
- {
- tracksView.Model = store_filter;
- store_filter.Refilter();
- }
}
}
Modified: branches/bgarret/src/Makefile.am
==============================================================================
--- branches/bgarret/src/Makefile.am (original)
+++ branches/bgarret/src/Makefile.am Thu Jan 31 21:38:51 2008
@@ -9,21 +9,32 @@
HIPO_GENERATED_FILES = Defines.cs
-HIPO_SOURCES = \
- $(srcdir)/HipoMain.cs \
- $(srcdir)/HipoMainWindow.cs \
- $(srcdir)/TracksView.cs \
+HIPO_SOURCES = \
+ $(srcdir)/Saviour.cs \
+ $(srcdir)/Tools.cs \
+ $(srcdir)/Source.cs \
$(srcdir)/ImportDialog.cs \
- $(srcdir)/PlaylistView.cs
+ $(srcdir)/CapacityBar.cs \
+ $(srcdir)/EditableCellRenderer.cs \
+ $(srcdir)/TracksContainer.cs \
+ $(srcdir)/DeviceSource.cs \
+ $(srcdir)/PlaylistSource.cs \
+ $(srcdir)/TracksSource.cs \
+ $(srcdir)/SourceList.cs \
+ $(srcdir)/HipoMainWindow.cs \
+ $(srcdir)/HipoMain.cs
HIPO_RESOURCES = \
$(srcdir)/hipo.glade \
$(srcdir)/errordialog.glade \
- $(srcdir)/hipo.xml \
+ $(srcdir)/menubar.xml \
+ $(srcdir)/devicepopup.xml \
+ $(srcdir)/playlistpopup.xml \
+ $(srcdir)/trackpopup.xml \
$(top_srcdir)/data/hipo-logo.png \
$(top_srcdir)/data/ipod.gif
-HIPO_ASSEMBLIES = -r:Mono.Posix -pkg:gtk-sharp-2.0,gnome-sharp-2.0,glade-sharp-2.0,ipod-sharp,ipod-sharp-ui -r:$(top_builddir)/taglib-sharp/taglib-sharp.dll
+HIPO_ASSEMBLIES = -r:Mono.Posix -pkg:gtk-sharp-2.0,gnome-sharp-2.0,glade-sharp-2.0,ipod-sharp,ipod-sharp-ui,ndesk-dbus-glib-1.0 -r:$(top_builddir)/taglib-sharp/taglib-sharp.dll
ASSEMBLY = hipo.exe
Added: branches/bgarret/src/PlaylistSource.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/PlaylistSource.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,313 @@
+// PlaylistSource.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using System.Collections.Generic;
+using Gtk;
+using IPod;
+using Mono.Unix;
+
+namespace Hipo
+{
+ public class PlaylistSource : TracksContainer
+ {
+ Playlist playlist;
+ public override event SourceDeletedEventHandler Deleted;
+
+ public PlaylistSource (Playlist playlist) : base ()
+ {
+ this.playlist = playlist;
+ Tracks = playlist.Tracks;
+
+ this.Type = Hipo.SourceType.Playlist;
+ this.Parent = SourceType.Device;
+ this.Icon = Gnome.IconTheme.Default.LoadIcon ("stock_playlist", 16, 0);
+
+ // hook up add and remove track event
+ playlist.TrackAdded += OnTrackAdded;
+ playlist.TrackRemoved += OnTrackRemoved;
+
+ // source list right click menu
+ // don't connect the handlers now
+ ActionEntry[] entries = {
+
+ new ActionEntry ("RenamePlaylist",
+ Gtk.Stock.Copy,
+ Catalog.GetString ("Rename"),
+ null,
+ Catalog.GetString ("Rename the playlist"),
+ null),
+ new ActionEntry ("DeletePlaylist",
+ Gtk.Stock.Delete,
+ Catalog.GetString ("Delete"),
+ null,
+ Catalog.GetString ("Delete the playlist"),
+ null)
+ };
+
+ ActionGroup group = new ActionGroup ("PlaylistPopup");
+ group.Add (entries);
+
+ UIManager.Instance.InsertActionGroup (group, 0);
+ UIManager.Instance.AddUiFromResource ("playlistpopup.xml");
+ }
+
+ public override string Name
+ {
+ get {
+ return playlist.Name;
+ }
+ set {
+ if (value != playlist.Name)
+ {
+ playlist.Name = value;
+ Saviour.Instance.Save ();
+ }
+ }
+ }
+
+ public override Menu Menu
+ {
+ get {
+ return (Menu)UIManager.Instance.GetWidget ("/ui/PlaylistPopup");
+ }
+ }
+
+ public override int Count
+ {
+ get {
+ return playlist.Tracks.Count;
+ }
+ }
+
+ public void AddTrack (Track track)
+ {
+ AddTrack (track, true);
+ }
+
+ public void AddTracks (List<Track> tracks)
+ {
+ foreach (Track track in tracks)
+ {
+ AddTrack (track, false);
+ }
+
+ Saviour.Instance.Save ();
+ }
+
+ private void AddTrack (Track track, bool save)
+ {
+ playlist.AddTrack (track);
+ }
+
+ // Adds the tracks to the database, then to the playlist
+ public override bool AddTracks (string[] uris, bool save)
+ {
+ bool trackAdded = false;
+
+ foreach (string uri in uris)
+ {
+ Uri u = new Uri (uri);
+ Track track = SourceList.Instance.Tracks.AddTrack (u.LocalPath, false);
+
+ if (track == null)
+ trackAdded |= false;
+ else
+ {
+ trackAdded |= true;
+ AddTrack (track, false);
+ }
+ }
+
+ if (trackAdded && save)
+ Saviour.Instance.Save ();
+
+ return trackAdded;
+ }
+
+ // Adds the tracks to the database, then to the playlist
+ public override bool AddFolder (string[] dirs, bool save)
+ {
+ // returns true if at least one track has been added
+ bool trackAdded = false;
+
+ foreach (string path in dirs)
+ {
+ if (path == null)
+ return false;
+
+ System.Uri uri = new System.Uri (path);
+
+ UnixDirectoryInfo info = new UnixDirectoryInfo (uri.LocalPath);
+ foreach (UnixFileSystemInfo file in info.GetFileSystemEntries ())
+ {
+ // |= gives true as soon as one of the arguments is true
+ if (!file.IsDirectory)
+ {
+ Track track = SourceList.Instance.Tracks.AddTrack (file.FullName, false);
+
+ if (track == null)
+ trackAdded |= false;
+ else
+ {
+ trackAdded |= true;
+ AddTrack (track, false);
+ }
+ }
+ else
+ {
+ string[] tmp = { file.FullName };
+ trackAdded |= AddFolder (tmp, false);
+ }
+ }
+ }
+
+ if (trackAdded && save)
+ Saviour.Instance.Save ();
+
+ return trackAdded;
+ }
+
+ public void RemoveTrack (Track track)
+ {
+ RemoveTrack (track, true);
+ }
+
+ public override void RemoveTracks (List<Track> tracks)
+ {
+ Tools.Log (this, "Removing {0} tracks from the playlist {1}", tracks.Count, playlist.Name);
+
+ foreach (Track track in tracks)
+ {
+ RemoveTrack (track, false);
+ }
+
+ Saviour.Instance.Save ();
+ }
+
+ private void RemoveTrack (Track track, bool save)
+ {
+ playlist.RemoveTrack (track);
+
+ if (save)
+ Saviour.Instance.Save ();
+ }
+
+ protected override void AddEventHandlers ()
+ {
+ Tools.Log (this, "Hooking {0} source menu event handlers", this.Name);
+
+ Menu menu = (Menu)UIManager.Instance.GetWidget ("/ui/PlaylistPopup");
+
+ // re-bind the menu items to the correct methods
+ foreach (MenuItem item in menu.Children)
+ {
+ switch (item.Name)
+ {
+ case "RenamePlaylist":
+ item.Activated += OnRename;
+ break;
+ case "DeletePlaylist":
+ item.Activated += OnDelete;
+ break;
+ }
+ }
+
+ base.AddEventHandlers ();
+ }
+
+ protected override void RemoveEventHandlers ()
+ {
+ Tools.Log (this, "Unhooking {0} source menu event handlers", this.Name);
+
+ Menu menu = (Menu)UIManager.Instance.GetWidget ("/ui/PlaylistPopup");
+
+ // re-bind the menu items to the correct methods
+ foreach (MenuItem item in menu.Children)
+ {
+ switch (item.Name)
+ {
+ case "RenamePlaylist":
+ item.Activated -= OnRename;
+ break;
+ case "DeletePlaylist":
+ item.Activated -= OnDelete;
+ break;
+ }
+ }
+
+ base.RemoveEventHandlers ();
+ }
+
+ private void OnTrackAdded (object o, int index, Track track)
+ {
+ Tools.Log (this, "Adding track {0} to playlist {1} at position {2}", track.Title, this.Name, index);
+ store.AppendValues (track);
+ }
+
+ private void OnTrackRemoved (object o, int index, Track track)
+ {
+ TreePath path = new TreePath ();
+ path.AppendIndex (index);
+
+ TreeIter iter = TreeIter.Zero;
+
+ if (!store.GetIter (out iter, path))
+ return;
+
+ store.Remove (ref iter);
+ }
+
+ private void OnRename (object o, EventArgs args)
+ {
+ Dialog dialog = new Dialog (Catalog.GetString ("Rename the playlist"), null, Gtk.DialogFlags.DestroyWithParent);
+
+ dialog.Modal = true;
+ dialog.AddButton ("Cancel", ResponseType.Close);
+ dialog.AddButton ("OK", ResponseType.Ok);
+
+ Gtk.Entry entry = new Gtk.Entry (this.Name);
+ dialog.VBox.PackStart (entry, false, false, 5);
+ dialog.DefaultResponse = ResponseType.Ok;
+
+ dialog.ShowAll ();
+ ResponseType r = (ResponseType) dialog.Run ();
+
+ if (r == ResponseType.Ok)
+ {
+ this.Name = entry.Text;
+ }
+
+ dialog.Destroy ();
+ }
+
+ private void OnDelete (object o, EventArgs args)
+ {
+ SourceList.Instance.Tracks.DeletePlaylist (playlist);
+
+ if (Deleted != null)
+ {
+ Deleted (this);
+ }
+
+ Saviour.Instance.Save ();
+ }
+ }
+}
Added: branches/bgarret/src/Saviour.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/Saviour.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,85 @@
+// Saver.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using System.Threading;
+using IPod;
+
+namespace Hipo
+{
+ // handles the save operations
+ public class Saviour
+ {
+ private static Saviour saviour = null;
+ private Device device;
+
+ public Saviour (Device device)
+ {
+ Tools.Log (this, "A saviour named {0} is born", device.Name);
+ this.device = device;
+ }
+
+ public static Saviour Instance {
+
+ get {
+ return saviour;
+ }
+ }
+
+ public static void Instantiate (Device device)
+ {
+ saviour = new Saviour (device);
+ }
+
+ public void Save ()
+ {
+ ThreadStart starter = delegate {
+
+ lock (this.device) {
+ this.device.Save ();
+ }
+ };
+
+ new Thread(starter).Start();
+ }
+ }
+
+ public class UIManager : Gtk.UIManager
+ {
+ private static Gtk.UIManager manager = null;
+
+ public UIManager () : base ()
+ {
+ Tools.Log (this, "Creating a new UIManager");
+ }
+
+ public static Gtk.UIManager Instance {
+
+ get {
+ if (manager == null)
+ {
+ manager = new UIManager ();
+ }
+
+ return manager;
+ }
+ }
+ }
+}
Added: branches/bgarret/src/Source.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/Source.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,195 @@
+// Source.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using System.Collections.Generic;
+using Gtk;
+using Gdk;
+
+namespace Hipo
+{
+ public delegate void SourceDeletedEventHandler (object source);
+
+ public interface ISource
+ {
+ event SourceDeletedEventHandler Deleted;
+
+ // name displayed in the source list
+ string Name {get; set;}
+
+ // widget providing a view of the source (goes in the right panel)
+ Widget View {get;}
+
+ // search entry filtering tracks, photos, etc
+ Entry SearchEntry {get;}
+
+ // menu shown when right clicked in the source list
+ Menu Menu {get;}
+
+ // source type
+ SourceType Type {get;}
+
+ // source icon
+ Pixbuf Icon {get;}
+
+ bool Selected {get; set;}
+
+ // source item count
+ int Count {get;}
+
+ // source id
+ int Id {get;}
+
+ // source parent
+ SourceType Parent {get;}
+ }
+
+ public abstract class SourceBase : ISource
+ {
+ private static int idCounter = 0;
+ private int id;
+ private string name;
+ private Viewport view;
+ private Entry searchEntry;
+ private Menu menu;
+ private SourceType type;
+ private Pixbuf icon;
+ private int count;
+ private SourceType parent;
+ private bool selected;
+
+ public virtual event SourceDeletedEventHandler Deleted;
+
+ public SourceBase ()
+ {
+ id = idCounter;
+ idCounter++;
+
+ // initialize everything with dummy values
+ view = new Viewport ();
+ searchEntry = new Entry ();
+ searchEntry.Sensitive = false;
+ menu = new Menu ();
+ type = SourceType.None;
+ selected = false;
+ count = 0;
+ name = "Default name, override me";
+ }
+
+ public virtual string Name
+ {
+ get {
+ return name;
+ }
+
+ set {
+ name = value;
+ }
+ }
+
+ public virtual Widget View
+ {
+ get {
+ return view;
+ }
+ }
+
+ public virtual Entry SearchEntry
+ {
+ get {
+ return searchEntry;
+ }
+ }
+
+ public virtual Menu Menu
+ {
+ get {
+ return menu;
+ }
+ }
+
+ public virtual SourceType Type
+ {
+ get {
+ return type;
+ }
+
+ protected set {
+ type = value;
+ }
+ }
+
+ public virtual Pixbuf Icon
+ {
+ get {
+ return icon;
+ }
+
+ protected set {
+ icon = value;
+ }
+ }
+
+ public virtual SourceType Parent
+ {
+ get {
+ return parent;
+ }
+
+ protected set {
+ parent = value;
+ }
+ }
+
+ public virtual bool Selected
+ {
+ get {
+ return selected;
+ }
+
+ set {
+ selected = value;
+ }
+ }
+
+ public virtual int Count
+ {
+ get {
+ return count;
+ }
+ }
+
+ public int Id
+ {
+ get {
+ return id;
+ }
+ }
+ }
+
+ public enum SourceType
+ {
+ None,
+ Device,
+ Tracks,
+ Playlist,
+ SmartPlaylist
+ }
+}
Added: branches/bgarret/src/SourceList.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/SourceList.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,440 @@
+// SourceList.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using System.Collections.Generic;
+using Gtk;
+using IPod;
+
+namespace Hipo
+{
+ public class SourceList
+ {
+ private static SourceList instance = null;
+
+ private TreeView view;
+ private TreeStore store;
+ private Menu menu;
+ private List<ISource> sources;
+ private ISource selectedSource;
+
+ private static TargetEntry [] dest_entries = {
+ new TargetEntry ("application/x-hipo", 0, 0)
+ };
+
+ public event SelectionChangedEventHandler SelectionChanged;
+ public delegate void SelectionChangedEventHandler (object source, SelectionChangedArgs e);
+
+ public class SelectionChangedArgs : EventArgs
+ {
+ ISource source;
+
+ public SelectionChangedArgs (ISource source)
+ {
+ this.source = source;
+ }
+
+ public ISource Source
+ {
+ get {
+ return source;
+ }
+ }
+ }
+
+ private SourceList ()
+ {
+ // initialize playlist list
+
+ sources = new List<ISource>();
+
+ // create the columns, treeview, etc
+
+ view = new TreeView ();
+ view.HeadersVisible = false;
+
+ CellRendererPixbuf pixbufCell = new CellRendererPixbuf ();
+ TreeViewColumn column = new TreeViewColumn ();
+ column.PackStart (pixbufCell, true);
+
+ TreeCellDataFunc iconCellDataFunc = new TreeCellDataFunc (IconCellDataFunc);
+ column.SetCellDataFunc (pixbufCell, iconCellDataFunc);
+
+ column.Expand = false;
+ column.Resizable = true;
+ view.AppendColumn (column);
+
+
+ EditableCellRenderer textCell = new EditableCellRenderer ();
+ textCell.Edited += OnSourceEdit;
+ textCell.Column = Column.Name;
+
+ column = new TreeViewColumn ();
+ column.PackStart (textCell, true);
+
+ TreeCellDataFunc textCellDataFunc = new TreeCellDataFunc (TextCellDataFunc);
+ column.SetCellDataFunc (textCell, textCellDataFunc);
+
+ column.Expand = true;
+ view.AppendColumn (column);
+
+
+ CellRendererText countCell = new CellRendererText ();
+ column = new TreeViewColumn ();
+ column.PackStart (countCell, true);
+
+ TreeCellDataFunc countCellDataFunc = new TreeCellDataFunc (CountCellDataFunc);
+ column.SetCellDataFunc (countCell, countCellDataFunc);
+
+ column.Expand = false;
+ view.AppendColumn (column);
+
+ // create the store
+ store = new TreeStore (typeof (ISource));
+
+ // bind store and view
+ view.Model = store;
+
+ // enable drag and drop
+ view.EnableModelDragDest (dest_entries, Gdk.DragAction.Copy);
+ view.DragDataReceived += OnDragDataReceived;
+
+ // hook up delegates
+ view.Selection.Changed += OnSelectionChanged;
+
+ // hook up popup menu handlers
+ view.KeyPressEvent += OnKeyPress;
+ view.ButtonPressEvent += OnButtonPress;
+ }
+
+ private void TextCellDataFunc (TreeViewColumn column, CellRenderer renderer,
+ TreeModel model, TreeIter iter)
+ {
+ ISource source = (ISource)model.GetValue (iter, 0);
+ EditableCellRenderer cell = (EditableCellRenderer)renderer;
+
+ switch (cell.Column)
+ {
+ case Column.Name:
+ cell.Text = source.Name;
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void IconCellDataFunc (TreeViewColumn column, CellRenderer renderer,
+ TreeModel model, TreeIter iter)
+ {
+ ISource source = (ISource)model.GetValue (iter, 0);
+ CellRendererPixbuf cell = (CellRendererPixbuf)renderer;
+
+ cell.Pixbuf = source.Icon;
+ }
+
+ private void CountCellDataFunc (TreeViewColumn column, CellRenderer renderer,
+ TreeModel model, TreeIter iter)
+ {
+ ISource source = (ISource)model.GetValue (iter, 0);
+ CellRendererText cell = (CellRendererText)renderer;
+
+ cell.Foreground = "grey";
+
+ if (source.Count < 1)
+ cell.Text = "";
+ else
+ cell.Text = "(" + source.Count + ")";
+ }
+
+ public Widget View
+ {
+ get {
+ return (Widget) view;
+ }
+ }
+
+ public ISource SelectedSource
+ {
+ get {
+ return selectedSource;
+ }
+
+ set {
+ if (value != null)
+ Tools.Log (this, "Selecting source {0}", value.Name);
+ else
+ Tools.Log (this, "No source selected");
+
+ if (selectedSource != null)
+ selectedSource.Selected = false;
+
+ selectedSource = value;
+
+ if (selectedSource != null)
+ {
+ selectedSource.Selected = true;
+
+ store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter) {
+
+ ISource source = (ISource)store.GetValue (iter, 0);
+
+ if (source.Id == selectedSource.Id)
+ {
+ view.Selection.SelectIter (iter);
+ return true;
+ }
+ else
+ return false;
+ });
+
+ if (SelectionChanged != null)
+ {
+ SelectionChanged (this, new SelectionChangedArgs (selectedSource));
+ Tools.Log (this, "Source {0} selected", selectedSource.Name);
+ }
+ }
+ else
+ {
+ if (SelectionChanged != null)
+ {
+ SelectionChanged (this, new SelectionChangedArgs (null));
+ Tools.Log (this, "No source selected");
+ }
+ }
+ }
+ }
+
+ public DeviceSource Device
+ {
+ get {
+ DeviceSource device = (DeviceSource)sources.Find (delegate (ISource source) {
+ if (source.Type == SourceType.Device)
+ return true;
+ else
+ return false;
+ });
+
+ return device;
+ }
+ }
+
+ public TracksSource Tracks
+ {
+ get {
+ TracksSource tracks = (TracksSource)sources.Find (delegate (ISource source) {
+ if (source.Type == SourceType.Tracks)
+ return true;
+ else
+ return false;
+ });
+
+ return tracks;
+ }
+ }
+
+ public List<ISource> Playlists
+ {
+ get {
+ return sources.FindAll (delegate (ISource source) {
+ if (source.Type == SourceType.Playlist)
+ return true;
+ else
+ return false;
+ });
+ }
+ }
+
+ public Menu Menu
+ {
+ get {
+ return menu;
+ }
+ }
+
+ public static SourceList Instance {
+
+ get {
+ if (instance == null)
+ instance = new SourceList ();
+
+ return instance;
+ }
+ }
+
+ public void Add (ISource source)
+ {
+ sources.Add (source);
+ source.Deleted += OnSourceDeleted;
+
+ if (source.Parent == SourceType.None)
+ store.AppendValues (source);
+ else
+ {
+ store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter) {
+
+ ISource s = (ISource)model.GetValue (iter, 0);
+
+ if (s.Type == source.Parent)
+ {
+ store.AppendValues (iter, source);
+ return true;
+ }
+ else
+ return false;
+ });
+ }
+
+ Tools.Log (this, "Added source {0} with id {1} to the list", source.Name, source.Id);
+ }
+
+ public void RefreshView ()
+ {
+ view.QueueDraw ();
+ }
+
+ public void Clear ()
+ {
+ this.store.Clear ();
+ this.sources.Clear ();
+ }
+
+ public void ExpandAll ()
+ {
+ view.ExpandAll ();
+ }
+
+ private void OnSelectionChanged (object o, EventArgs args)
+ {
+ TreeIter iter;
+ TreeModel model;
+
+ if (((TreeSelection)o).GetSelected (out model, out iter))
+ {
+ ISource source = (ISource)model.GetValue (iter, 0);
+
+ this.SelectedSource = source;
+ }
+ }
+
+ [GLib.ConnectBefore]
+ private void OnButtonPress (object o, ButtonPressEventArgs args)
+ {
+ // if right click then show the menu
+ switch (args.Event.Button)
+ {
+ case 3:
+ Tools.Log (this, "Ooooh, right click");
+ PopupMenu (args.Event);
+ args.RetVal = true;
+ break;
+ }
+ }
+
+ private void OnKeyPress (object o, KeyPressEventArgs args)
+ {
+ switch (args.Event.Key)
+ {
+ case Gdk.Key.Menu:
+ Tools.Log (this, "Ooooh, menu button");
+ PopupMenu (args.Event);
+ args.RetVal = true;
+ break;
+ }
+ }
+
+ private void PopupMenu (Gdk.Event ev)
+ {
+ // build the menu and show it
+ Menu menu = selectedSource.Menu;
+
+ if (menu != null)
+ menu.Popup (null, null, null,
+ ((ev != null) && ev.Type == Gdk.EventType.ButtonPress) ? ((Gdk.EventButton)ev).Button : 0,
+ Gdk.EventHelper.GetTime (ev));
+ }
+
+ private void OnSourceEdit (object o, EditedArgs args)
+ {
+ TreeIter iter = TreeIter.Zero;
+
+ if (!store.GetIter (out iter, new TreePath (args.Path)))
+ return;
+
+ ISource source = (ISource)store.GetValue (iter, 0);
+
+ source.Name = args.NewText;
+ }
+
+ private void OnSourceDeleted (object o)
+ {
+ ISource source = (ISource)o;
+
+ sources.Remove (source);
+ store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter) {
+
+ ISource s = (ISource)model.GetValue (iter, 0);
+
+ if (source.Id == s.Id)
+ {
+ store.Remove (ref iter);
+ return true;
+ }
+ else
+ return false;
+ });
+ }
+
+ private void OnDragDataReceived (object o, DragDataReceivedArgs args)
+ {
+ TreePath treepath;
+ TreeViewDropPosition position;
+ TreeIter iter;
+
+ view.GetDestRowAtPos (args.X, args.Y, out treepath, out position);
+ store.GetIter (out iter, treepath);
+
+ try {
+ ISource source = (ISource) store.GetValue (iter, 0);
+
+ if (source.Type == SourceType.Playlist)
+ {
+ string data = System.Text.Encoding.UTF8.GetString (args.SelectionData.Data);
+
+ foreach (string d in data.Trim ().Split ('\n')) {
+
+ Track track = Tracks.GetTrack (long.Parse (d));
+
+ if (track == null)
+ return;
+
+ ((PlaylistSource)source).AddTrack (track);
+ }
+
+ Saviour.Instance.Save ();
+ }
+
+ Drag.Finish (args.Context, true, false, args.Time);
+
+ } catch (Exception e) {
+ Tools.Log (this, "{0}", e.Message);
+ }
+ }
+ }
+}
Added: branches/bgarret/src/Tools.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/Tools.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,60 @@
+// Tools.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+
+namespace Hipo
+{
+ public static class Tools
+ {
+ private static bool logEnabled;
+
+ public static 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 void Log (object o, string message)
+ {
+ if (logEnabled)
+ Console.WriteLine ("{0}: {1}", o, message);
+ }
+
+ public static void Log (object o, string format, params object[] args)
+ {
+ Log (o, String.Format (format, args));
+ }
+
+ public static bool LogEnabled
+ {
+ get {
+ return logEnabled;
+ }
+
+ set {
+ logEnabled = value;
+ }
+ }
+ }
+}
Added: branches/bgarret/src/TracksContainer.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/TracksContainer.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,782 @@
+// TracksContainer.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using Gtk;
+using Gdk;
+using Glade;
+using IPod;
+using Mono.Unix;
+
+namespace Hipo
+{
+ // this class contains the shared code for all sources containing tracks
+
+ public abstract class TracksContainer : SourceBase
+ {
+ private TreeView view;
+ protected ListStore store;
+ private TreeModelFilter store_filter;
+ private Entry search;
+ private SourceType type;
+ private bool selected;
+ private IList<Track> tracks;
+ private Column sortColumn = Column.Artist;
+
+ private static TargetEntry [] source_entries = {
+ new TargetEntry ("text/uri-list", 0, 0),
+ new TargetEntry ("application/x-hipo", 0, 0)
+ };
+
+ public TracksContainer ()
+ {
+ // create the columns, treeview, etc
+ view = new TreeView ();
+
+ TreeViewColumn column = BuildColumn (Column.Artist);
+ view.AppendColumn (column);
+
+ column = BuildColumn (Column.Album);
+ view.AppendColumn (column);
+
+ column = BuildColumn (Column.Title);
+ view.AppendColumn (column);
+
+ column = BuildColumn (Column.Genre);
+ view.AppendColumn (column);
+
+ view.HeadersVisible = true;
+ view.HeadersClickable = true;
+
+ // create the store
+ store = new ListStore (typeof (Track));
+ store.SetSortFunc (0, CompareFunc);
+
+ // bind store and view
+ view.Model = store;
+
+ // enable drag and drop
+ view.EnableModelDragSource (Gdk.ModifierType.Button1Mask,
+ source_entries, Gdk.DragAction.Copy);
+ view.DragDataGet += OnDragDataGet;
+
+ view.EnableModelDragDest (source_entries, Gdk.DragAction.Copy);
+ view.DragDataReceived += OnDragDataReceived;
+
+ view.Selection.Mode = SelectionMode.Multiple;
+
+ // hook up popup menu handlers
+ view.KeyPressEvent += OnKeyPress;
+ view.ButtonPressEvent += OnButtonPress;
+
+ // create the search entry and bind the changed event
+ search = new Entry ();
+ search.Changed += SearchFor;
+ store_filter = new TreeModelFilter (view.Model, null);
+ store_filter.VisibleFunc = SearchFilterFunc;
+
+ // create action entries
+ ActionEntry[] entries = {
+
+ new ActionEntry ("AddToPlaylist",
+ Gtk.Stock.Add, Catalog.GetString ("Add to Playlist..."),
+ null,
+ Catalog.GetString ("Add the track to a Playlist"),
+ null),
+ new ActionEntry ("Remove",
+ Gtk.Stock.Remove,
+ null,
+ null,
+ Catalog.GetString ("Remove the track from your iPod"),
+ null),
+ new ActionEntry ("TrackProperties",
+ Gtk.Stock.Properties,
+ Catalog.GetString ("Track Properties"),
+ null,
+ Catalog.GetString ("Track Properties"),
+ null),
+ };
+
+ // create the ui manager and the keyboard shortcuts
+ ActionGroup group = new ActionGroup ("TrackPopup");
+ group.Add (entries);
+
+ UIManager.Instance.InsertActionGroup (group, 0);
+ UIManager.Instance.AddUiFromResource ("trackpopup.xml");
+ }
+
+ TreeViewColumn BuildColumn (Column column)
+ {
+ EditableCellRenderer cell = new EditableCellRenderer ();
+ cell.Edited += OnTrackEdit;
+ cell.Column = column;
+
+ TreeViewColumn col = new TreeViewColumn ();
+ col.Title = Catalog.GetString (column.ToString ());
+ col.PackStart (cell, true);
+
+ TreeCellDataFunc textCellDataFunc = new TreeCellDataFunc (TextCellDataFunc);
+ col.SetCellDataFunc (cell, textCellDataFunc);
+
+ col.Clickable = true;
+ col.Clicked += delegate { sortColumn = column; };
+
+ col.Resizable = true;
+ col.Expand = false;
+
+ col.SortIndicator = true;
+ col.SortColumnId = 0;
+
+ col.Sizing = TreeViewColumnSizing.Fixed;
+
+ if (column == Column.Genre)
+ col.FixedWidth = 100;
+ else
+ col.FixedWidth = 200;
+
+ return col;
+ }
+
+ private void TextCellDataFunc (TreeViewColumn column, CellRenderer renderer,
+ TreeModel model, TreeIter iter)
+ {
+ Track track = (Track) model.GetValue (iter, 0);
+ EditableCellRenderer cell = (EditableCellRenderer)renderer;
+
+ switch (cell.Column)
+ {
+ case Column.Album:
+ cell.Text = track.Album;
+ break;
+ case Column.Artist:
+ cell.Text = track.Artist;
+ break;
+ case Column.Genre:
+ cell.Text = track.Genre;
+ break;
+ case Column.Title:
+ cell.Text = track.Title;
+ break;
+ default:
+ cell.Text = "";
+ break;
+ }
+ }
+
+ int CompareFunc (TreeModel model, TreeIter a, TreeIter b)
+ {
+ Track tracka = (Track)store.GetValue (a, 0);
+ Track trackb = (Track)store.GetValue (b, 0);
+
+ switch (sortColumn)
+ {
+ case Column.Album:
+ return String.Compare (tracka.Album, trackb.Album);
+ case Column.Artist:
+ return String.Compare (tracka.Artist, trackb.Artist);
+ case Column.Genre:
+ return String.Compare (tracka.Genre, trackb.Genre);
+ case Column.Title:
+ return String.Compare (tracka.Title, trackb.Title);
+ default:
+ return 0;
+ }
+ }
+
+ public override Widget View
+ {
+ get {
+ return (Widget)view;
+ }
+ }
+
+ public override Entry SearchEntry
+ {
+ get {
+ return search;
+ }
+ }
+
+ public override SourceType Type
+ {
+ get {
+ return type;
+ }
+
+ protected set {
+ this.type = value;
+ }
+ }
+
+ protected IList<Track> Tracks
+ {
+ set {
+ tracks = value;
+ store.Clear ();
+
+ foreach (Track track in tracks)
+ {
+ store.AppendValues (track);
+ }
+ }
+
+ get {
+ return tracks;
+ }
+ }
+
+ public override bool Selected
+ {
+ get {
+ return selected;
+ }
+
+ set {
+ this.selected = value;
+
+ if (this.selected)
+ AddEventHandlers ();
+ else
+ RemoveEventHandlers ();
+ }
+ }
+
+ // the two following methods have to be implemented
+ // to add tracks to the source when drag and dropped to.
+ public virtual bool AddTracks (string[] paths, bool save)
+ {
+ return true;
+ }
+
+ public virtual bool AddFolder (string[] dirs, bool save)
+ {
+ return true;
+ }
+
+ // implement this to make the right click menu delete item work
+ public virtual void RemoveTracks (List<Track> tracks)
+ {
+
+ }
+
+ [GLib.ConnectBefore]
+ private void OnButtonPress (object o, ButtonPressEventArgs args)
+ {
+ // if right click then show the menu
+ switch (args.Event.Button)
+ {
+ case 3:
+ Tools.Log (this, "Ooooh, right click");
+ PopupMenu (args.Event);
+ args.RetVal = true;
+ break;
+ }
+ }
+
+ private void OnKeyPress (object o, KeyPressEventArgs args)
+ {
+ switch (args.Event.Key)
+ {
+ case Gdk.Key.Menu:
+ Tools.Log (this, "Ooooh, menu button");
+ PopupMenu (args.Event);
+ args.RetVal = true;
+ break;
+ case Gdk.Key.Delete:
+ Tools.Log (this, "Ooooh, delete button");
+ RemoveTracks (GetSelectedTracks ());
+ args.RetVal = true;
+ break;
+ }
+ }
+
+ private void PopupMenu (Gdk.Event ev)
+ {
+ // build the menu and show it
+
+ if (view.Selection.CountSelectedRows () > 0)
+ {
+ Tools.Log (this, "Building and showing track popup menu");
+
+ Menu playlistMenu = new Menu ();
+ MenuItem addToPlaylistItem = (MenuItem)UIManager.Instance.GetWidget ("/ui/TrackPopup/AddToPlaylist");
+
+ foreach (ISource source in SourceList.Instance.Playlists)
+ {
+ PlaylistSource playlistSource = (PlaylistSource)source;
+ ImageMenuItem item = new ImageMenuItem (playlistSource.Name);
+ item.Image = new Gtk.Image (Gnome.IconTheme.Default.LoadIcon ("stock_playlist", 16, 0));
+ // eww, ugly
+ item.Activated += delegate {
+
+ AddToPlaylist (playlistSource);
+ };
+ playlistMenu.Append (item);
+ Tools.Log (this, "Added playlist {0} to the menu", playlistSource.Name);
+ }
+
+ addToPlaylistItem.Submenu = playlistMenu;
+
+ Menu menu = (Menu)Hipo.UIManager.Instance.GetWidget ("/ui/TrackPopup");
+
+ if (menu == null)
+ Console.WriteLine ("menu");
+
+ menu.ShowAll ();
+ playlistMenu.ShowAll ();
+
+ menu.Popup (null, null, null, ((ev != null) && ev.Type == Gdk.EventType.ButtonPress) ? ((Gdk.EventButton)ev).Button : 0,
+ Gdk.EventHelper.GetTime (ev));
+ }
+ }
+
+ private void AddToPlaylist (PlaylistSource playlistSource)
+ {
+ playlistSource.AddTracks (GetSelectedTracks ());
+ }
+
+ protected virtual void AddEventHandlers ()
+ {
+ Tools.Log (this, "Hooking {0} track menu event handlers", this.Name);
+
+ Menu menu = (Menu)UIManager.Instance.GetWidget ("/ui/TrackPopup");
+
+ // re-bind the menu items to the correct methods
+ foreach (MenuItem item in menu.Children)
+ {
+ switch (item.Name)
+ {
+ case "Remove":
+ item.Activated += OnRemove;
+ break;
+ case "TrackProperties":
+ item.Activated += OnTrackProperties;
+ break;
+ }
+ }
+ }
+
+ protected virtual void RemoveEventHandlers ()
+ {
+ Tools.Log (this, "Unhooking {0} track menu event handlers", this.Name);
+
+ Menu menu = (Menu)UIManager.Instance.GetWidget ("/ui/TrackPopup");
+
+ // re-bind the menu items to the correct methods
+ foreach (MenuItem item in menu.Children)
+ {
+ switch (item.Name)
+ {
+ case "Remove":
+ item.Activated -= OnRemove;
+ break;
+ case "TrackProperties":
+ item.Activated -= OnTrackProperties;
+ break;
+ }
+ }
+ }
+
+ private List<Track> GetSelectedTracks ()
+ {
+ TreeIter iter;
+ TreeModel model;
+
+ Array treePaths = view.Selection.GetSelectedRows (out model);
+ List<Track> selectedTracks = new List<Track>();
+
+ foreach (TreePath tPath in treePaths)
+ {
+ if (model.GetIter (out iter, tPath))
+ {
+ Track track = (Track)model.GetValue (iter, 0);
+ selectedTracks.Add (track);
+ }
+ }
+
+ return selectedTracks;
+ }
+
+ private void OnTrackEdit (object o, EditedArgs args)
+ {
+ TreeIter iter = TreeIter.Zero;
+ EditableCellRenderer cell = (EditableCellRenderer) o;
+ bool modified = false;
+
+ if (!store.GetIter (out iter, new TreePath (args.Path)))
+ return;
+
+ Track track = (Track)store.GetValue (iter, 0);
+
+ switch (cell.Column)
+ {
+ case Column.Artist:
+ if (args.NewText != track.Artist)
+ {
+ track.Artist = args.NewText;
+ modified = true;
+ }
+ break;
+ case Column.Album:
+ if (args.NewText != track.Album)
+ {
+ track.Album = args.NewText;
+ modified = true;
+ }
+ break;
+ case Column.Title:
+ if (args.NewText != track.Title)
+ {
+ track.Title = args.NewText;
+ modified = true;
+ }
+ break;
+ case Column.Genre:
+ if (args.NewText != track.Genre)
+ {
+ track.Genre = args.NewText;
+ modified = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (modified)
+ {
+ Saviour.Instance.Save ();
+ }
+ }
+
+ [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;
+ [Widget] private Gtk.Label titleLabel;
+ [Widget] private Gtk.Label numberLabel;
+
+ private void OnTrackProperties (object o, EventArgs args)
+ {
+ Glade.XML xml = new Glade.XML (null, "hipo.glade", "trackProperties", null);
+ xml.Autoconnect (this);
+
+ bool modified = false;
+ Gdk.Pixbuf newCover = null;
+ string artist = "";
+ string album = "";
+ string title = "";
+ string genre = "";
+ int trackNumber = 0;
+ Gdk.Pixbuf image = null;
+
+ List<Track> selectedTracks = GetSelectedTracks ();
+
+ if (selectedTracks.Count > 0)
+ {
+ foreach (Track track in selectedTracks)
+ {
+ /*
+ The values are filled in with the properties of the first track of the list.
+ A comparison is made with the subsequent tracks,
+ if the values are the same, nothing is changed,
+ if they are different, a blank value is put
+ */
+
+ if (selectedTracks.IndexOf (track) == 0)
+ {
+ artist = track.Artist;
+ album = track.Album;
+ title = track.Title;
+ genre = track.Genre;
+ trackNumber = track.TrackNumber;
+
+ foreach (ArtworkFormat format in SourceList.Instance.Device.LookupArtworkFormats (ArtworkUsage.Cover)) {
+
+ if (format != null) {
+ if (track.HasCoverArt (format))
+ image = ArtworkHelpers.ToPixbuf (format, track.GetCoverArt (format));
+ }
+ }
+
+ if (selectedTracks.Count == 1)
+ {
+ /* artist name and track title properties */
+ trackProperties.Title = String.Format (Catalog.GetString ("{0} {1} Properties"),
+ track.Artist, track.Title);
+ }
+ else
+ {
+ trackProperties.Title = Catalog.GetString ("Multiple tracks properties");
+ titleEntry.Hide ();
+ titleLabel.Hide ();
+ numberLabel.Hide ();
+ numberSpin.Hide ();
+ }
+ }
+ else
+ {
+ if (!artist.Equals("") && !artist.Equals (track.Artist))
+ artist = "";
+
+ if (!album.Equals("") && !album.Equals (track.Album))
+ album = "";
+
+ if (!title.Equals("") && !title.Equals (track.Title))
+ title = "";
+
+ if (!genre.Equals("") && !genre.Equals (track.Genre))
+ genre = "";
+
+ if ((trackNumber != 0) && (trackNumber != track.TrackNumber))
+ trackNumber = 0;
+
+ }
+ }
+
+ artistEntry.Text = artist;
+ albumEntry.Text = album;
+ titleEntry.Text = title;
+ genreEntry.Text = genre;
+ numberSpin.Value = trackNumber;
+ artwork.FromPixbuf = image;
+ }
+
+ 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 = new Gtk.Image ();
+
+ 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 != artist) {
+ modified = true;
+ foreach (Track track in selectedTracks)
+ {
+ track.Artist = artistEntry.Text;
+ }
+ }
+
+ if (albumEntry.Text != album) {
+ modified = true;
+ foreach (Track track in selectedTracks)
+ {
+ track.Album = albumEntry.Text;
+ }
+ }
+
+ if (titleEntry.Text != title) {
+ modified = true;
+ foreach (Track track in selectedTracks)
+ {
+ track.Title = titleEntry.Text;
+ }
+ }
+
+ if (genreEntry.Text != genre) {
+ modified = true;
+ foreach (Track track in selectedTracks)
+ {
+ track.Genre = genreEntry.Text;
+ }
+ }
+
+ if (numberSpin.Value != trackNumber) {
+ modified = true;
+ foreach (Track track in selectedTracks)
+ {
+ track.TrackNumber = (int) numberSpin.Value;
+ }
+ }
+
+ if (newCover != null) {
+
+ foreach (ArtworkFormat format in SourceList.Instance.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.
+
+ foreach (Track track in selectedTracks)
+ {
+ track.SetCoverArt (format, ArtworkHelpers.ToBytes (format, newCover));
+ }
+ }
+
+ modified = true;
+ }
+ }
+
+ if (modified)
+ Saviour.Instance.Save ();
+
+ trackProperties.Destroy ();
+ }
+
+ private void OnUpdatePreview (object o, EventArgs args)
+ {
+ FileChooser fileChooser = (FileChooser)o;
+
+ try {
+
+ if (fileChooser.PreviewFilename != null)
+ {
+ Gdk.Pixbuf cover = new Gdk.Pixbuf (fileChooser.PreviewFilename);
+
+ ((Gtk.Image)fileChooser.PreviewWidget).Pixbuf = cover.ScaleSimple (150, 150, Gdk.InterpType.Bilinear);
+
+ ((Gtk.Image)fileChooser.PreviewWidget).Show ();
+ }
+ } catch (Exception e) {
+
+ ((Gtk.Image)fileChooser.PreviewWidget).Hide ();
+ Console.WriteLine (e.Message);
+ }
+ }
+
+ private void OnRemove (object o, EventArgs args)
+ {
+ RemoveTracks (GetSelectedTracks ());
+ }
+
+ private void OnDragDataGet (object o, DragDataGetArgs args)
+ {
+ Atom[] targets = args.Context.Targets;
+ StringBuilder dragData = new StringBuilder ();
+
+ List<Track> selectedTracks = GetSelectedTracks ();
+
+ foreach (Track track in selectedTracks)
+ {
+ if (args.SelectionData.Target == "text/uri-list")
+ dragData.Append (track.FileName + "\r\n");
+ else
+ dragData.Append (track.Id + "\n");
+ }
+
+ args.SelectionData.Set (targets[0], 8,
+ System.Text.Encoding.UTF8.GetBytes (dragData.ToString()));
+ }
+
+ private void OnDragDataReceived (object o, DragDataReceivedArgs args)
+ {
+ try {
+
+ if ((Gtk.Drag.GetSourceWidget (args.Context) != view) &&
+ (args.SelectionData.Length >=0 && args.SelectionData.Format == 8))
+ {
+ string data = System.Text.Encoding.UTF8.GetString (args.SelectionData.Data);
+ bool trackAdded = false;
+
+ foreach (string ur in data.Trim ().Split ('\n'))
+ {
+ string formatUri = ur.Trim ();
+
+ Uri uri = new Uri (formatUri);
+
+ if (Directory.Exists (uri.LocalPath))
+ {
+ string[] tmp = { formatUri };
+ trackAdded |= AddFolder (tmp, false);
+ }
+ else if (File.Exists (uri.LocalPath))
+ {
+ string[] tmp = { formatUri };
+ trackAdded |= AddTracks (tmp, false);
+ }
+ }
+
+ if (trackAdded)
+ Saviour.Instance.Save ();
+
+ Gtk.Drag.Finish (args.Context, true, false, args.Time);
+ }
+ } catch (Exception e) {
+ Console.WriteLine (e.Message);
+ }
+ }
+
+ private bool SearchFilterFunc (TreeModel model, TreeIter iter)
+ {
+ if (search.Text.Trim().Length < 1)
+ return true;
+
+ bool ret = true;
+ Track track = (Track)model.GetValue (iter, 0);
+
+ try {
+ string search_term = search.Text.Trim().ToLower();
+ string artist = track.Artist.ToLower();
+ string album = track.Album.ToLower();
+ string title = track.Title.ToLower();
+ string genre = track.Genre.ToLower();
+ ret = ( artist.Contains(search_term) ||
+ album.Contains(search_term) ||
+ title.Contains(search_term) ||
+ genre.Contains(search_term)
+ );
+ } catch (Exception e) {
+ Console.WriteLine (e.Message);
+ }
+ return ret;
+ }
+
+ private void SearchFor (object o, EventArgs args)
+ {
+ view.Model = store_filter;
+ store_filter.Refilter();
+ }
+ }
+}
Added: branches/bgarret/src/TracksSource.cs
==============================================================================
--- (empty file)
+++ branches/bgarret/src/TracksSource.cs Thu Jan 31 21:38:51 2008
@@ -0,0 +1,263 @@
+// TracksSource.cs
+//
+// Copyright (C) 2008 Benoit Garret
+//
+// 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
+//
+//
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using Gtk;
+using Gdk;
+using IPod;
+using Mono.Unix;
+
+namespace Hipo
+{
+ public class TracksSource : TracksContainer
+ {
+ private TrackDatabase tracksDb;
+ private string name;
+
+ public TracksSource (TrackDatabase db) : base ()
+ {
+ this.tracksDb = db;
+ Tracks = db.Tracks;
+
+ this.name = Catalog.GetString ("Music");
+ this.Icon = Gnome.IconTheme.Default.LoadIcon ("stock_music-library", 16, 0);
+
+ this.Type = Hipo.SourceType.Tracks;
+ this.Parent = SourceType.Device;
+ }
+
+ public override string Name
+ {
+ get {
+ return name;
+ }
+
+ set {
+
+ }
+ }
+
+ public override Menu Menu
+ {
+ get {
+ return null;
+ }
+ }
+
+ public override int Count
+ {
+ get {
+ return tracksDb.Tracks.Count;
+ }
+ }
+
+ public Playlist CreatePlaylist (string name)
+ {
+ Playlist playlist = null;
+
+ if ((playlist = tracksDb.CreatePlaylist (name)) != null)
+ {
+ Saviour.Instance.Save ();
+ }
+
+ return playlist;
+ }
+
+ public void DeletePlaylist (Playlist playlist)
+ {
+ tracksDb.RemovePlaylist (playlist);
+ }
+
+ public bool AddTrack (string path)
+ {
+ Track track = AddTrack (path, true);
+
+ if (track != null)
+ Saviour.Instance.Save ();
+
+ if (track == null)
+ return false;
+ else
+ return true;
+ }
+
+ public override bool AddTracks (string[] uris, bool save)
+ {
+ bool trackAdded = false;
+
+ foreach (string uri in uris)
+ {
+ Tools.Log (this, "Adding uri {0}", uri);
+
+ Uri u = new Uri (uri);
+ Track track = AddTrack (u.LocalPath, false);
+
+ if (track == null)
+ trackAdded |= false;
+ else
+ {
+ trackAdded |= true;
+ }
+ }
+
+ if (trackAdded && save)
+ Saviour.Instance.Save ();
+
+ return trackAdded;
+ }
+
+ public Track AddTrack (string path, bool save)
+ {
+ Track track = null;
+ string ext = Path.GetExtension (path);
+
+ if ((ext.ToLower () == ".mp3") || (ext.ToLower () == ".mp4") ||
+ (ext.ToLower () == ".m4a"))
+ {
+ TagLib.File file = TagLib.File.Create (path);
+
+ track = tracksDb.CreateTrack ();
+
+ if ((file.Tag.FirstArtist == null) || (file.Tag.FirstArtist == String.Empty))
+ track.Artist = "Unknown";
+ else
+ track.Artist = file.Tag.FirstArtist;
+
+ if ((file.Tag.Title == null) || (file.Tag.Title == String.Empty))
+ track.Title = "Unknown";
+ else
+ track.Title = file.Tag.Title;
+
+ if ((file.Tag.Album == null) || (file.Tag.Album == String.Empty))
+ track.Album = "Unknown";
+ else
+ track.Album = file.Tag.Album;
+
+ if ((file.Tag.FirstGenre == null) || (file.Tag.FirstGenre == String.Empty))
+ track.Genre = "Unknown";
+ else
+ track.Genre = file.Tag.FirstGenre;
+
+ track.FileName = path;
+ track.Duration = file.Properties.Duration;
+ track.TrackNumber = (int) file.Tag.Track;
+
+ store.AppendValues (track);
+
+ Tools.Log (this, "Added {0}", path);
+ }
+
+ if (save && (track != null))
+ Saviour.Instance.Save ();
+
+ return track;
+ }
+
+ public override bool AddFolder (string[] dirs, bool save)
+ {
+ // returns true if at least one track has been added
+ bool trackAdded = false;
+
+ foreach (string path in dirs)
+ {
+ if (path == null)
+ return false;
+
+ Tools.Log (this, "Adding uri {0}", path);
+
+ System.Uri uri = new System.Uri (path);
+
+ UnixDirectoryInfo info = new UnixDirectoryInfo (uri.LocalPath);
+ foreach (UnixFileSystemInfo file in info.GetFileSystemEntries ())
+ {
+ // |= gives true as soon as one of the arguments is true
+ if (!file.IsDirectory)
+ {
+ Track track = AddTrack (file.FullName, false);
+ if (track == null)
+ trackAdded |= false;
+ else
+ trackAdded |= true;
+ }
+ else
+ {
+ string[] tmp = { file.FullName };
+ trackAdded |= AddFolder (tmp, false);
+ }
+ }
+ }
+
+ if (trackAdded && save)
+ Saviour.Instance.Save ();
+
+ return trackAdded;
+ }
+
+ public void RemoveTrack (Track track)
+ {
+ RemoveTrack (track, true);
+ }
+
+ public override void RemoveTracks (List<Track> tracks)
+ {
+ Tools.Log (this, "Removing {0} tracks from the database", tracks.Count);
+
+ foreach (Track track in tracks)
+ {
+ RemoveTrack (track, false);
+ }
+
+ Saviour.Instance.Save ();
+ }
+
+ private void RemoveTrack (Track track, bool save)
+ {
+ tracksDb.RemoveTrack (track);
+ store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter) {
+
+ Track t = (Track)model.GetValue (iter, 0);
+
+ if (track.Id == t.Id)
+ {
+ store.Remove (ref iter);
+ return true;
+ }
+ else
+ return false;
+ });
+
+ if (save)
+ Saviour.Instance.Save ();
+ }
+
+ public Track GetTrack (long id)
+ {
+ foreach (Track track in Tracks)
+ {
+ if (track.Id == id)
+ return track;
+ }
+
+ return null;
+ }
+ }
+}
Added: branches/bgarret/src/devicepopup.xml
==============================================================================
--- (empty file)
+++ branches/bgarret/src/devicepopup.xml Thu Jan 31 21:38:51 2008
@@ -0,0 +1,6 @@
+<ui>
+ <popup name="DevicePopup">
+ <menuitem action="RenameDevice" />
+ </popup>
+</ui>
+
Modified: branches/bgarret/src/errordialog.glade
==============================================================================
--- branches/bgarret/src/errordialog.glade (original)
+++ branches/bgarret/src/errordialog.glade Thu Jan 31 21:38:51 2008
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.0 on Sun Dec 2 21:04:20 2007 -->
+<!--Generated with glade3 3.4.0 on Mon Jan 28 21:16:26 2008 -->
<glade-interface>
<widget class="GtkDialog" id="errorDialog">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@@ -55,6 +55,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">5</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
Modified: branches/bgarret/src/hipo.glade
==============================================================================
--- branches/bgarret/src/hipo.glade (original)
+++ branches/bgarret/src/hipo.glade Thu Jan 31 21:38:51 2008
@@ -1,1185 +1,598 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
<glade-interface>
-
-<widget class="GtkWindow" id="hipoWindow">
- <property name="visible">True</property>
- <property name="title" translatable="yes" context="yes">Hipo iPod Management Tool</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="default_width">800</property>
- <property name="default_height">600</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHPaned" id="hpaned1">
- <property name="border_width">5</property>
- <property name="visible">True</property>
- <property name="position">200</property>
-
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">5</property>
-
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes" context="yes"><b>Music Library</b></property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">True</property>
- <property name="selectable">False</property>
- <property name="xalign">0.0500000007451</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">hpaned1</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="plistView">
- <property name="visible">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">False</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkProgressBar" id="ipodCapacityBar">
- <property name="visible">True</property>
- <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
- <property name="fraction">0</property>
- <property name="pulse_step">0.10000000149</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="shrink">True</property>
- <property name="resize">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox2">
- <property name="border_width">5</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">5</property>
-
- <child>
- <widget class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes" context="yes">_Search:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">filterEntry</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="filterEntry">
- <property name="width_request">255</property>
- <property name="visible">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">â</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow3">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="tracksView">
- <property name="visible">True</property>
- <property name="headers_visible">True</property>
- <property name="rules_hint">True</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="shrink">True</property>
- <property name="resize">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkStatusbar" id="statusbar1">
- <property name="visible">True</property>
- <property name="has_resize_grip">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkDialog" id="trackProperties">
- <property name="visible">True</property>
- <property name="title" translatable="yes"></property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
- <property name="has_separator">True</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area1">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
-
- <child>
- <widget class="GtkButton" id="cancelbutton1">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-close</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">-7</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="okbutton1">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-save</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">-5</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table1">
- <property name="border_width">5</property>
- <property name="visible">True</property>
- <property name="n_rows">6</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">5</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>_Artist:</b></property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">artistEntry</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>_Album:</b></property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">albumEntry</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="titleLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>_Title:</b></property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">titleEntry</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label7">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>_Genre:</b></property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">genreEntry</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="numberLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>_Track Number:</b></property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">numberSpin</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label9">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>_Artwork:</b></property>
- <property name="use_underline">True</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="artistEntry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">â</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="albumEntry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">â</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="titleEntry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">â</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="genreEntry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">â</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkSpinButton" id="numberSpin">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="climb_rate">1</property>
- <property name="digits">0</property>
- <property name="numeric">True</property>
- <property name="update_policy">GTK_UPDATE_ALWAYS</property>
- <property name="snap_to_ticks">False</property>
- <property name="wrap">False</property>
- <property name="adjustment">0 0 1000 1 10 10</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox4">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">5</property>
-
- <child>
- <widget class="GtkImage" id="artwork">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="openArtwork">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-open</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkDialog" id="deviceProperties">
- <property name="visible">True</property>
- <property name="title" translatable="yes"></property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
- <property name="has_separator">True</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area2">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
-
- <child>
- <widget class="GtkButton" id="cancelbutton2">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-close</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">-7</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="okbutton2">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-save</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">-5</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table2">
- <property name="border_width">5</property>
- <property name="visible">True</property>
- <property name="n_rows">8</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">5</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Name:</b></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Model:</b></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Serial Number:</b></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="nameEntry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">â</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="modelLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="serialLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label15">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Mount Point:</b></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label16">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Space Used:</b></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="capacityLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="mountLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="spaceLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label14">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Capacity:</b></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label17">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Generation:</b></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="generationLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label18">
- <property name="visible">True</property>
- <property name="label" translatable="yes"><b>Firmware Version:</b></property>
- <property name="use_underline">False</property>
- <property name="use_markup">True</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="firmwareLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
+ <widget class="GtkWindow" id="hipoWindow">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes" context="yes">Hipo iPod Management Tool</property>
+ <property name="default_width">800</property>
+ <property name="default_height">600</property>
+ <child>
+ <widget class="GtkVBox" id="menuBar">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHPaned" id="hpaned1">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="position">200</property>
+ <child>
+ <widget class="GtkVBox" id="sourceListBox">
+ <property name="visible">True</property>
+ <property name="spacing">5</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="sourceListScroll">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="searchBox">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="spacing">5</property>
+ <child>
+ <widget class="GtkLabel" id="searchLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes" context="yes">_Search:</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="defaultSearchEntry">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="sourceScroll">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+ <child>
+ <widget class="GtkViewport" id="defaultSourceWidget">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkLabel" id="sourceLabel">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes" context="yes">No device found.</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkStatusbar" id="statusbar1">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkDialog" id="trackProperties">
+ <property name="visible">True</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="n_rows">6</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">5</property>
+ <child>
+ <widget class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <property name="spacing">5</property>
+ <child>
+ <widget class="GtkImage" id="artwork">
+ <property name="visible">True</property>
+ <property name="stock">gtk-missing-image</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="openArtwork">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" context="yes">gtk-open</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="numberSpin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 1000 1 10 10</property>
+ <property name="climb_rate">1</property>
+ <property name="numeric">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="genreEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="titleEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="albumEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="artistEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>_Artwork:</b></property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="numberLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>_Track Number:</b></property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">numberSpin</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>_Genre:</b></property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">genreEntry</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="titleLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>_Title:</b></property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">titleEntry</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>_Album:</b></property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">albumEntry</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>_Artist:</b></property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">artistEntry</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="cancelbutton1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label" context="yes">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">-7</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="okbutton1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label" context="yes">gtk-save</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="deviceProperties">
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <widget class="GtkViewport" id="deviceViewport">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkTable" id="deviceTable">
+ <property name="visible">True</property>
+ <property name="border_width">10</property>
+ <property name="n_rows">7</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">5</property>
+ <child>
+ <widget class="GtkLabel" id="firmwareLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>Firmware Version:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="generationLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>Generation:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>Capacity:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="spaceLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="mountLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="capacityLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>Space Used:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>Mount Point:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="serialLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="modelLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>Serial Number:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes"><b>Model:</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
Added: branches/bgarret/src/menubar.xml
==============================================================================
--- (empty file)
+++ branches/bgarret/src/menubar.xml Thu Jan 31 21:38:51 2008
@@ -0,0 +1,22 @@
+<ui>
+ <menubar name="HipoMenu">
+ <menu name="File" action="FileMenu">
+ <menuitem name="AddFile" action="AddFile" />
+ <menuitem name="AddFolder" action="AddFolder" />
+ <separator />
+ <menuitem name="NewPlaylist" action="NewPlaylist" />
+ <separator />
+ <menuitem name="Eject" action="Eject" />
+ <menuitem name="Quit" action="Quit" />
+ </menu>
+ <menu name="Edit" action="EditMenu">
+ <menuitem name="Preferences" action="Preferences" />
+ </menu>
+ <menu name="Help" action="HelpMenu">
+ <menuitem name="Contents" action="Help" />
+ <separator />
+ <menuitem name="About" action="About" />
+ </menu>
+ </menubar>
+</ui>
+
Added: branches/bgarret/src/playlistpopup.xml
==============================================================================
--- (empty file)
+++ branches/bgarret/src/playlistpopup.xml Thu Jan 31 21:38:51 2008
@@ -0,0 +1,6 @@
+<ui>
+ <popup name="PlaylistPopup">
+ <menuitem action="RenamePlaylist" />
+ <menuitem action="DeletePlaylist" />
+ </popup>
+</ui>
Added: branches/bgarret/src/trackpopup.xml
==============================================================================
--- (empty file)
+++ branches/bgarret/src/trackpopup.xml Thu Jan 31 21:38:51 2008
@@ -0,0 +1,7 @@
+<ui>
+ <popup name="TrackPopup">
+ <menuitem action="AddToPlaylist" />
+ <menuitem action="Remove" />
+ <menuitem action="TrackProperties" />
+ </popup>
+</ui>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]