Index: src/Core/Banshee/PlayerInterface.cs
===================================================================
--- src/Core/Banshee/PlayerInterface.cs	(revision 2227)
+++ src/Core/Banshee/PlayerInterface.cs	(working copy)
@@ -1584,25 +1584,34 @@
 
         private Menu song_popup_menu = null;
         private MenuItem add_to_playlist_menu_item = null;
-        private MenuItem rating_menu_item = null;
+        private RatingMenuItem rating_menu_item = null;
         
         private bool PlaylistMenuPopupTimeout(uint time)
         {
             if(song_popup_menu == null) {
                 song_popup_menu = Globals.ActionManager.GetWidget("/SongViewPopup") as Menu;
-                add_to_playlist_menu_item = Globals.ActionManager.GetWidget(
-                    "/SongViewPopup/AddToPlaylist") as MenuItem;
-                rating_menu_item = Globals.ActionManager.GetWidget("/SongViewPopup/Rating") as MenuItem;
+                add_to_playlist_menu_item = Globals.ActionManager.GetWidget("/SongViewPopup/AddToPlaylist") as MenuItem;
+                
+                for(int i = 0; i < song_popup_menu.Children.Length; i++) {
+                    if(song_popup_menu.Children[i] == add_to_playlist_menu_item) {
+                        rating_menu_item = new RatingMenuItem();
+                        rating_menu_item.Activated += OnItemRatingActivated;
+                        rating_menu_item.Visible = false;
+                        song_popup_menu.Insert(rating_menu_item, i + 1);
+                        break;
+                    }
+                }
             }
           
-            bool sensitive = playlistView.Selection.CountSelectedRows() > 0;
+            int selected_row_count = playlistView.Selection.CountSelectedRows();
+            bool sensitive = selected_row_count > 0;
 
             if(sensitive && (SourceManager.ActiveSource is LibrarySource ||
                     SourceManager.ActiveSource is PlaylistSource ||
                     SourceManager.ActiveSource is Banshee.SmartPlaylist.SmartPlaylistSource)) {
 
                 Globals.ActionManager["AddToPlaylistAction"].Visible = true;
-                Globals.ActionManager["RatingAction"].Visible = true;
+                rating_menu_item.Visible = true;
             
                 Menu plMenu = new Menu();
                 playlistMenuMap.Clear();
@@ -1626,41 +1635,23 @@
                     }
                 }
                 
-                Menu ratingMenu = new Menu();
-                
-                MenuItem clearItem = new MenuItem(Catalog.GetString("Clear"));
-                clearItem.Name = "0";
-                clearItem.Activated += OnItemRatingActivated;
-                
-                ratingMenu.Append(clearItem);
-                ratingMenu.Append(new SeparatorMenuItem());
-                
-                for(int i = 0; i < 5; i++) {
-                    MenuItem item = new MenuItem();
-                    HBox box = new HBox();
-                    box.Spacing = 3;
-                    
-                    for(int j = 0; j < i + 1; j++) {
-                        box.PackStart(new Gtk.Image(Banshee.Gui.CellRendererRating.RatedPixbuf), false, false, 0);
-                    }
-                    
-                    item.Add(box);
-                    item.Name = String.Format("{0}", i + 1);
-                    item.Activated += OnItemRatingActivated;
-                    ratingMenu.Append(item);
-                }
-                
                 add_to_playlist_menu_item.Submenu = plMenu;
-                rating_menu_item.Submenu = ratingMenu;
-                
                 plMenu.ShowAll();
-                ratingMenu.ShowAll();
+                
+                // FIXME: The selection/popup order is fux0red
+                // if(selected_row_count == 1) {
+                //    rating_menu_item.Reset((int)playlistView.SelectedTrackInfo.Rating);
+                // } else {
+                //    rating_menu_item.Reset(0);
+                // }
+                
+                rating_menu_item.Reset(0);
             } else {
                 Globals.ActionManager["AddToPlaylistAction"].Visible = false;
-                Globals.ActionManager["RatingAction"].Visible = false;
+                rating_menu_item.Visible = false;
             }
         
-            song_popup_menu.ShowAll();
+            song_popup_menu.Show();
             song_popup_menu.Popup(null, null, null, 0, time);
             
             return false;
@@ -1668,9 +1659,12 @@
 
         private void OnItemRatingActivated(object o, EventArgs args)
         {
-            uint rating = Convert.ToUInt32((o as Widget).Name);
-            foreach(TreePath path in playlistView.Selection.GetSelectedRows())
+            uint rating = (uint)(o as RatingMenuItem).Value;
+            
+            foreach(TreePath path in playlistView.Selection.GetSelectedRows()) {
                 playlistModel.PathTrackInfo(path).Rating = rating;
+            }
+            
             playlistView.QueueDraw();
         }
 
Index: src/Core/Banshee.Widgets/Banshee.Widgets.mdp
===================================================================
--- src/Core/Banshee.Widgets/Banshee.Widgets.mdp	(revision 2216)
+++ src/Core/Banshee.Widgets/Banshee.Widgets.mdp	(working copy)
@@ -41,6 +41,7 @@
     <File name="./FadingAlignment.cs" subtype="Code" buildaction="Compile" />
     <File name="./VolumeButton.cs" subtype="Code" buildaction="Compile" />
     <File name="./CoverArtView.cs" subtype="Code" buildaction="Compile" />
+    <File name="./RatingMenuItem.cs" subtype="Code" buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.8.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
Index: src/Core/Banshee.Widgets/RatingEntry.cs
===================================================================
--- src/Core/Banshee.Widgets/RatingEntry.cs	(revision 2216)
+++ src/Core/Banshee.Widgets/RatingEntry.cs	(working copy)
@@ -8,13 +8,14 @@
     {
         private static int max_rating = 5;
         private static int min_rating = 1;
-        private static int y_offset = 4, x_offset = 4;
         private static Pixbuf icon_rated;
         private static Pixbuf icon_blank;
         
         public object RatedObject;
         
         private int rating;
+        private bool embedded;
+        private int y_offset = 4, x_offset = 4;
         private Gdk.Pixbuf display_pixbuf;
         
         public event EventHandler Changed;
@@ -22,15 +23,25 @@
         public RatingEntry() : this(1) 
         {
         }
+        
+        public RatingEntry(int rating) : this(rating, false)
+        {
+        }
 
-        public RatingEntry(int rating)
+        public RatingEntry(int rating, bool embedded)
         {
             if(IconRated.Height != IconNotRated.Height || IconRated.Width != IconNotRated.Width) {
                 throw new ArgumentException("Rating widget requires that rated and blank icons have the same height and width");
             }
             
             this.rating = rating;
+            this.embedded = embedded;
             
+            if(embedded) {
+                y_offset = 0;
+                x_offset = 0;
+            }
+            
             CanFocus = true;
             
             display_pixbuf = new Pixbuf(Gdk.Colorspace.Rgb, true, 8, Width, Height);
@@ -79,7 +90,8 @@
         
         private int RatingFromPosition(double x)
         {
-            return x < 5 ? 0 : (int)Math.Max(0, Math.Min(((x - 4) / (double)icon_rated.Width) + 1, MaxRating));
+            return x < x_offset + 1 ? 0 : (int)Math.Max(0, Math.Min(((x - x_offset) 
+                / (double)icon_rated.Width) + 1, MaxRating));
         }
         
         protected override bool OnExposeEvent(Gdk.EventExpose evnt)
@@ -89,15 +101,17 @@
             if(evnt.Window != GdkWindow) {
                 return ret;
             }
-            
+           
             int y_mid = (Allocation.Height - Height) / 2;
 
-            GdkWindow.DrawRectangle(Style.BaseGC(StateType.Normal), true, 0, y_mid - y_offset,
-                Allocation.Width, Height + (y_offset * 2));
+            if(!embedded) {
+                GdkWindow.DrawRectangle(Style.BaseGC(StateType.Normal), true, 0, y_mid - y_offset,
+                    Allocation.Width, Height + (y_offset * 2));
             
-            Gtk.Style.PaintShadow(Style, GdkWindow, StateType.Normal, ShadowType.In,
-                evnt.Area, this, "entry", 0, y_mid - y_offset, Allocation.Width, 
-                Height + (y_offset * 2));
+                Gtk.Style.PaintShadow(Style, GdkWindow, StateType.Normal, ShadowType.In,
+                    evnt.Area, this, "entry", 0, y_mid - y_offset, Allocation.Width, 
+                    Height + (y_offset * 2));
+            }
 
             GdkWindow.DrawPixbuf(Style.BackgroundGC(StateType.Normal), 
                 display_pixbuf, 0, 0, x_offset, y_mid, Width, Height, Gdk.RgbDither.None, 0, 0);
@@ -105,7 +119,6 @@
             return ret;
         }
 
-        [GLib.ConnectBefore]
         protected override bool OnButtonPressEvent(Gdk.EventButton evnt)
         {
             if(evnt.Button != 1) {
@@ -122,7 +135,6 @@
             return this.OnKeyPressEvent(evnt);
         }
         
-        [GLib.ConnectBefore]
         protected override bool OnKeyPressEvent(Gdk.EventKey evnt)
         {
             switch(evnt.Key) {
@@ -148,9 +160,13 @@
             return false;
         }
         
-        [GLib.ConnectBefore]
         protected override bool OnScrollEvent(EventScroll args)
         {
+            return HandleScroll(args);
+        }
+
+        public bool HandleScroll(EventScroll args)
+        {
             switch(args.Direction) {
                 case Gdk.ScrollDirection.Up:
                 case Gdk.ScrollDirection.Right:
@@ -166,7 +182,6 @@
             return false;
         }
         
-        [GLib.ConnectBefore]
         protected override bool OnMotionNotifyEvent(Gdk.EventMotion evnt)
         {
             // TODO draw highlights onmouseover a rating? (and clear on leaveNotify)
@@ -189,6 +204,11 @@
             }
         }
         
+        public void SetValueFromPosition(int x)
+        {
+            Value = RatingFromPosition(x);
+        }
+
         public int Value {
             get { return rating; }
             set {
Index: src/Core/Banshee.Widgets/RatingMenuItem.cs
===================================================================
--- src/Core/Banshee.Widgets/RatingMenuItem.cs	(revision 0)
+++ src/Core/Banshee.Widgets/RatingMenuItem.cs	(revision 0)
@@ -0,0 +1,124 @@
+/***************************************************************************
+ *  RatingMenuItem.cs
+ *
+ *  Copyright (C) 2007 Novell, Inc.
+ *  Written by Aaron Bockover <abockover@novell.com>
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),  
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using Gtk;
+using Mono.Unix;
+
+namespace Banshee.Widgets
+{
+    public class RatingMenuItem : MenuItem
+    {
+        private RatingEntry entry;
+        private bool pressing;
+        private bool can_activate = true;
+
+        public RatingMenuItem() : base()
+        {
+            entry = new RatingEntry(0, true);
+            entry.Changed += OnEntryChanged;
+            entry.Show();
+            Add(entry);
+        }
+
+        private int TransformX(double inx)
+        {
+            int x = (int)inx - entry.Allocation.X;
+
+            if(x < 0) {
+                x = 0;
+            } else if(x > entry.Allocation.Width) {
+                x = entry.Allocation.Width;
+            }
+
+            return x;
+        }
+
+        protected override bool OnButtonPressEvent(Gdk.EventButton evnt)
+        {
+            pressing = true;
+            entry.SetValueFromPosition(TransformX(evnt.X));
+            return true;
+        }
+
+        protected override bool OnButtonReleaseEvent(Gdk.EventButton evnt)
+        {
+            pressing = false;
+            return true;
+        }
+
+        protected override bool OnMotionNotifyEvent(Gdk.EventMotion evnt)
+        {
+            if(!pressing) {
+                return false;
+            }
+
+            entry.SetValueFromPosition(TransformX(evnt.X));
+            return true;
+        }
+
+        protected override bool OnLeaveNotifyEvent(Gdk.EventCrossing evnt)
+        {
+            pressing = false;
+            return true;
+        }
+
+        protected override bool OnScrollEvent(Gdk.EventScroll evnt)
+        {
+            return entry.HandleScroll(evnt);
+        }
+
+        protected override bool OnExposeEvent(Gdk.EventExpose evnt)
+        {
+            return true;
+        }
+        
+        private void OnEntryChanged(object o, EventArgs args)
+        {
+            if(can_activate) {
+                Activate();
+            }
+        }
+        
+        public void Reset(int value)
+        {
+            can_activate = false;
+            Value = value;
+            can_activate = true;
+        }
+        
+        public int Value {
+            get { return entry.Value; }
+            set { entry.Value = value; }
+        }
+        
+        public RatingEntry RatingEntry {
+            get { return entry; }
+        }
+    }
+}
Index: src/Core/Banshee.Widgets/Makefile.am
===================================================================
--- src/Core/Banshee.Widgets/Makefile.am	(revision 2216)
+++ src/Core/Banshee.Widgets/Makefile.am	(working copy)
@@ -38,7 +38,8 @@
 	$(srcdir)/RatingEntry.cs \
 	$(srcdir)/ShadowContainer.cs \
 	$(srcdir)/DictionaryComboBox.cs \
-	$(srcdir)/FadingAlignment.cs 
+	$(srcdir)/FadingAlignment.cs \
+	$(srcdir)/RatingMenuItem.cs
 
 Banshee_Widgets_RESOURCES = \
 	data/images/rating-rated.png \
Index: src/Core/Banshee.Base/ActionManager.cs
===================================================================
--- src/Core/Banshee.Base/ActionManager.cs	(revision 2227)
+++ src/Core/Banshee.Base/ActionManager.cs	(working copy)
@@ -261,10 +261,6 @@
                 new ActionEntry("AddToPlaylistAction", null,
                     Catalog.GetString("Add _to Playlist"), null,
                     Catalog.GetString("Append selected songs to playlist or create new playlist from selection"), null),
-                    
-                new ActionEntry("RatingAction", null,
-                    Catalog.GetString("Ratin_g"), null,
-                    Catalog.GetString("Set rating for selected songs"), null)
             });
             
             ui.InsertActionGroup(song_actions, 0);
Index: data/UIManagerLayout.xml
===================================================================
--- data/UIManagerLayout.xml	(revision 2216)
+++ data/UIManagerLayout.xml	(working copy)
@@ -97,7 +97,6 @@
         <menuitem name="Columns" action="ColumnsAction" />
         <separator />
         <menuitem name="AddToPlaylist" action="AddToPlaylistAction" />
-        <menuitem name="Rating" action="RatingAction" />
         <separator />
         <menuitem name="CopySongs" action="CopySongsAction" />
         <menuitem name="RemoveSongs" action="RemoveSongsAction" />
