banshee r3343 - in trunk/banshee: . src/Clients/Nereid src/Clients/Nereid/Nereid src/Core/Banshee.ThickClient src/Core/Banshee.ThickClient/Banshee.Gui src/Core/Banshee.ThickClient/Banshee.Gui.Widgets src/Core/Banshee.ThickClient/Resources src/Libraries/Hyena/Hyena tests tests/Hyena
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r3343 - in trunk/banshee: . src/Clients/Nereid src/Clients/Nereid/Nereid src/Core/Banshee.ThickClient src/Core/Banshee.ThickClient/Banshee.Gui src/Core/Banshee.ThickClient/Banshee.Gui.Widgets src/Core/Banshee.ThickClient/Resources src/Libraries/Hyena/Hyena tests tests/Hyena
- Date: Wed, 27 Feb 2008 23:53:11 +0000 (GMT)
Author: abock
Date: Wed Feb 27 23:53:11 2008
New Revision: 3343
URL: http://svn.gnome.org/viewvc/banshee?rev=3343&view=rev
Log:
2008-02-27 Aaron Bockover <abock gnome org>
* src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs:
Created UI actions for repeat mode functionality; this is where the
repeat mode can be accessed and is stored/loaded from configuration;
the UI actions are set up here
* src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs:
A special button that syncs its state with the PlaybackRepeatActions and
presents the actions as a popup menu
* src/Clients/Nereid/Nereid/PlayerInterface.cs: Make the footer actually
a Gtk.Toolbar, pack the new RepeatActionButton, and do some allocation
magic to ensure the status bar is always centered on the toolbar; moved
the only two schema items that are still at the client level into here
* src/Core/Banshee.ThickClient/Banshee.Gui/BansheeIconFactory.cs: Added
the media-repeat icons into the stock
* src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackActions.cs: Load the
PlaybackRepeatActions as a child set of actions
* src/Clients/Nereid/Nereid/PlayerWindowSchema.cs: Removed
* src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml:
Added a ToolbarFooter object
* src/Libraries/Hyena/Hyena/StringUtil.cs: Added UnderCaseToCamelCase
method that does the opposite of what CamelCaseToUnderCaseDoes; use
a StringBuilder for the latter
* tests/Hyena/StringUtilTests.cs: Added some tests for the above two methods
Added:
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs
trunk/banshee/tests/Hyena/StringUtilTests.cs
Removed:
trunk/banshee/src/Clients/Nereid/Nereid/PlayerWindowSchema.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Clients/Nereid/Makefile.am
trunk/banshee/src/Clients/Nereid/Nereid.mdp
trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeIconFactory.cs
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackActions.cs
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp
trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am
trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml
trunk/banshee/src/Libraries/Hyena/Hyena/StringUtil.cs
trunk/banshee/tests/Makefile.am
Modified: trunk/banshee/src/Clients/Nereid/Makefile.am
==============================================================================
--- trunk/banshee/src/Clients/Nereid/Makefile.am (original)
+++ trunk/banshee/src/Clients/Nereid/Makefile.am Wed Feb 27 23:53:11 2008
@@ -4,7 +4,6 @@
SOURCES = \
Nereid/Client.cs \
Nereid/PlayerInterface.cs \
- Nereid/PlayerWindowSchema.cs \
Nereid/ViewContainer.cs
bin_SCRIPTS = banshee2
Modified: trunk/banshee/src/Clients/Nereid/Nereid.mdp
==============================================================================
--- trunk/banshee/src/Clients/Nereid/Nereid.mdp (original)
+++ trunk/banshee/src/Clients/Nereid/Nereid.mdp Wed Feb 27 23:53:11 2008
@@ -10,7 +10,6 @@
<Contents>
<File name="Nereid/PlayerInterface.cs" subtype="Code" buildaction="Compile" />
<File name="Nereid/ViewContainer.cs" subtype="Code" buildaction="Compile" />
- <File name="Nereid/PlayerWindowSchema.cs" subtype="Code" buildaction="Compile" />
<File name="Nereid/Client.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
Modified: trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs
==============================================================================
--- trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs (original)
+++ trunk/banshee/src/Clients/Nereid/Nereid/PlayerInterface.cs Wed Feb 27 23:53:11 2008
@@ -42,6 +42,7 @@
using Banshee.Collection;
using Banshee.Collection.Database;
using Banshee.MediaEngine;
+using Banshee.Configuration;
using Banshee.Gui;
using Banshee.Gui.Widgets;
@@ -57,8 +58,8 @@
// Major Layout Components
private VBox primary_vbox;
private Toolbar header_toolbar;
+ private Toolbar footer_toolbar;
private HPaned views_pane;
- private HBox footer_box;
private ViewContainer view_container;
// Major Interaction Components
@@ -195,31 +196,28 @@
private void BuildFooter ()
{
- footer_box = new HBox ();
- footer_box.Spacing = 2;
+ footer_toolbar = (Toolbar)ActionService.UIManager.GetWidget ("/FooterToolbar");
+ footer_toolbar.ShowArrow = false;
+ footer_toolbar.ToolbarStyle = ToolbarStyle.BothHoriz;
+ footer_toolbar.IconSize = IconSize.Menu;
status_label = new Label ();
status_label.ModifyFg (StateType.Normal, Hyena.Gui.GtkUtilities.ColorBlend (
status_label.Style.Foreground (StateType.Normal), status_label.Style.Background (StateType.Normal)));
-
- ActionButton song_properties_button = new ActionButton
- (ActionService.TrackActions["TrackPropertiesAction"]);
- song_properties_button.IconSize = IconSize.Menu;
- song_properties_button.Padding = 0;
- song_properties_button.LabelVisible = false;
-
- //footer_box.PackStart (shuffle_toggle_button, false, false, 0);
- //footer_box.PackStart (repeat_toggle_button, false, false, 0);
- footer_box.PackStart (status_label, true, true, 0);
- footer_box.PackStart (song_properties_button, false, false, 0);
-
- Alignment align = new Alignment (0.5f, 0.5f, 1.0f, 1.0f);
- align.TopPadding = 2;
- align.BottomPadding = 0;
- align.Add (footer_box);
- align.ShowAll ();
- primary_vbox.PackStart (align, false, true, 0);
+ Alignment status_align = new Alignment (0.5f, 0.5f, 1.0f, 1.0f);
+ status_align.Add (status_label);
+
+ 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
@@ -228,7 +226,7 @@
private void LoadSettings ()
{
- views_pane.Position = PlayerWindowSchema.SourceViewWidth.Get ();
+ views_pane.Position = SourceViewWidth.Get ();
}
#endregion
@@ -247,7 +245,7 @@
// UI events
view_container.SearchEntry.Changed += OnSearchEntryChanged;
views_pane.SizeRequested += delegate {
- PlayerWindowSchema.SourceViewWidth.Set (views_pane.Position);
+ SourceViewWidth.Set (views_pane.Position);
};
composite_view.TrackView.RowActivated += delegate (object o, RowActivatedArgs<TrackInfo> args) {
@@ -262,7 +260,8 @@
}
};
- header_toolbar.ExposeEvent += OnHeaderToolbarExposeEvent;
+ header_toolbar.ExposeEvent += OnToolbarExposeEvent;
+ footer_toolbar.ExposeEvent += OnToolbarExposeEvent;
}
#endregion
@@ -349,17 +348,19 @@
source.FilterQuery = view_container.SearchEntry.Query;
}
- private void OnHeaderToolbarExposeEvent (object o, ExposeEventArgs args)
+ 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 (header_toolbar.GdkWindow, true, State,
- args.Event.Area, header_toolbar.Allocation.X, header_toolbar.Allocation.Y,
- header_toolbar.Allocation.Width, header_toolbar.Allocation.Height);
+ 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 header_toolbar.Children) {
- header_toolbar.PropagateExpose (child, args.Event);
+ foreach (Widget child in toolbar.Children) {
+ toolbar.PropagateExpose (child, args.Event);
}
}
@@ -472,9 +473,26 @@
#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
+
string IService.ServiceName {
get { return "NereidPlayerInterface"; }
}
}
}
-
Added: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/RepeatActionButton.cs Wed Feb 27 23:53:11 2008
@@ -0,0 +1,130 @@
+//
+// ConnectedRepeatComboBox.cs
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 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 Gtk;
+
+using Banshee.Gui;
+using Banshee.ServiceStack;
+
+namespace Banshee.Gui.Widgets
+{
+ public class RepeatActionButton : Button
+ {
+ private HBox box = new HBox ();
+ private Image image = new Image ();
+ private Label label = new Label ();
+
+ public RepeatActionButton () : base ()
+ {
+ InterfaceActionService service = ServiceManager.Get<InterfaceActionService> ();
+ service.PlaybackActions.RepeatActions.Changed += OnActionChanged;
+
+ Relief = ReliefStyle.None;
+
+ label.UseUnderline = true;
+ image.IconSize = (int)IconSize.Menu;
+
+ box.Spacing = 4;
+ box.PackStart (image, false, false, 0);
+ box.PackStart (label, true, true, 0);
+ box.ShowAll ();
+ Add (box);
+
+ SetActiveItem (service.PlaybackActions.RepeatActions.Active);
+ }
+
+ private void OnActionChanged (object o, ChangedArgs args)
+ {
+ SetActiveItem ((RadioAction)args.Current);
+ }
+
+ private void SetActiveItem (RadioAction action)
+ {
+ if (action == null) {
+ return;
+ }
+
+ image.Stock = action.StockId;
+ label.TextWithMnemonic = action.Label;
+ box.Sensitive = action.Sensitive && action.Visible;
+ }
+
+ protected override void OnActivated ()
+ {
+ BuildMenu ().Popup (null, null, PositionMenu, 1, Gtk.Global.CurrentEventTime);
+ }
+
+ protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
+ {
+ if (evnt.Button == 1 || evnt.Button == 3) {
+ BuildMenu ().Popup (null, null, PositionMenu, 1, evnt.Time);
+ }
+
+ return true;
+ }
+
+ private Menu BuildMenu ()
+ {
+ Menu menu = new Menu ();
+ InterfaceActionService service = ServiceManager.Get<InterfaceActionService> ();
+ foreach (RadioAction action in service.PlaybackActions.RepeatActions) {
+ menu.Append (action.CreateMenuItem ());
+ }
+
+ menu.ShowAll ();
+ return menu;
+ }
+
+ private void PositionMenu (Menu menu, out int x, out int y, out bool push_in)
+ {
+ Gtk.Requisition menu_req = menu.SizeRequest ();
+ int monitor_num = Screen.GetMonitorAtWindow (GdkWindow);
+ Gdk.Rectangle monitor = Screen.GetMonitorGeometry (monitor_num < 0 ? 0 : monitor_num);
+
+ GdkWindow.GetOrigin (out x, out y);
+
+ y += Allocation.Y;
+ x += Allocation.X + (Direction == TextDirection.Ltr
+ ? Math.Max (Allocation.Width - menu_req.Width, 0)
+ : - (menu_req.Width - Allocation.Width));
+
+ if (y + Allocation.Height + menu_req.Height <= monitor.Y + monitor.Height) {
+ y += Allocation.Height;
+ } else if (y - menu_req.Height >= monitor.Y) {
+ y -= menu_req.Height;
+ } else if (monitor.Y + monitor.Height - (y + Allocation.Height) > y) {
+ y += Allocation.Height;
+ } else {
+ y -= menu_req.Height;
+ }
+
+ push_in = false;
+ }
+ }
+}
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeIconFactory.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeIconFactory.cs (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeIconFactory.cs Wed Feb 27 23:53:11 2008
@@ -44,6 +44,9 @@
"media-playback-pause",
"media-playback-stop",
"media-eject",
+ "media-repeat-all",
+ "media-repeat-none",
+ "media-repeat-single",
/* Volume Button Icons */
"audio-volume-high",
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackActions.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackActions.cs (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackActions.cs Wed Feb 27 23:53:11 2008
@@ -43,9 +43,16 @@
{
private InterfaceActionService action_service;
private Gtk.Action play_pause_action;
+ private PlaybackRepeatActions repeat_actions;
+
+ public PlaybackRepeatActions RepeatActions {
+ get { return repeat_actions; }
+ }
public PlaybackActions (InterfaceActionService actionService) : base ("Playback")
{
+ repeat_actions = new PlaybackRepeatActions (actionService);
+
Add (new ActionEntry [] {
new ActionEntry ("PlayPauseAction", "media-playback-start",
Catalog.GetString ("_Play"), "space",
@@ -79,20 +86,6 @@
Catalog.GetString ("Stop playback after the current song finishes playing"),
OnStopWhenFinishedAction, false)
});
-
- Add (new RadioActionEntry [] {
- new RadioActionEntry ("RepeatNoneAction", null,
- Catalog.GetString ("Repeat N_one"), null,
- Catalog.GetString ("Do not repeat playlist"), 0),
-
- new RadioActionEntry ("RepeatAllAction", null,
- Catalog.GetString ("Repeat _All"), null,
- Catalog.GetString ("Play all songs before repeating playlist"), 1),
-
- new RadioActionEntry ("RepeatSingleAction", null,
- Catalog.GetString ("Repeat Si_ngle"), null,
- Catalog.GetString ("Repeat the current playing song"), 2)
- }, 0, null);
actionService.GlobalActions.Add (new ActionEntry [] {
new ActionEntry ("PlaybackMenuAction", null,
Added: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackRepeatActions.cs Wed Feb 27 23:53:11 2008
@@ -0,0 +1,123 @@
+//
+// PlaybackRepeatActions.cs
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 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;
+using System.Collections.Generic;
+using Mono.Unix;
+using Gtk;
+
+using Hyena;
+using Banshee.Configuration;
+
+namespace Banshee.Gui
+{
+ public class PlaybackRepeatActions : BansheeActionGroup, IEnumerable<RadioAction>
+ {
+ private InterfaceActionService action_service;
+ private RadioAction active_action;
+
+ public RadioAction Active {
+ get { return active_action; }
+ set {
+ active_action = value;
+ RepeatMode.Set (active_action == null ? String.Empty : ActionNameToConfigId (active_action.Name));
+ }
+ }
+
+ public event ChangedHandler Changed;
+
+ public PlaybackRepeatActions (InterfaceActionService actionService) : base ("PlaybackRepeat")
+ {
+ actionService.AddActionGroup (this);
+
+ Add (new RadioActionEntry [] {
+ new RadioActionEntry ("RepeatNoneAction", "media-repeat-none",
+ Catalog.GetString ("Repeat N_one"), null,
+ Catalog.GetString ("Do not repeat playlist"), 0),
+
+ new RadioActionEntry ("RepeatAllAction", "media-repeat-all",
+ Catalog.GetString ("Repeat _All"), null,
+ Catalog.GetString ("Play all songs before repeating playlist"), 1),
+
+ new RadioActionEntry ("RepeatSingleAction", "media-repeat-single",
+ Catalog.GetString ("Repeat Si_ngle"), null,
+ Catalog.GetString ("Repeat the current playing song"), 2)
+ }, 0, OnChanged);
+
+ action_service = actionService;
+
+ Gtk.Action action = this[ConfigIdToActionName (RepeatMode.Get ())];
+ if (action is RadioAction) {
+ active_action = (RadioAction)action;
+ } else {
+ Active = (RadioAction)this["RepeatNoneAction"];
+ }
+ }
+
+ private void OnChanged (object o, ChangedArgs args)
+ {
+ Active = args.Current;
+
+ ChangedHandler handler = Changed;
+ if (handler != null) {
+ handler (o, args);
+ }
+ }
+
+ public IEnumerator<RadioAction> GetEnumerator ()
+ {
+ yield return (RadioAction)this["RepeatNoneAction"];
+ yield return (RadioAction)this["RepeatAllAction"];
+ yield return (RadioAction)this["RepeatSingleAction"];
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return GetEnumerator ();
+ }
+
+ private static string ConfigIdToActionName (string configuration)
+ {
+ return String.Format ("{0}Action", StringUtil.UnderCaseToCamelCase (configuration));
+ }
+
+ private static string ActionNameToConfigId (string actionName)
+ {
+ return StringUtil.CamelCaseToUnderCase (actionName.Substring (0,
+ actionName.Length - (actionName.EndsWith ("Action") ? 6 : 0)));
+ }
+
+ public static readonly SchemaEntry<string> RepeatMode = new SchemaEntry<string> (
+ "playback", "repeat_mode",
+ "none",
+ "Repeat playback",
+ "Repeat mode (repeat_none, repeat_all, repeat_single)"
+ );
+ }
+}
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.ThickClient.mdp Wed Feb 27 23:53:11 2008
@@ -94,6 +94,11 @@
<File name="Banshee.Sources.Gui/ISourceContents.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.Sources.Gui/ObjectListSourceContents.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.Playlist.Gui/PlaylistExportDialog.cs" subtype="Code" buildaction="Compile" />
+ <File name="Resources/media-repeat-all.png" subtype="Code" buildaction="EmbedAsResource" />
+ <File name="Resources/media-repeat-none.png" subtype="Code" buildaction="EmbedAsResource" />
+ <File name="Resources/media-repeat-single.png" subtype="Code" buildaction="EmbedAsResource" />
+ <File name="Banshee.Gui.Widgets/RepeatActionButton.cs" subtype="Code" buildaction="Compile" />
+ <File name="Banshee.Gui/PlaybackRepeatActions.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
<ProjectReference type="Project" localcopy="False" refto="Hyena.Gui" />
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Makefile.am Wed Feb 27 23:53:11 2008
@@ -44,6 +44,7 @@
Banshee.Gui.Widgets/ConnectedSeekSlider.cs \
Banshee.Gui.Widgets/ConnectedVolumeButton.cs \
Banshee.Gui.Widgets/PlaylistMenuItem.cs \
+ Banshee.Gui.Widgets/RepeatActionButton.cs \
Banshee.Gui.Widgets/TrackInfoDisplay.cs \
Banshee.Gui.Widgets/UserJobTile.cs \
Banshee.Gui.Widgets/UserJobTileHost.cs \
@@ -58,6 +59,7 @@
Banshee.Gui/IHasSourceView.cs \
Banshee.Gui/InterfaceActionService.cs \
Banshee.Gui/PlaybackActions.cs \
+ Banshee.Gui/PlaybackRepeatActions.cs \
Banshee.Gui/SourceActions.cs \
Banshee.Gui/TrackActions.cs \
Banshee.Gui/ViewActions.cs \
@@ -85,6 +87,9 @@
Resources/banshee-logo.png \
Resources/browser-album-cover.png \
Resources/core-ui-actions-layout.xml \
+ Resources/media-repeat-all.png \
+ Resources/media-repeat-none.png \
+ Resources/media-repeat-single.png \
Resources/source-cd-audio.png \
Resources/source-library.png \
Resources/source-localqueue.png \
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml Wed Feb 27 23:53:11 2008
@@ -10,6 +10,10 @@
</placeholder>
<placeholder name="VolumeButton"/>
</toolbar>
+ <toolbar name="FooterToolbar">
+ <placeholder name="StatusBar"/>
+ <placeholder name="RepeatButton"/>
+ </toolbar>
<menubar name="MainMenu">
<menu name="MusicMenu" action="MusicMenuAction">
@@ -70,9 +74,9 @@
<menuitem name="RestartSong" action="RestartSongAction"/>
<separator/>
<placeholder name="PlaybackMenuAdditions"/>
- <!--<menuitem name="RepeatNone" action="RepeatNoneAction"/>
+ <menuitem name="RepeatNone" action="RepeatNoneAction"/>
<menuitem name="RepeatAll" action="RepeatAllAction"/>
- <menuitem name="RepeatSingle" action="RepeatSingleAction"/>-->
+ <menuitem name="RepeatSingle" action="RepeatSingleAction"/>
<separator/>
<menuitem name="Shuffle" action="ShuffleAction"/>
</menu>
Modified: trunk/banshee/src/Libraries/Hyena/Hyena/StringUtil.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena/StringUtil.cs (original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena/StringUtil.cs Wed Feb 27 23:53:11 2008
@@ -27,6 +27,7 @@
//
using System;
+using System.Text;
using System.Globalization;
using System.Text.RegularExpressions;
@@ -66,7 +67,7 @@
return null;
}
- string undercase = String.Empty;
+ StringBuilder undercase = new StringBuilder ();
string [] tokens = Regex.Split (s, "([A-Z]{1}[a-z]+)");
for (int i = 0; i < tokens.Length; i++) {
@@ -74,13 +75,42 @@
continue;
}
- undercase += tokens[i].ToLower ();
+ undercase.Append (tokens[i].ToLower ());
if (i < tokens.Length - 2) {
- undercase += "_";
+ undercase.Append ('_');
}
}
- return undercase;
+ return undercase.ToString ();
+ }
+
+ public static string UnderCaseToCamelCase (string s)
+ {
+ if (String.IsNullOrEmpty (s)) {
+ return null;
+ }
+
+ StringBuilder builder = new StringBuilder ();
+
+ for (int i = 0, n = s.Length, b = -1; i < n; i++) {
+ if (b < 0 && s[i] != '_') {
+ builder.Append (Char.ToUpper (s[i]));
+ b = i;
+ } else if (s[i] == '_' && i + 1 < n && s[i + 1] != '_') {
+ if (builder.Length > 0 && Char.IsUpper (builder[builder.Length - 1])) {
+ builder.Append (Char.ToLower (s[i + 1]));
+ } else {
+ builder.Append (Char.ToUpper (s[i + 1]));
+ }
+ i++;
+ b = i;
+ } else if (s[i] != '_') {
+ builder.Append (Char.ToLower (s[i]));
+ b = i;
+ }
+ }
+
+ return builder.ToString ();
}
}
}
Added: trunk/banshee/tests/Hyena/StringUtilTests.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/tests/Hyena/StringUtilTests.cs Wed Feb 27 23:53:11 2008
@@ -0,0 +1,60 @@
+using System;
+using NUnit.Framework;
+using Hyena;
+
+[TestFixture]
+public class StringUtilTests
+{
+ private class Map
+ {
+ public Map (string camel, string under)
+ {
+ Camel = camel;
+ Under = under;
+ }
+
+ public string Camel;
+ public string Under;
+ }
+
+ private Map [] u_to_c_maps = new Map [] {
+ new Map ("Hello", "hello"),
+ new Map ("HelloWorld", "hello_world"),
+ new Map ("HelloWorld", "hello__world"),
+ new Map ("HelloWorld", "hello___world"),
+ new Map ("HelloWorld", "hello____world"),
+ new Map ("HelloWorld", "_hello_world"),
+ new Map ("HelloWorld", "__hello__world"),
+ new Map ("HelloWorld", "___hello_world_"),
+ new Map ("HelloWorldHowAreYou", "_hello_World_HOW_ARE__YOU__"),
+ new Map (null, ""),
+ new Map ("H", "h")
+ };
+
+ [Test]
+ public void TestUnderCaseToCamelCase ()
+ {
+ foreach (Map map in u_to_c_maps) {
+ Assert.AreEqual (map.Camel, StringUtil.UnderCaseToCamelCase (map.Under));
+ }
+ }
+
+ private Map [] c_to_u_maps = new Map [] {
+ new Map ("Hello", "hello"),
+ new Map ("HelloWorld", "hello_world"),
+ new Map ("HiWorldHowAreYouDoingToday", "hi_world_how_are_you_doing_today"),
+ new Map ("SRSLYHowAreYou", "srsly_how_are_you"),
+ new Map ("OMGThisShitIsBananas", "omg_this_shit_is_bananas"),
+ new Map ("KTHXBAI", "kthxbai"),
+ new Map ("", null),
+ new Map ("H", "h")
+ };
+
+ [Test]
+ public void TestCamelCaseToUnderCase ()
+ {
+ foreach (Map map in c_to_u_maps) {
+ Assert.AreEqual (map.Under, StringUtil.CamelCaseToUnderCase (map.Camel));
+ }
+ }
+}
Modified: trunk/banshee/tests/Makefile.am
==============================================================================
--- trunk/banshee/tests/Makefile.am (original)
+++ trunk/banshee/tests/Makefile.am Wed Feb 27 23:53:11 2008
@@ -13,7 +13,7 @@
Hyena/CryptoUtilTests.cs \
Hyena/RangeCollectionTests.cs
-CFS=Hyena/RangeCollectionTests.cs Hyena/CryptoUtilTests.cs
+CFS=Hyena/RangeCollectionTests.cs Hyena/CryptoUtilTests.cs Hyena/StringUtilTests.cs
NUNIT_TESTER_NAME = ConsoleUi
NUNIT_TESTER = $(NUNIT_TESTER_NAME).exe
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]