banshee r4432 - in trunk/banshee: . src/Clients src/Clients/Muinshee src/Clients/Muinshee/Muinshee



Author: gburt
Date: Tue Aug 26 19:30:15 2008
New Revision: 4432
URL: http://svn.gnome.org/viewvc/banshee?rev=4432&view=rev

Log:
2008-08-26  Gabriel Burt  <gabriel burt gmail com>

	* src/Clients/Clients.mds:
	* src/Clients/Makefile.am:
	* src/Clients/Muinshee/Makefile.am:
	* src/Clients/Muinshee/Muinshee.mdp:
	* src/Clients/Muinshee/Muinshee/PlayerInterface.cs:
	* src/Clients/Muinshee/Muinshee/ViewContainer.cs:
	* src/Clients/Muinshee/Muinshee/Client.cs:
	* configure.ac: Groundwork for a new client: Muinshee



Added:
   trunk/banshee/src/Clients/Muinshee/   (props changed)
   trunk/banshee/src/Clients/Muinshee/Makefile.am
   trunk/banshee/src/Clients/Muinshee/Muinshee/
   trunk/banshee/src/Clients/Muinshee/Muinshee.mdp
   trunk/banshee/src/Clients/Muinshee/Muinshee/Client.cs
   trunk/banshee/src/Clients/Muinshee/Muinshee/PlayerInterface.cs
   trunk/banshee/src/Clients/Muinshee/Muinshee/ViewContainer.cs
Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/configure.ac
   trunk/banshee/src/Clients/Clients.mds
   trunk/banshee/src/Clients/Makefile.am

Modified: trunk/banshee/configure.ac
==============================================================================
--- trunk/banshee/configure.ac	(original)
+++ trunk/banshee/configure.ac	Tue Aug 26 19:30:15 2008
@@ -134,6 +134,7 @@
 src/Clients/Makefile
 src/Clients/banshee-1
 src/Clients/Halie/Makefile
+src/Clients/Muinshee/Makefile
 src/Clients/Nereid/Makefile
 
 src/Core/Makefile

Modified: trunk/banshee/src/Clients/Clients.mds
==============================================================================
--- trunk/banshee/src/Clients/Clients.mds	(original)
+++ trunk/banshee/src/Clients/Clients.mds	Tue Aug 26 19:30:15 2008
@@ -1,16 +1,19 @@
 <Combine name="Clients" fileversion="2.0">
   <Configurations active="Debug">
     <Configuration name="Debug" ctype="CombineConfiguration">
+      <Entry build="True" name="Muinshee" configuration="Debug" />
       <Entry build="True" name="Nereid" configuration="Debug" />
       <Entry build="True" name="Halie" configuration="Debug" />
     </Configuration>
   </Configurations>
   <StartMode startupentry="Nereid" single="True">
+    <Execute type="None" entry="Muinshee" />
     <Execute type="None" entry="Nereid" />
     <Execute type="None" entry="Halie" />
   </StartMode>
   <Entries>
+    <Entry filename="Muinshee/Muinshee.mdp" />
     <Entry filename="Nereid/Nereid.mdp" />
     <Entry filename="Halie/Halie.mdp" />
   </Entries>
-</Combine>
\ No newline at end of file
+</Combine>

Modified: trunk/banshee/src/Clients/Makefile.am
==============================================================================
--- trunk/banshee/src/Clients/Makefile.am	(original)
+++ trunk/banshee/src/Clients/Makefile.am	Tue Aug 26 19:30:15 2008
@@ -1,5 +1,6 @@
 SUBDIRS = \
 	Halie \
+	Muinshee \
 	Nereid
 
 bin_SCRIPTS = banshee-1

Added: trunk/banshee/src/Clients/Muinshee/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Clients/Muinshee/Makefile.am	Tue Aug 26 19:30:15 2008
@@ -0,0 +1,10 @@
+ASSEMBLY = Muinshee
+TARGET = exe
+LINK = $(REF_NEREID)
+SOURCES =  \
+	Muinshee/Client.cs \
+	Muinshee/PlayerInterface.cs \
+	Muinshee/ViewContainer.cs
+
+include $(top_srcdir)/build/build.mk
+

Added: trunk/banshee/src/Clients/Muinshee/Muinshee.mdp
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Clients/Muinshee/Muinshee.mdp	Tue Aug 26 19:30:15 2008
@@ -0,0 +1,35 @@
+<Project name="Muinshee" fileversion="2.0" language="C#" UseParentDirectoryAsNamespace="True" clr-version="Net_2_0" ctype="DotNetProject">
+  <Configurations active="Debug">
+    <Configuration name="Debug" ctype="DotNetProjectConfiguration">
+      <Output directory="../../../bin" assemblyKeyFile="." assembly="Muinshee" />
+      <Build debugmode="True" target="Exe" />
+      <Execution runwithwarnings="True" externalconsole="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
+      <CodeGeneration compiler="Mcs" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" generatexmldocumentation="False" win32Icon="." ctype="CSharpCompilerParameters" />
+    </Configuration>
+  </Configurations>
+  <Contents>
+    <File name="Muinshee/PlayerInterface.cs" subtype="Code" buildaction="Compile" />
+    <File name="Muinshee/ViewContainer.cs" subtype="Code" buildaction="Compile" />
+    <File name="Muinshee/Client.cs" subtype="Code" buildaction="Compile" />
+  </Contents>
+  <References>
+    <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.10.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+    <ProjectReference type="Project" localcopy="False" refto="Banshee.ThickClient" />
+    <ProjectReference type="Project" localcopy="False" refto="Banshee.Services" />
+    <ProjectReference type="Project" localcopy="False" refto="Banshee.Core" />
+    <ProjectReference type="Project" localcopy="False" refto="Banshee.Widgets" />
+    <ProjectReference type="Project" localcopy="False" refto="Hyena" />
+    <ProjectReference type="Project" localcopy="False" refto="Hyena.Gui" />
+    <ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.10.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+  </References>
+  <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="Makefile.am" ExecuteTargetName="run">
+    <BuildFilesVar Sync="True" Name="SOURCES" />
+    <DeployFilesVar />
+    <ResourcesVar />
+    <OthersVar />
+    <GacRefVar />
+    <AsmRefVar />
+    <ProjectRefVar />
+  </MonoDevelop.Autotools.MakefileInfo>
+</Project>

Added: trunk/banshee/src/Clients/Muinshee/Muinshee/Client.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Clients/Muinshee/Muinshee/Client.cs	Tue Aug 26 19:30:15 2008
@@ -0,0 +1,212 @@
+//
+// Muinshee.cs
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2007-2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Reflection;
+using System.Collections.Generic;
+using Mono.Unix;
+
+using Hyena;
+using Hyena.CommandLine;
+
+using Banshee.Base;
+using Banshee.ServiceStack;
+
+namespace Muinshee
+{
+    public class Client : Banshee.Gui.GtkBaseClient
+    {
+        private static string user_gtkrc = Path.Combine (Paths.ApplicationData, "gtkrc"); 
+        public static void Main (string [] args)
+        {
+            if (CheckHelpVersion ()) {
+                return;
+            }
+        
+            // Check for single instance
+            DBusConnection.Connect ();
+            if (DBusConnection.InstanceAlreadyRunning) {
+                // Try running our friend Halie, the DBus command line client
+                AppDomain.CurrentDomain.ExecuteAssembly (Path.Combine (Path.GetDirectoryName (
+                    Assembly.GetEntryAssembly ().Location), "Halie.exe"));
+                Gdk.Global.InitCheck (ref args);
+                Gdk.Global.NotifyStartupComplete ();
+                return;
+            }
+                    
+            Hyena.Log.InformationFormat ("Running Banshee {0}", Application.Version);
+            
+            // This could go into GtkBaseClient, but it's probably something we
+            // should really only support at each client level
+            if (File.Exists (user_gtkrc) && !ApplicationContext.CommandLine.Contains ("no-gtkrc")) {
+                Gtk.Rc.AddDefaultFile (user_gtkrc);
+            } 
+            
+            // Ugly hack to avoid stupid themes that set this to 0, causing a huge
+            // bug when constructing the "add to playlist" popup menu (BGO #524706)
+            Gtk.Rc.ParseString ("gtk-menu-popup-delay = 225");
+
+            // Boot the client
+            Banshee.Gui.GtkBaseClient.Entry<Client> ();
+        }
+        
+        protected override void OnRegisterServices ()
+        {
+            // Register the main interface
+            ServiceManager.RegisterService<PlayerInterface> ();
+        }
+        
+        private static bool CheckHelpVersion ()
+        {
+            if (ApplicationContext.CommandLine.ContainsStart ("help")) {
+                ShowHelp ();
+                return true;
+            } else if (ApplicationContext.CommandLine.Contains ("version")) {
+                ShowVersion ();
+                return true;
+            }
+            
+            return false;
+        }
+        
+        private static void ShowHelp ()
+        {
+            Console.WriteLine ("Usage: {0} [options...] [files|URIs...]", "banshee-1");
+            Console.WriteLine ();
+            
+            Layout commands = new Layout (
+                new LayoutGroup ("help", Catalog.GetString ("Help Options"),
+                    new LayoutOption ("help", Catalog.GetString ("Show this help")),
+                    new LayoutOption ("help-playback", Catalog.GetString ("Show options for controlling playback")),
+                    new LayoutOption ("help-query-track", Catalog.GetString ("Show options for querying the playing track")),
+                    new LayoutOption ("help-query-player", Catalog.GetString ("Show options for querying the playing engine")),
+                    new LayoutOption ("help-ui", Catalog.GetString ("Show options for the user interface")),
+                    new LayoutOption ("help-debug", Catalog.GetString ("Show options for developers and debugging")),
+                    new LayoutOption ("help-all", Catalog.GetString ("Show all option groups")),
+                    new LayoutOption ("version", Catalog.GetString ("Show version information"))
+                ),
+                
+                new LayoutGroup ("playback", Catalog.GetString ("Playback Control Options"),
+                    new LayoutOption ("next", Catalog.GetString ("Play the next track, optionally restarting if the 'restart' value is set")),
+                    new LayoutOption ("previous", Catalog.GetString ("Play the previous track, optionally restarting if the 'restart value is set")),
+                    new LayoutOption ("play-enqueued", Catalog.GetString ("Automatically start playing any tracks enqueued on the command line")),
+                    new LayoutOption ("play", Catalog.GetString ("Start playback")),
+                    new LayoutOption ("pause", Catalog.GetString ("Pause playback")),
+                    new LayoutOption ("stop", Catalog.GetString ("Completely stop playback")),
+                    new LayoutOption ("stop-when-finished", Catalog.GetString (
+                        "Enable or disable playback stopping after the currently playing track (value should be either 'true' or 'false')")),
+                    new LayoutOption ("set-volume=LEVEL", Catalog.GetString ("Set the playback volume (0-100)")),
+                    new LayoutOption ("set-position=POS", Catalog.GetString ("Seek to a specific point (seconds, float)"))
+                ),
+                
+                new LayoutGroup ("query-player", Catalog.GetString ("Player Engine Query Options"),
+                    new LayoutOption ("query-current-state", Catalog.GetString ("Current player state")),
+                    new LayoutOption ("query-last-state", Catalog.GetString ("Last player state")),
+                    new LayoutOption ("query-can-pause", Catalog.GetString ("Query whether the player can be paused")),
+                    new LayoutOption ("query-can-seek", Catalog.GetString ("Query whether the player can seek")),
+                    new LayoutOption ("query-volume", Catalog.GetString ("Player volume")),
+                    new LayoutOption ("query-position", Catalog.GetString ("Player position in currently playing track"))
+                ),
+                
+                new LayoutGroup ("query-track", Catalog.GetString ("Playing Track Metadata Query Options"),
+                    new LayoutOption ("query-uri", Catalog.GetString ("URI")),
+                    new LayoutOption ("query-artist", Catalog.GetString ("Artist Name")),
+                    new LayoutOption ("query-album", Catalog.GetString ("Album Title")),
+                    new LayoutOption ("query-title", Catalog.GetString ("Track Title")),
+                    new LayoutOption ("query-duration", Catalog.GetString ("Duration")),
+                    new LayoutOption ("query-track-number", Catalog.GetString ("Track Number")),
+                    new LayoutOption ("query-track-count", Catalog.GetString ("Track Count")),
+                    new LayoutOption ("query-disc", Catalog.GetString ("Disc Number")),
+                    new LayoutOption ("query-year", Catalog.GetString ("Year")),
+                    new LayoutOption ("query-rating", Catalog.GetString ("Rating"))
+                ),
+                
+                new LayoutGroup ("ui", Catalog.GetString ("User Interface Options"),
+                    new LayoutOption ("show|--present", Catalog.GetString ("Present the user interface on the active workspace")),
+                    new LayoutOption ("hide", Catalog.GetString ("Hide the user interface")),
+                    new LayoutOption ("no-present", Catalog.GetString ("Do not present the user interface, regardless of any other options"))
+                ),
+                
+                new LayoutGroup ("debugging", Catalog.GetString ("Debugging and Development Options"), 
+                    new LayoutOption ("debug", Catalog.GetString ("Enable general debugging features")),
+                    new LayoutOption ("debug-sql", Catalog.GetString ("Enable debugging output of SQL queries")),
+                    new LayoutOption ("debug-addins", Catalog.GetString ("Enable debugging output of Mono.Addins")),
+                    new LayoutOption ("db=FILE", Catalog.GetString ("Specify an alternate database to use")),
+                    new LayoutOption ("uninstalled", Catalog.GetString ("Optimize instance for running uninstalled; " + 
+                        "most notably, this will create an alternate Mono.Addins database in the working directory")),
+                    new LayoutOption ("disable-dbus", Catalog.GetString ("Disable DBus support completely")),
+                    new LayoutOption ("no-gtkrc", String.Format (Catalog.GetString (
+                        "Skip loading a custom gtkrc file ({0}) if it exists"), 
+                        user_gtkrc.Replace (Environment.GetFolderPath (Environment.SpecialFolder.Personal), "~")))
+                )
+            );
+            
+            if (ApplicationContext.CommandLine.Contains ("help-all")) {
+                Console.WriteLine (commands);
+                return;
+            }
+            
+            List<string> errors = null;
+            
+            foreach (KeyValuePair<string, string> argument in ApplicationContext.CommandLine.Arguments) {
+                switch (argument.Key) {
+                    case "help": Console.WriteLine (commands.ToString ("help")); break;
+                    case "help-debug": Console.WriteLine (commands.ToString ("debugging")); break;
+                    case "help-query-track": Console.WriteLine (commands.ToString ("query-track")); break;
+                    case "help-query-player": Console.WriteLine (commands.ToString ("query-player")); break;
+                    case "help-ui": Console.WriteLine (commands.ToString ("ui")); break;
+                    case "help-playback": Console.WriteLine (commands.ToString ("playback")); break;
+                    default:
+                        if (argument.Key.StartsWith ("help")) {
+                            (errors ?? errors = new List<string> ()).Add (argument.Key);
+                        }
+                        break;
+                }
+            }
+            
+            if (errors != null) {
+                Console.WriteLine (commands.LayoutLine (String.Format (Catalog.GetString (
+                    "The following help arguments are invalid: {0}"),
+                    Hyena.Collections.CollectionExtensions.Join (errors, "--", null, ", "))));
+            }
+        }
+        
+        private static void ShowVersion ()
+        {
+            Console.WriteLine ("Banshee {0} ({1}) http://banshee-project.org";, Application.DisplayVersion, Application.Version);
+            Console.WriteLine ("Copyright 2005-{0} Novell, Inc. and Contributors.", DateTime.Now.Year);
+        }
+        
+        public override string ClientId {
+            get { return "nereid"; }
+        }
+    }
+}
+

Added: trunk/banshee/src/Clients/Muinshee/Muinshee/PlayerInterface.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Clients/Muinshee/Muinshee/PlayerInterface.cs	Tue Aug 26 19:30:15 2008
@@ -0,0 +1,583 @@
+// 
+// PlayerInterface.cs
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2007-2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using Mono.Unix;
+using Gtk;
+
+using Hyena.Gui;
+using Hyena.Data;
+using Hyena.Data.Gui;
+using Hyena.Widgets;
+
+using Banshee.ServiceStack;
+using Banshee.Sources;
+using Banshee.Database;
+using Banshee.Collection;
+using Banshee.Collection.Database;
+using Banshee.MediaEngine;
+using Banshee.Configuration;
+
+using Banshee.Gui;
+using Banshee.Gui.Widgets;
+using Banshee.Gui.Dialogs;
+using Banshee.Widgets;
+using Banshee.Collection.Gui;
+using Banshee.Sources.Gui;
+
+namespace Muinshee
+{
+    public class PlayerInterface : BaseClientWindow, IClientWindow, IDBusObjectName, IService, IDisposable, IHasSourceView
+    {
+        // Major Layout Components
+        private VBox primary_vbox;
+        private Toolbar header_toolbar;
+        private Toolbar footer_toolbar;
+        private HPaned views_pane;
+        private ViewContainer view_container;
+        
+        // Major Interaction Components
+        private SourceView source_view;
+        private CompositeTrackSourceContents composite_view;
+        private ObjectListSourceContents object_view;
+        private Label status_label;
+        
+        public PlayerInterface () : base (Catalog.GetString ("Banshee Media Player"))
+        {
+        }
+        
+        protected override void Initialize ()
+        {
+            BuildPrimaryLayout ();
+            ConnectEvents ();
+
+            ActionService.SourceActions.SourceView = this;
+            
+            composite_view.TrackView.HasFocus = true;
+            
+            Show ();
+        }
+        
+        protected override void UpdateTitle ()
+        {
+            TrackInfo track = ServiceManager.PlayerEngine.CurrentTrack;
+            if (track != null) {
+                // Translators: this is the window title when a track is playing
+                //              {0} is the track title, {1} is the artist name
+                Title = String.Format (Catalog.GetString ("{0} by {1}"), 
+                    track.DisplayTrackTitle, track.DisplayArtistName);
+            } else {
+                Title = Catalog.GetString ("Banshee Media Player");
+            }
+            
+            OnTitleChanged ();
+        }
+        
+#region System Overrides 
+        
+        public override void Dispose ()
+        {
+            lock (this) {
+                Hide ();
+                base.Dispose ();
+                Gtk.Application.Quit ();
+            }
+        }
+        
+#endregion        
+
+#region Interface Construction
+        
+        private void BuildPrimaryLayout ()
+        {
+            primary_vbox = new VBox ();
+            
+            Widget menu = new MainMenu ();
+            menu.Show ();
+            primary_vbox.PackStart (menu, false, false, 0);
+           
+            BuildHeader ();
+            BuildViews ();
+            BuildFooter ();
+            
+            primary_vbox.Show ();
+            Add (primary_vbox);
+        }
+        
+        private void BuildHeader ()
+        {
+            Alignment toolbar_alignment = new Alignment (0.0f, 0.0f, 1.0f, 1.0f);
+            toolbar_alignment.TopPadding = 3;
+            toolbar_alignment.BottomPadding = 3;
+            
+            header_toolbar = (Toolbar)ActionService.UIManager.GetWidget ("/HeaderToolbar");
+            header_toolbar.ShowArrow = false;
+            header_toolbar.ToolbarStyle = ToolbarStyle.BothHoriz;
+            
+            toolbar_alignment.Add (header_toolbar);
+            toolbar_alignment.ShowAll ();
+            
+            primary_vbox.PackStart (toolbar_alignment, false, false, 0);
+            
+            Widget next_button = new NextButton (ActionService);
+            next_button.Show ();
+            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/NextArrowButton", next_button);
+            
+            ConnectedSeekSlider seek_slider = new ConnectedSeekSlider ();
+            seek_slider.Show ();
+            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/SeekSlider", seek_slider);
+            
+            TrackInfoDisplay track_info_display = new ClassicTrackInfoDisplay ();
+            track_info_display.Show ();
+            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/TrackInfoDisplay", track_info_display, true);
+            
+            ConnectedVolumeButton volume_button = new ConnectedVolumeButton ();
+            volume_button.Show ();
+            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/VolumeButton", volume_button);
+        }
+
+        private void BuildViews ()
+        {
+            VBox source_box = new VBox ();
+            
+            views_pane = new HPaned ();
+            PersistentPaneController.Control (views_pane, SourceViewWidth);
+            view_container = new ViewContainer ();
+            
+            source_view = new SourceView ();
+            composite_view = new CompositeTrackSourceContents ();
+            
+            Hyena.Widgets.ScrolledWindow source_scroll = new Hyena.Widgets.ScrolledWindow ();
+            source_scroll.AddWithFrame (source_view);       
+            
+            composite_view.TrackView.HeaderVisible = false;
+            view_container.Content = composite_view;
+            
+            source_box.PackStart (source_scroll, true, true, 0);
+            source_box.PackStart (new UserJobTileHost (), false, false, 0);
+            
+            source_view.SetSizeRequest (125, -1);
+            view_container.SetSizeRequest (425, -1);
+            
+            views_pane.Pack1 (source_box, false, false);
+            views_pane.Pack2 (view_container, true, false);
+            
+            source_box.ShowAll ();
+            view_container.Show ();
+            views_pane.Show ();
+            
+            primary_vbox.PackStart (views_pane, true, true, 0);
+        }
+
+        private void BuildFooter ()
+        {
+            footer_toolbar = (Toolbar)ActionService.UIManager.GetWidget ("/FooterToolbar");
+            footer_toolbar.ShowArrow = false;
+            footer_toolbar.ToolbarStyle = ToolbarStyle.BothHoriz;
+
+            EventBox status_event_box = new EventBox ();
+            status_event_box.ButtonPressEvent += delegate (object o, ButtonPressEventArgs args) {
+                Source source = ServiceManager.SourceManager.ActiveSource;
+                if (source != null) {
+                    source.CycleStatusFormat ();
+                    UpdateSourceInformation ();
+                }
+            };
+            status_label = new Label ();
+            status_event_box.Add (status_label);
+            
+            Alignment status_align = new Alignment (0.5f, 0.5f, 1.0f, 1.0f);
+            status_align.Add (status_event_box);
+
+            RepeatActionButton repeat_button = new RepeatActionButton ();
+            repeat_button.SizeAllocated += delegate (object o, Gtk.SizeAllocatedArgs args) {
+                status_align.LeftPadding = (uint)args.Allocation.Width;
+            };
+
+            ActionService.PopulateToolbarPlaceholder (footer_toolbar, "/FooterToolbar/StatusBar", status_align, true);
+            ActionService.PopulateToolbarPlaceholder (footer_toolbar, "/FooterToolbar/RepeatButton", repeat_button);
+
+            footer_toolbar.ShowAll ();
+            primary_vbox.PackStart (footer_toolbar, false, true, 0);
+        }
+
+#endregion
+        
+#region Events and Logic Setup
+        
+        private void ConnectEvents ()
+        {
+            // Service events
+            ServiceManager.SourceManager.ActiveSourceChanged += OnActiveSourceChanged;
+            ServiceManager.SourceManager.SourceUpdated += OnSourceUpdated;
+            ServiceManager.PlayerEngine.ConnectEvent (OnPlayerEvent, 
+                PlayerEvent.StartOfStream |
+                PlayerEvent.TrackInfoUpdated |
+                PlayerEvent.EndOfStream);
+            
+            ActionService.TrackActions ["SearchForSameArtistAction"].Activated += OnProgrammaticSearch;
+            ActionService.TrackActions ["SearchForSameAlbumAction"].Activated += OnProgrammaticSearch;
+
+            // UI events
+            view_container.SearchEntry.Changed += OnSearchEntryChanged;
+            views_pane.SizeRequested += delegate {
+                SourceViewWidth.Set (views_pane.Position);
+            };
+            
+            source_view.RowActivated += delegate {
+                Source source = ServiceManager.SourceManager.ActiveSource;
+                if (source is ITrackModelSource) {
+                    ServiceManager.PlaybackController.NextSource = (ITrackModelSource)source;
+                    // Allow changing the play source without stopping the current song by
+                    // holding ctrl when activating a source. After the song is done, playback will
+                    // continue from the new source.
+                    if (GtkUtilities.NoImportantModifiersAreSet (Gdk.ModifierType.ControlMask)) {
+                        ServiceManager.PlaybackController.Next ();
+                    }
+                }
+            };
+            
+            header_toolbar.ExposeEvent += OnToolbarExposeEvent;
+            footer_toolbar.ExposeEvent += OnToolbarExposeEvent;
+        }
+        
+#endregion
+
+#region Service Event Handlers
+
+        private void OnProgrammaticSearch (object o, EventArgs args)
+        {
+            Source source = ServiceManager.SourceManager.ActiveSource;
+            view_container.SearchEntry.Ready = false;
+            view_container.SearchEntry.Query = source.FilterQuery;
+            view_container.SearchEntry.Ready = true;
+        }
+        
+        private Source previous_source = null;
+        private TrackListModel previous_track_model = null;
+        private void OnActiveSourceChanged (SourceEventArgs args)
+        {
+            Banshee.Base.ThreadAssist.ProxyToMain (delegate {
+                Source source = ServiceManager.SourceManager.ActiveSource;
+    
+                view_container.SearchSensitive = source != null && source.CanSearch;
+                
+                if (source == null) {
+                    return;
+                }
+                
+                view_container.Title = source.Name;
+                view_container.SearchEntry.Ready = false;
+                view_container.SearchEntry.CancelSearch ();
+    
+                if (source.FilterQuery != null) {
+                    view_container.SearchEntry.Query = source.FilterQuery;
+                    view_container.SearchEntry.ActivateFilter ((int)source.FilterType);
+                }
+    
+                if (view_container.Content != null) {
+                    view_container.Content.ResetSource ();
+                }
+    
+                if (previous_track_model != null) {
+                    previous_track_model.Reloaded -= HandleTrackModelReloaded;
+                    previous_track_model = null;
+                }
+    
+                if (source is ITrackModelSource) {
+                    previous_track_model = (source as ITrackModelSource).TrackModel;
+                    previous_track_model.Reloaded += HandleTrackModelReloaded;
+                }
+                
+                if (previous_source != null) {
+                    previous_source.Properties.PropertyChanged -= OnSourcePropertyChanged;
+                }
+                
+                previous_source = source;
+                previous_source.Properties.PropertyChanged += OnSourcePropertyChanged;
+                
+                UpdateSourceContents (source);
+                
+                UpdateSourceInformation ();
+                view_container.SearchEntry.Ready = true;
+            });
+        }
+        
+        private void OnSourcePropertyChanged (object o, PropertyChangeEventArgs args)
+        {
+            if (args.PropertyName == "Nereid.SourceContents") {
+                UpdateSourceContents (previous_source);
+            }
+        }
+        
+        private void UpdateSourceContents (Source source)
+        {
+            if (source == null) {
+                return;
+            }
+            
+            // Connect the source models to the views if possible
+            ISourceContents contents = source.GetInheritedProperty<bool> ("Nereid.SourceContentsPropagate")
+                ? source.GetInheritedProperty<ISourceContents> ("Nereid.SourceContents")
+                : source.Properties.Get<ISourceContents> ("Nereid.SourceContents");
+            
+            if (contents != null) {
+                if (view_container.Content != contents) {
+                    view_container.Content = contents;
+                }
+                view_container.Content.SetSource (source);
+                view_container.Show ();
+            } else if (source is ITrackModelSource) {
+                view_container.Content = composite_view;
+                view_container.Content.SetSource (source);
+                view_container.Show ();
+            } else if (source is Hyena.Data.IObjectListModel) {
+                if (object_view == null) {
+                    object_view = new ObjectListSourceContents ();
+                }
+                
+                view_container.Content = object_view;
+                view_container.Content.SetSource (source);
+                view_container.Show ();
+            } else {
+                view_container.Hide ();
+            }
+
+            // Associate the view with the model
+            if (view_container.Visible && view_container.Content is ITrackModelSourceContents) {
+                ITrackModelSourceContents track_content = view_container.Content as ITrackModelSourceContents;
+                source.Properties.Set<IListView<TrackInfo>>  ("Track.IListView", track_content.TrackView);
+            }
+
+            view_container.Header.Visible = source.Properties.Contains ("Nereid.SourceContents.HeaderVisible") ?
+                source.Properties.Get<bool> ("Nereid.SourceContents.HeaderVisible") : true;
+            
+            view_container.ClearFooter ();
+            Widget footer_widget = null;
+            
+            if (source.Properties.Contains ("Nereid.SourceContents.FooterWidget")) {
+                footer_widget = source.Properties.Get<Widget> ("Nereid.SourceContents.FooterWidget");
+            }
+            
+            if (footer_widget != null) {
+                view_container.SetFooter (footer_widget);
+            }
+        }
+
+        private void OnSourceUpdated (SourceEventArgs args)
+        {
+            if (args.Source == ServiceManager.SourceManager.ActiveSource) {
+                UpdateSourceInformation ();
+                view_container.Title = args.Source.Name;
+            }
+        }
+        
+        private void OnPlayerEvent (PlayerEventArgs args) 
+        {
+            UpdateTitle ();
+        }
+        
+#endregion
+
+#region UI Event Handlers
+        
+        private void OnSearchEntryChanged (object o, EventArgs args)
+        {
+            Source source = ServiceManager.SourceManager.ActiveSource;
+            if (source == null)
+                return;
+            
+            source.FilterType = (TrackFilterType)view_container.SearchEntry.ActiveFilterID;
+            source.FilterQuery = view_container.SearchEntry.Query;
+        }
+        
+        private void OnToolbarExposeEvent (object o, ExposeEventArgs args)
+        {
+            Toolbar toolbar = (Toolbar)o;
+
+            // This forces the toolbar to look like it's just a regular part
+            // of the window since the stock toolbar look makes Banshee look ugly.
+            Style.ApplyDefaultBackground (toolbar.GdkWindow, true, State, 
+                args.Event.Area, toolbar.Allocation.X, toolbar.Allocation.Y, 
+                toolbar.Allocation.Width, toolbar.Allocation.Height);
+
+            // Manually expose all the toolbar's children
+            foreach (Widget child in toolbar.Children) {
+                toolbar.PropagateExpose (child, args.Event);
+            }
+        }
+        
+#endregion
+
+#region Implement Interfaces
+
+        // IHasTrackSelection
+        /*public IEnumerable<TrackInfo> GetSelectedTracks ()
+        {
+            return new ModelSelection<TrackInfo> (composite_view.TrackModel, composite_view.TrackView.Selection);
+        }
+
+        public Hyena.Collections.SelectionProxy TrackSelectionProxy {
+            get { return composite_view.TrackView.SelectionProxy; }
+        }
+
+        public DatabaseTrackListModel TrackModel {
+            get { return composite_view.TrackModel as DatabaseTrackListModel; }
+        }*/
+
+        // IHasSourceView
+        public Source HighlightedSource {
+            get { return source_view.HighlightedSource; }
+        }
+
+        public void BeginRenameSource (Source source)
+        {
+            source_view.BeginRenameSource (source);
+        }
+        
+        public void ResetHighlight ()
+        {
+            source_view.ResetHighlight ();
+        }
+
+        public override Box ViewContainer {
+            get { return view_container; }
+        }
+
+#endregion
+        
+#region Gtk.Window Overrides
+
+        private bool accel_group_active = true;
+
+        private void OnEntryFocusOutEvent (object o, FocusOutEventArgs args)
+        {
+            if (!accel_group_active) {
+                AddAccelGroup (ActionService.UIManager.AccelGroup);
+                accel_group_active = true;
+            }
+
+            (o as Widget).FocusOutEvent -= OnEntryFocusOutEvent;
+        }
+        
+        protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
+        {
+            bool focus_search = false;
+            
+            if (Focus is Gtk.Entry && (GtkUtilities.NoImportantModifiersAreSet () && 
+                evnt.Key != Gdk.Key.Control_L && evnt.Key != Gdk.Key.Control_R)) {
+                if (accel_group_active) {
+                    RemoveAccelGroup (ActionService.UIManager.AccelGroup);
+                    accel_group_active = false;
+
+                    // Reinstate the AccelGroup as soon as the focus leaves the entry
+                    Focus.FocusOutEvent += OnEntryFocusOutEvent;
+                 }
+            } else {
+                if (!accel_group_active) {
+                    AddAccelGroup (ActionService.UIManager.AccelGroup);
+                    accel_group_active = true;
+                }
+            }
+            
+            switch (evnt.Key) {
+                case Gdk.Key.f:
+                    if (Gdk.ModifierType.ControlMask == (evnt.State & Gdk.ModifierType.ControlMask)) {
+                        focus_search = true;
+                    }
+                    break;
+
+                case Gdk.Key.S:  case Gdk.Key.s:
+                case Gdk.Key.F3: case Gdk.Key.slash:
+                    focus_search = true;
+                    break;
+            }
+
+            if (focus_search && !view_container.SearchEntry.HasFocus && !source_view.EditingRow) {
+                view_container.SearchEntry.HasFocus = true;
+                return true;
+            }
+            
+            return base.OnKeyPressEvent (evnt);
+        }
+
+#endregion
+
+#region Helper Functions
+
+        private void HandleTrackModelReloaded (object sender, EventArgs args)
+        {
+            UpdateSourceInformation ();
+        }
+
+        private void UpdateSourceInformation ()
+        {
+            Source source = ServiceManager.SourceManager.ActiveSource;
+            if (source == null) {
+                status_label.Text = String.Empty;
+                return;
+            }
+
+            status_label.Text = source.GetStatusText ();
+        }
+
+#endregion
+
+#region Configuration Schemas
+
+        public static readonly SchemaEntry<int> SourceViewWidth = new SchemaEntry<int> (
+            "player_window", "source_view_width",
+            175,
+            "Source View Width",
+            "Width of Source View Column."
+        );
+
+        public static readonly SchemaEntry<bool> ShowCoverArt = new SchemaEntry<bool> (
+            "player_window", "show_cover_art",
+            true,
+            "Show cover art",
+            "Show cover art below source view if available"
+        );
+
+#endregion
+
+        IDBusExportable IDBusExportable.Parent {
+            get { return null; }
+        }
+        
+        string IDBusObjectName.ExportObjectName {
+            get { return "ClientWindow"; }
+        }
+
+        string IService.ServiceName {
+            get { return "NereidPlayerInterface"; }
+        }
+    }
+}

Added: trunk/banshee/src/Clients/Muinshee/Muinshee/ViewContainer.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Clients/Muinshee/Muinshee/ViewContainer.cs	Tue Aug 26 19:30:15 2008
@@ -0,0 +1,247 @@
+// 
+// ViewContainer.cs
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2007 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using Gtk;
+using Mono.Unix;
+
+using Banshee.Widgets;
+using Banshee.Gui.Widgets;
+using Banshee.Sources.Gui;
+using Banshee.Collection;
+
+using Banshee.Gui;
+using Banshee.ServiceStack;
+
+namespace Muinshee
+{
+
+    public class ViewContainer : VBox
+    {
+        private SearchEntry search_entry;
+        private HBox header;
+        private Label title_label;
+        private Label search_label;
+        private VBox footer;
+        
+        private ISourceContents content;
+        
+        public ViewContainer ()
+        {
+            BuildHeader ();           
+            
+            Spacing = 8;
+            SearchSensitive = false;
+        }
+        
+        private void BuildHeader ()
+        {
+            header = new HBox ();
+            footer = new VBox ();
+            
+            EventBox title_box = new EventBox ();
+            title_label = new Label ();
+            title_label.Xalign = 0.0f;
+            title_label.Ellipsize = Pango.EllipsizeMode.End;
+
+            title_box.Add (title_label);
+
+            // Show the source context menu when the title is right clicked
+            title_box.PopupMenu += delegate {
+                ServiceManager.Get<InterfaceActionService> ().SourceActions ["SourceContextMenuAction"].Activate ();
+            };
+
+            title_box.ButtonPressEvent += delegate (object o, ButtonPressEventArgs press) {
+                if (press.Event.Button == 3) {
+                    ServiceManager.Get<InterfaceActionService> ().SourceActions ["SourceContextMenuAction"].Activate ();
+                }
+            };
+            
+            BuildSearchEntry ();
+            
+            search_label = new Label (Catalog.GetString ("_Search:"));
+            search_label.MnemonicWidget = search_entry.InnerEntry;
+            
+            header.PackStart (title_box, true, true, 0);
+            header.PackStart (search_label, false, false, 5);
+            header.PackStart (search_entry, false, false, 0);
+            
+            InterfaceActionService uia = ServiceManager.Get<InterfaceActionService> ();
+            if (uia != null) {
+                Gtk.Action action = uia.GlobalActions["WikiSearchHelpAction"];
+                if (action != null) {
+                    MenuItem item = new SeparatorMenuItem ();
+                    item.Show ();
+                    search_entry.Menu.Append (item);
+                    
+                    item = new ImageMenuItem (Stock.Help, null);
+                    item.Activated += delegate { action.Activate (); };
+                    item.Show ();
+                    search_entry.Menu.Append (item);
+                }
+            }
+            
+            header.ShowAll ();
+            search_entry.Show ();
+            
+            PackStart (header, false, false, 0);
+            PackEnd (footer, false, false, 0);
+            PackEnd (new ConnectedMessageBar (), false, true, 0);
+        }
+        
+        private struct SearchFilter
+        {
+            public int Id;
+            public string Field;
+            public string Title;
+        }
+        
+        private Dictionary<int, SearchFilter> search_filters = new Dictionary<int, SearchFilter> ();
+        
+        private void AddSearchFilter (TrackFilterType id, string field, string title)
+        {
+            SearchFilter filter = new SearchFilter ();
+            filter.Id = (int)id;
+            filter.Field = field;
+            filter.Title = title;
+            search_filters.Add (filter.Id, filter);
+        }
+        
+        private void BuildSearchEntry ()
+        {
+            AddSearchFilter (TrackFilterType.None, String.Empty, Catalog.GetString ("All Columns"));
+            AddSearchFilter (TrackFilterType.SongName, "title", Catalog.GetString ("Track Title"));
+            AddSearchFilter (TrackFilterType.ArtistName, "artist", Catalog.GetString ("Artist Name"));
+            AddSearchFilter (TrackFilterType.AlbumTitle, "album", Catalog.GetString ("Album Title"));
+            AddSearchFilter (TrackFilterType.Genre, "genre", Catalog.GetString ("Genre"));
+            AddSearchFilter (TrackFilterType.Year, "year", Catalog.GetString ("Year"));
+
+            search_entry = new SearchEntry ();
+            search_entry.SetSizeRequest (200, -1);
+
+            foreach (SearchFilter filter in search_filters.Values) {
+                search_entry.AddFilterOption (filter.Id, filter.Title);
+                if (filter.Id == (int)TrackFilterType.None) {
+                    search_entry.AddFilterSeparator ();
+                }
+            }
+
+            search_entry.FilterChanged += OnSearchEntryFilterChanged;
+            search_entry.ActivateFilter ((int)TrackFilterType.None);
+
+            OnSearchEntryFilterChanged (search_entry, EventArgs.Empty);
+        }
+
+        private void OnSearchEntryFilterChanged (object o, EventArgs args)
+        {
+            /* Translators: this is a verb (command), not a noun (things) */
+            search_entry.EmptyMessage = String.Format (Catalog.GetString ("Filter Results"));
+            /*search_entry.EmptyMessage = String.Format (Catalog.GetString ("Filter on {0}"),
+                search_entry.GetLabelForFilterID (search_entry.ActiveFilterID));*/
+
+            string query = search_filters.ContainsKey (search_entry.ActiveFilterID)
+                ? search_filters[search_entry.ActiveFilterID].Field
+                : String.Empty;
+
+            search_entry.Query = String.IsNullOrEmpty (query) ? String.Empty : query + ":";
+
+            Editable editable = search_entry.InnerEntry as Editable;
+            if (editable != null) {
+                editable.Position = search_entry.Query.Length;
+            }
+        }
+        
+        public void SetFooter (Widget contents)
+        {
+            if (contents != null) {
+                footer.PackStart (contents, false, false, 0);
+                contents.Show ();
+                footer.Show ();
+            }
+        }
+        
+        public void ClearFooter ()
+        {
+            foreach (Widget child in footer.Children) {
+                footer.Remove (child);
+            }
+            
+            footer.Hide ();
+        }
+        
+        public HBox Header {
+            get { return header; }
+        }
+        
+        public SearchEntry SearchEntry {
+            get { return search_entry; }
+        }
+        
+        public ISourceContents Content {
+            get { return content; }
+            set {
+                if (content == value) {
+                    return;
+                }
+
+                // Hide the old content widget
+                if (content != null && content.Widget != null) {
+                    content.Widget.Hide ();
+                }
+
+                // Add and show the new one
+                if (value != null && value.Widget != null) {
+                    PackStart (value.Widget, true, true, 0);
+                    value.Widget.Show ();
+                }
+                
+                // Remove the old one
+                if (content != null && content.Widget != null) {
+                    Remove (content.Widget);
+                }
+                
+                content = value;
+            }
+        }
+        
+        public string Title {
+            set { title_label.Markup = String.Format ("<b>{0}</b>", GLib.Markup.EscapeText (value)); }
+        }
+        
+        public bool SearchSensitive {
+            get { return search_entry.Sensitive; }
+            set { 
+                search_entry.Sensitive = value;
+                search_label.Sensitive = value;
+                search_entry.Visible = value;
+                search_label.Visible = value;
+            }
+        }
+    }
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]