[Banshee-List] improved Browser Patch for .13



Title: improved Browser Patch for .13

Hi Banshee-Lovers

Here is the improved Browser Patch for .13
it is diffed from BANSHEE_0_9_13 cvs

Dont have much time to organize the list but here are the issues got fixed

it would look nicer if the vertical scrollbar of the two lists is always one, the horizontal only when needed
a border around every list would look better too, currently the 'Artist' and 'Album' "headline" above both looks a bit lost
update the two lists when songs are added or removed :)
and disabling the match checkbox in the query doesn't show everything again
better handling of switching between library and sources. like remembering the last query etc..
smaller search button..

and more....

there are some known issues but none of them are show stoppers.

Please lemme know any problems you encounter.

Best
aydemir ulas sahin.


diff -Naur -x CVS banshee/data/glade/player.glade /home/ulas/development/banshee/data/glade/player.glade
--- banshee/data/glade/player.glade	2005-12-01 11:22:27.000000000 +0200
+++ /home/ulas/development/banshee/data/glade/player.glade	2005-12-05 22:17:48.000000000 +0200
@@ -954,28 +954,95 @@
 		      <property name="spacing">5</property>
 
 		      <child>
-			<widget class="GtkHBox" id="PlaylistHeaderBox">
+			<widget class="GtkVBox" id="HeaderVBox">
 			  <property name="visible">True</property>
 			  <property name="homogeneous">False</property>
-			  <property name="spacing">5</property>
+			  <property name="spacing">0</property>
 
 			  <child>
-			    <widget class="GtkLabel" id="ViewNameLabel">
+			    <widget class="GtkHBox" id="HeaderHBox">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">&lt;b&gt;Playlist&lt;/b&gt;</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">True</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
+			      <property name="homogeneous">False</property>
+			      <property name="spacing">0</property>
+
+			      <child>
+				<widget class="GtkExpander" id="CustomExpander">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="expanded">False</property>
+				  <property name="spacing">0</property>
+
+				  <child>
+				    <placeholder/>
+				  </child>
+
+				  <child>
+				    <widget class="GtkLabel" id="ViewNameLabel">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">&lt;b&gt;Library&lt;/b&gt;</property>
+				      <property name="use_underline">False</property>
+				      <property name="use_markup">True</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0.5</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="type">label_item</property>
+				    </packing>
+				  </child>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">True</property>
+				  <property name="fill">True</property>
+				</packing>
+			      </child>
+
+			      <child>
+				<widget class="GtkHBox" id="PlaylistHeaderBox">
+				  <property name="visible">True</property>
+				  <property name="homogeneous">False</property>
+				  <property name="spacing">0</property>
+
+				  <child>
+				    <widget class="GtkLabel" id="SearchLabel">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">Search:</property>
+				      <property name="use_underline">False</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0.5</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+				      <property name="width_chars">-1</property>
+				      <property name="single_line_mode">False</property>
+				      <property name="angle">0</property>
+				    </widget>
+				    <packing>
+				      <property name="padding">0</property>
+				      <property name="expand">False</property>
+				      <property name="fill">False</property>
+				    </packing>
+				  </child>
+				</widget>
+				<packing>
+				  <property name="padding">0</property>
+				  <property name="expand">False</property>
+				  <property name="fill">False</property>
+				</packing>
+			      </child>
 			    </widget>
 			    <packing>
 			      <property name="padding">0</property>
@@ -983,31 +1050,6 @@
 			      <property name="fill">True</property>
 			    </packing>
 			  </child>
-
-			  <child>
-			    <widget class="GtkLabel" id="SearchLabel">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Search:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
 			</widget>
 			<packing>
 			  <property name="padding">0</property>
@@ -1017,30 +1059,57 @@
 		      </child>
 
 		      <child>
-			<widget class="GtkAlignment" id="LibraryAlignment">
+			<widget class="GtkVPaned" id="VPane">
 			  <property name="visible">True</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xscale">1</property>
-			  <property name="yscale">1</property>
-			  <property name="top_padding">0</property>
-			  <property name="bottom_padding">0</property>
-			  <property name="left_padding">0</property>
-			  <property name="right_padding">0</property>
+			  <property name="can_focus">True</property>
+			  <property name="position">200</property>
 
 			  <child>
-			    <widget class="GtkScrolledWindow" id="LibraryContainer">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-			      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-			      <property name="shadow_type">GTK_SHADOW_IN</property>
-			      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+			    <widget class="GtkVBox" id="DisclosureBox">
+			      <property name="homogeneous">False</property>
+			      <property name="spacing">0</property>
 
 			      <child>
 				<placeholder/>
 			      </child>
 			    </widget>
+			    <packing>
+			      <property name="shrink">False</property>
+			      <property name="resize">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkAlignment" id="LibraryAlignment">
+			      <property name="visible">True</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xscale">1</property>
+			      <property name="yscale">1</property>
+			      <property name="top_padding">0</property>
+			      <property name="bottom_padding">0</property>
+			      <property name="left_padding">0</property>
+			      <property name="right_padding">0</property>
+
+			      <child>
+				<widget class="GtkScrolledWindow" id="LibraryContainer">
+				  <property name="visible">True</property>
+				  <property name="can_focus">True</property>
+				  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+				  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+				  <property name="shadow_type">GTK_SHADOW_IN</property>
+				  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+				  <child>
+				    <placeholder/>
+				  </child>
+				</widget>
+			      </child>
+			    </widget>
+			    <packing>
+			      <property name="shrink">True</property>
+			      <property name="resize">True</property>
+			    </packing>
 			  </child>
 			</widget>
 			<packing>
diff -Naur -x CVS banshee/src/ArtistAlbumBrowser.cs /home/ulas/development/banshee/src/ArtistAlbumBrowser.cs
--- banshee/src/ArtistAlbumBrowser.cs	1970-01-01 02:00:00.000000000 +0200
+++ /home/ulas/development/banshee/src/ArtistAlbumBrowser.cs	2005-12-05 22:17:48.000000000 +0200
@@ -0,0 +1,318 @@
+// created on 11/19/2005 at 1:26 AM by Aydemir Ulas Sahin
+
+using System;
+using System.Data;
+using System.IO;
+using System.Collections;
+using GLib;
+using Gtk;
+using Mono.Unix;
+using Sql;
+
+namespace Banshee
+{	
+	public class ArtistAlbumBrowser : VBox
+	{	
+		private Gtk.HBox main_box = new Gtk.HBox();
+		private Gtk.ScrolledWindow artist_scroller = new Gtk.ScrolledWindow();
+		private Gtk.ScrolledWindow album_scroller = new Gtk.ScrolledWindow();
+		private Gtk.TreeView artist_tree = new Gtk.TreeView();
+		private Gtk.TreeView album_tree = new Gtk.TreeView();
+		
+		private ListStore artist_store;
+		private ListStore album_store;
+		
+		private string artist_selected = "none";
+		private string album_selected = "none";
+		
+		private int artist_selection_index = 0;
+		private int album_selection_index = 0;
+		
+		private Statement query;
+		private string library_query;
+		
+		private int [] ResetSelectPath = {0};
+		
+		public event EventHandler BrowserClicked;
+		
+		public ArtistAlbumBrowser() : base()
+		{
+			BuildUI();
+			Init();
+		}
+			
+		public string Query
+		{
+			get {
+				return library_query;
+			}
+			set {
+				library_query = value;
+			}
+		}
+			
+		private void BuildUI()
+		{
+			artist_scroller.HscrollbarPolicy = PolicyType.Automatic;
+			artist_scroller.VscrollbarPolicy = PolicyType.Always;
+			artist_scroller.ShadowType = ShadowType.EtchedIn;	
+			artist_scroller.BorderWidth = 3;
+			
+			album_scroller.HscrollbarPolicy = PolicyType.Automatic;			
+			album_scroller.VscrollbarPolicy = PolicyType.Always;
+			album_scroller.ShadowType = ShadowType.EtchedIn;
+			album_scroller.BorderWidth = 3;
+			
+			artist_tree.HeadersVisible = true;
+			artist_tree.AppendColumn(Catalog.GetString("Artist"), new CellRendererText(), "text", 0);
+			artist_store = CreateStore();
+			artist_tree.Model = artist_store;
+			artist_tree.CursorChanged += OnArtistCursorChanged;
+			artist_scroller.Add(artist_tree);
+			
+			album_tree.HeadersVisible = true;
+			album_tree.AppendColumn(Catalog.GetString("Album"), new CellRendererText(), "text", 0);
+			album_store = CreateStore();
+			album_tree.Model = album_store;
+			album_tree.CursorChanged += OnAlbumCursorChanged;
+			album_scroller.Add(album_tree);
+			
+			main_box.PackStart(artist_scroller, true, true, 0);
+			main_box.PackStart(album_scroller, true, true, 0);					
+			
+			PackStart(main_box, true, true, 0);
+			Spacing = 5;
+			
+		}
+			
+		private void Init()
+		{
+			query = new Select("Tracks", new Statement("DISTINCT Artist"));
+			PopulateArtistStore(false);
+			PopulateAlbumStore(false);
+			
+			artist_tree.Selection.SelectPath(new TreePath(ResetSelectPath));
+			album_tree.Selection.SelectPath(new TreePath(ResetSelectPath));
+			
+			this.ShowAll();
+		}
+		
+		public void Reset()
+		{
+			query = new Select("Tracks", new Statement("DISTINCT Artist"));
+			artist_tree.Selection.SelectPath(new TreePath(ResetSelectPath));
+			artist_tree.ScrollToPoint(0,0);
+			album_tree.Selection.SelectPath(new TreePath(ResetSelectPath));
+			album_tree.ScrollToPoint(0,0);
+		}
+		
+		public void Update(bool isFiltered)
+		{
+			query = new Select("Tracks", new Statement("DISTINCT Artist"));
+			PopulateArtistStore(true);
+			PopulateAlbumStore(true);
+			if(isFiltered) {
+				RunQuery();
+			}
+		}
+		
+		public bool FilterStatus()
+		{
+			if(artist_selection_index == 0 && album_selection_index == 0) {
+				return false;
+			} else {
+				return true;
+			}
+		}
+		
+		private ListStore CreateStore()
+		{
+			ListStore store = new ListStore(typeof(string));
+				
+			//We dont need a sort for this view but in case anyone asks...
+			/*		
+			store.SetSortFunc(1, delegate(TreeModel model, TreeIter a, TreeIter b) {
+			try {
+			String a_string = (String)store.GetValue(a, 1);
+			String b_string = (String)store.GetValue(b, 1);
+			return String.Compare(a_string, b_string);
+			} catch(Exception) {
+			return 0;
+			}
+			});
+			store.SetSortColumnId(1, SortType.Descending);
+			*/
+			return store;
+		}
+		
+		private void PopulateArtistStore(bool isUpdate)
+		{
+			artist_store.Clear();
+			ArrayList artistlist = new ArrayList();
+			try 
+			{
+				IDataReader reader = Core.Library.Db.Query(query);
+				while(reader.Read())
+				{
+					artistlist.Add((reader[0] as string));
+				}
+			} catch(Exception) {
+			
+			}
+			
+			AddEntry("All", true, artist_store);
+			foreach(string entry in artistlist) {
+				AddEntry(entry, false, artist_store);
+			}
+			if (isUpdate) {
+				UpdateArtistList();
+			}
+			else {
+				ResetArtistList();
+			}
+				
+		}
+		
+		private void PopulateAlbumStore(bool isUpdate)
+		{
+			album_store.Clear();
+			ArrayList albumlist = new ArrayList();
+			if (artist_selection_index == 0)
+			{
+				query = new Select("Tracks", new Statement("DISTINCT AlbumTitle, Artist"));
+			}
+			else
+			{
+				query = new Select("Tracks", new Statement("DISTINCT AlbumTitle, Artist"))
+				+ new Where(new Compare("Artist", Op.EqualTo, artist_selected));
+			} 
+		
+			try 
+			{
+				IDataReader reader = Core.Library.Db.Query(query);
+				while(reader.Read())
+				{              
+					albumlist.Add((reader[0] as string));
+				}
+		
+			} catch(Exception) {
+			
+			}
+						
+			AddEntry("All", true, album_store);
+			foreach(string entry in albumlist) {
+				AddEntry(entry, false, album_store);
+			}
+			if (isUpdate) {
+				UpdateAlbumList();
+			}
+			else {
+				ResetAlbumList();
+			}
+				
+		}
+        
+		private void UpdateAlbumList()
+		{
+			int [] UpdateSelectPath = {album_selection_index };
+			album_tree.Selection.SelectPath(new TreePath(UpdateSelectPath));
+		}
+		
+		private void UpdateArtistList()
+		{
+			int [] UpdateSelectPath = {artist_selection_index };
+			artist_tree.Selection.SelectPath(new TreePath(UpdateSelectPath));
+		}
+		
+		private void ResetAlbumList()
+		{
+			album_tree.Selection.SelectPath(new TreePath(ResetSelectPath));
+			TreePath[] treeIndex = album_tree.Selection.GetSelectedRows();
+			album_selection_index = treeIndex[0].Indices[0];
+		}
+		
+		private void ResetArtistList()
+		{
+			artist_tree.Selection.SelectPath(new TreePath(ResetSelectPath));
+			TreePath[] treeIndex = artist_tree.Selection.GetSelectedRows();
+			artist_selection_index = treeIndex[0].Indices[0];
+		}
+			
+		private void AddEntry(string entry, bool prepend,ListStore store)
+		{   
+			TreeIter iter = prepend ? store.Insert(0) : store.Append();
+			store.SetValue(iter, 0, entry);
+		}
+		
+		private void OnArtistCursorChanged(object o, EventArgs args)
+		{
+			TreeIter iter;
+			if(!artist_tree.Selection.GetSelected(out iter)) {
+				return;
+			}
+		
+			object artist_name = artist_store.GetValue(iter, 0);
+			artist_selected = (artist_name as string);
+		
+			TreePath[] treeIndex = artist_tree.Selection.GetSelectedRows();
+			artist_selection_index = treeIndex[0].Indices[0];
+		
+			if(artist_name == null) {
+				return;
+			}
+            
+			PopulateAlbumStore(false);
+			RunQuery();
+		}
+        
+		private void OnAlbumCursorChanged(object o, EventArgs args)
+		{
+			TreeIter iter;
+			if(!album_tree.Selection.GetSelected(out iter)) {
+				return;
+			}
+		
+			object album_name = album_store.GetValue(iter, 0);
+			album_selected = (album_name as string);
+			
+			TreePath[] treeIndex = album_tree.Selection.GetSelectedRows();
+			album_selection_index = treeIndex[0].Indices[0];
+		
+			if(album_name == null) {
+				return;
+			}
+		
+			RunQuery();
+		}
+		
+		private void RunQuery()
+		{
+			query = new Select("Tracks");
+			if (artist_selection_index != 0)
+			{
+				query += new Where( 
+				+ new Compare("Artist", Op.EqualTo, artist_selected));
+			}
+			
+			if (album_selection_index != 0)
+			{
+				query += new Where( 
+				+ new Compare("AlbumTitle", Op.EqualTo, album_selected));
+			}
+			
+			if (artist_selection_index != 0 && album_selection_index != 0)
+			{
+				query = new Select("Tracks") + new Where( new Compare("AlbumTitle", Op.EqualTo, album_selected) 
+				+ new And() + new Compare("Artist", Op.EqualTo, artist_selected));	
+			}
+			
+			library_query = query.ToString();
+			
+			EventHandler handler = BrowserClicked;
+			if(handler != null)
+				handler(this, new EventArgs());		
+		}
+			
+	}
+}
+	
\ No newline at end of file
diff -Naur -x CVS banshee/src/BrowserNoteBook.cs /home/ulas/development/banshee/src/BrowserNoteBook.cs
--- banshee/src/BrowserNoteBook.cs	1970-01-01 02:00:00.000000000 +0200
+++ /home/ulas/development/banshee/src/BrowserNoteBook.cs	2005-12-05 22:17:48.000000000 +0200
@@ -0,0 +1,94 @@
+// created on 11/19/2005 at 1:26 AM by Aydemir Ulas Sahin
+
+using System;
+using GLib;
+using Gtk;
+using Mono.Unix;
+using Sql;
+
+namespace Banshee
+{	
+	public delegate void QueryTransactionHandler(object o, QueryTransactionEventArgs args);
+	
+	public class QueryTransactionEventArgs : EventArgs
+	{
+		public Statement query;
+	}
+    
+	public class BrowserNoteBook : Notebook
+	{
+		private SqlBuilderUI query_builder;
+		private ArtistAlbumBrowser browser;
+		private VBox queryHolder = new VBox();
+		
+		public event QueryTransactionHandler QueryTransactionComplete;
+		
+		public BrowserNoteBook() : base()
+		{
+			BuildUI();
+		}
+		
+		private void BuildUI()
+		{
+			browser = new ArtistAlbumBrowser();
+			browser.HeightRequest = 150;
+			browser.BrowserClicked += OnBrowserClicked;
+			query_builder = new SqlBuilderUI(queryHolder);
+			query_builder.SearchButtonClicked += OnSearchButtonClicked;
+			
+			AppendPage(browser, new Gtk.Label(Catalog.GetString("Browser")));
+			AppendPage(queryHolder, new Gtk.Label(Catalog.GetString("Query")));
+			
+			ShowAll();
+		}
+		
+		private void OnSearchButtonClicked(object o, EventArgs args)
+		{
+			string query = query_builder.Query;    	
+ 			Statement query_statement = new Statement(query);
+ 			QueryLibrary(query_statement);	
+		}
+         
+		private void OnBrowserClicked(object o, EventArgs args)
+		{
+			string query = browser.Query;     	
+ 			Statement query_statement = new Statement(query);
+ 			QueryLibrary(query_statement);
+		}
+         
+		public void QueryLibrary(Statement query)
+		{
+			QueryTransactionHandler handler = QueryTransactionComplete;
+			QueryTransactionEventArgs query_args = new QueryTransactionEventArgs();
+			query_args.query = query;
+			if(handler != null)
+				handler(this, query_args);
+		
+		}
+		
+		public void BrowserReset()
+		{
+			browser.Reset();
+		}
+		
+		public void BrowserUpdate()
+		{
+			browser.Update(false);
+		}
+		
+		public void BrowserFilter()
+		{
+			browser.Update(true);
+		}
+		
+		public bool BrowserHasFilter()
+		{
+			return browser.FilterStatus();
+		}
+		
+		public void Active(bool status)
+		{
+			this.Sensitive = status;
+		}
+	}
+}
diff -Naur -x CVS banshee/src/LibraryTransactions.cs /home/ulas/development/banshee/src/LibraryTransactions.cs
--- banshee/src/LibraryTransactions.cs	2005-11-26 04:09:56.000000000 +0200
+++ /home/ulas/development/banshee/src/LibraryTransactions.cs	2005-12-05 22:17:48.000000000 +0200
@@ -485,7 +485,7 @@
     
     abstract public class TrackRemoveTransaction : LibraryTransaction
     {
-        public ArrayList RemoveQueue;
+	public ArrayList RemoveQueue;
         
         public TrackRemoveTransaction()
         {
@@ -496,7 +496,7 @@
     
     public class LibraryTrackRemoveTransaction : TrackRemoveTransaction
     {
-        public override string Name
+	public override string Name
         {
             get {
                 return Catalog.GetString("Library Track Remove");
@@ -528,6 +528,7 @@
             currentCount = 0;
             totalCount = 0;
             Core.Library.Db.Execute(query);
+	    
         }
     }
     
@@ -768,4 +769,64 @@
             return count;
         }    
     }
+    
+    public class SqlQueryTransaction : LibraryTransaction
+ 	{
+ 		private string sql;
+ 		public event HaveTrackInfoHandler HaveTrackInfo;
+ 		
+ 		public override string Name {
+ 			get {
+ 				return Catalog.GetString("Library Track Loader");
+ 			}
+ 		}
+ 		
+ 		public SqlQueryTransaction(string sql)
+ 		{
+ 		    showStatus = false;
+ 			this.sql = sql;
+ 		}
+ 		
+ 		public SqlQueryTransaction(Statement sql) : this(sql.ToString())
+ 		{
+ 		
+ 		}
+ 		
+ 		public override void Run()
+ 		{
+ 			statusMessage = Catalog.GetString("Processing");
+ 			FilterSql();
+ 		}
+ 		
+ 		private void RaiseTrackInfo(TrackInfo ti)
+ 		{
+ 			statusMessage = String.Format(
+ 				Catalog.GetString("Loading {0} - {1} ..."),
+ 				ti.Artist, ti.Title);
+ 			currentCount++;
+ 			
+ 			HaveTrackInfoHandler handler = HaveTrackInfo;
+ 			if(handler != null) {
+ 				HaveTrackInfoArgs args = new HaveTrackInfoArgs();
+ 				args.TrackInfo = ti;
+ 				handler(this, args);
+ 			}
+ 		}
+ 		
+ 		
+ 		private void FilterSql()
+ 		{
+ 			IDataReader reader = Core.Library.Db.Query(sql);
+ 			while(reader.Read() && !cancelRequested) {
+ 				DateTime startStamp = DateTime.Now;
+                int tid = Convert.ToInt32(reader[0]);
+                TrackInfo ti = Core.Library.Tracks[tid] as TrackInfo;
+                
+                if(ti != null) {
+                    RaiseTrackInfo(ti);
+                    UpdateAverageDuration(startStamp);
+                }
+ 			}
+ 		}
+ 	}	
 }
diff -Naur -x CVS banshee/src/Makefile.am /home/ulas/development/banshee/src/Makefile.am
--- banshee/src/Makefile.am	2005-12-01 11:22:29.000000000 +0200
+++ /home/ulas/development/banshee/src/Makefile.am	2005-12-05 22:17:48.000000000 +0200
@@ -69,6 +69,8 @@
 	ThemeIcons.cs \
 	VersionInformationDialog.cs \
 	LogCoreViewer.cs \
+	ArtistAlbumBrowser.cs \
+	BrowserNoteBook.cs \
 	FileSystemMonitor/Watcher.cs \
 	FileSystemMonitor/Inotify.cs \
 	FileSystemMonitor/Watch.cs \
diff -Naur -x CVS banshee/src/PlayerInterface.cs /home/ulas/development/banshee/src/PlayerInterface.cs
--- banshee/src/PlayerInterface.cs	2005-12-01 11:22:29.000000000 +0200
+++ /home/ulas/development/banshee/src/PlayerInterface.cs	2005-12-05 22:17:48.000000000 +0200
@@ -62,6 +62,9 @@
         [Widget] private Gtk.Label LabelStatusBar;
         [Widget] private HPaned SourceSplitter;
         [Widget] private Button HeaderCycleButton;
+        [Widget] private Expander CustomExpander;
+        [Widget] private Gtk.VBox DisclosureBox;
+        
 
         private PlaylistModel playlistModel;
 
@@ -92,6 +95,8 @@
         private CoverArtThumbnail cover_art;
         
         private bool incrementedCurrentSongPlayCount;
+        
+        private BrowserNoteBook browser_notebook;
     
         public Gtk.Window Window
         {
@@ -404,7 +409,16 @@
             searchEntry.Show();
             ((HBox)gxml["PlaylistHeaderBox"]).PackStart(searchEntry, 
                 false, false, 0);
-                
+            
+            // Custom Expander and browser related stuff.
+            CustomExpander = ((Expander)gxml["CustomExpander"]);
+            DisclosureBox = ((VBox)gxml["DisclosureBox"]);
+            CustomExpander.Activated += OnExpandAreaClicked;
+            browser_notebook = new BrowserNoteBook();
+            browser_notebook.QueryTransactionComplete += OnQueryTransactionComplete;
+            DisclosureBox.Add(browser_notebook);
+
+                    
             // Repeat/Shuffle buttons
             
             repeat_toggle_button = new MultiStateToggleButton();
@@ -544,6 +558,11 @@
             }
         }
         
+        private void OnQueryTransactionComplete(object o, QueryTransactionEventArgs args)
+        {
+          	playlistModel.LoadFromQuery(args.query);
+        }
+        
         private void ConnectToLibraryTransactionManager()
         {
             Core.Library.TransactionManager.ExecutionStackChanged += OnLTMExecutionStackChanged;
@@ -767,6 +786,17 @@
                         handled = true;
                     } 
                     break;
+                case Gdk.Key.F5:
+                    if((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+                        if (CustomExpander.Expanded) {
+                        	CustomExpander.Expanded = false;
+                        } else {
+                        	CustomExpander.Expanded = true;
+                        }
+                        OnExpandAreaClicked(this, new EventArgs());
+                        handled = true;
+                    } 
+                    break;
                 case Gdk.Key.space:
                     if(!searchEntry.HasFocus) {
                         PlayPause();
@@ -1108,13 +1138,22 @@
             if(sourceView.SelectedSource.Type == SourceType.Library &&
                 searchEntry.Query == String.Empty) {
                 playlistModel.AddFile(path);
+		playlistModel.FileAdded += OnFileAdded;	
             } else {
                 FileLoadTransaction loader = new FileLoadTransaction(path);
                 loader.HaveTrackInfo += OnLoaderHaveTrackInfo;
+		loader.Finished += OnFileAdded;    
                 loader.Register();
             }
         }
         
+	private void OnFileAdded(object o, EventArgs args)
+        {
+	    Application.Invoke(delegate {
+                browser_notebook.BrowserUpdate();
+            });
+        }
+	
         private void OnLoaderHaveTrackInfo(object o, HaveTrackInfoArgs args)
         {
             sourceView.QueueDraw();
@@ -1235,9 +1274,15 @@
             searchEntry.CancelSearch(false);
                 
             if(source.Type == SourceType.Library) {
-                playlistModel.LoadFromLibrary();
+		if(!browser_notebook.BrowserHasFilter()) {
+			playlistModel.LoadFromLibrary();
+		}
                 playlistModel.Source = source;
-               
+		browser_notebook.Active(true);
+		Application.Invoke(delegate {
+			browser_notebook.BrowserFilter();
+		});
+		
                 (gxml["ViewNameLabel"] as Label).Markup = 
                     String.Format(Catalog.GetString("<b>{0}'s Music Library</b>"),
                     GLib.Markup.EscapeText(Core.Instance.UserFirstName));
@@ -1247,15 +1292,17 @@
                 DapSource dap_source = source as DapSource;
                 playlistModel.LoadFromDapSource(dap_source);
                 UpdateDapDiskUsageBar(dap_source);
+		browser_notebook.Active(false);
             } else if(source.Type == SourceType.AudioCd) {
                 playlistModel.Clear();
                 playlistModel.Source = source;
-                
                 AudioCdSource cdSource = source as AudioCdSource;
                 playlistModel.LoadFromAudioCdSource(cdSource);
+		browser_notebook.Active(false);
             } else {
                 playlistModel.LoadFromPlaylist(source.Name);
                 playlistModel.Source = source;
+		browser_notebook.Active(false);
             }
             
             (gxml["ViewNameLabel"] as Label).Markup = 
@@ -1706,15 +1753,18 @@
                     } catch(Exception) {}
                 }
             }
-            
-            transaction.Finished += OnLibraryTrackRemoveFinished;
+		
+	    transaction.Finished += OnLibraryTrackRemoveFinished;
             transaction.Register();
         }
         
         private void OnLibraryTrackRemoveFinished(object o, EventArgs args)
         {
-            playlistView.QueueDraw();
+	    playlistView.QueueDraw();
             sourceView.QueueDraw();
+	    Application.Invoke(delegate { 
+		browser_notebook.BrowserUpdate();
+	    });
         }
         
         private void OnItemPropertiesActivate(object o, EventArgs args)
@@ -2483,5 +2533,17 @@
             alignment.Add(syncing_container);
             alignment.ShowAll();
         }
+        
+        private void OnExpandAreaClicked (object sender, EventArgs args)
+		{
+			if (CustomExpander.Expanded)
+			{
+				DisclosureBox.Visible = true;
+			}
+			else
+			{
+				DisclosureBox.Visible = false;
+			}	
+		}
     }
 }
diff -Naur -x CVS banshee/src/PlaylistModel.cs /home/ulas/development/banshee/src/PlaylistModel.cs
--- banshee/src/PlaylistModel.cs	2005-12-01 11:22:29.000000000 +0200
+++ /home/ulas/development/banshee/src/PlaylistModel.cs	2005-12-05 22:17:48.000000000 +0200
@@ -61,6 +61,8 @@
         public Source Source;
         
         public event EventHandler Updated;
+	public event EventHandler FileAdded;
+        
         
         public static int NextUid
         {
@@ -131,7 +133,7 @@
         {
             if(o == importTransaction && !canUpdate)
                 return;
-                
+		
             QueueAddTrack(args.TrackInfo);
         }
 
@@ -155,10 +157,18 @@
         
         public void AddFile(string path)
         {
-            importTransaction = new FileLoadTransaction(path);
+	    importTransaction = new FileLoadTransaction(path);
             importTransaction.HaveTrackInfo += OnLoaderHaveTrackInfo;
+	    importTransaction.Finished += OnLoaderAddFileFinished;
             importTransaction.Register();    
         }
+	
+	private void OnLoaderAddFileFinished(object o, EventArgs args)
+        {
+	    EventHandler handler = FileAdded;
+            if(handler != null)
+                handler(o, args);	
+        }
         
         public void AddSql(object query)
         {
@@ -168,6 +178,14 @@
             Core.Library.TransactionManager.Register(loader);
         }
         
+        public void LoadFromQuery(Statement query)
+        {
+            ClearModel();
+            SqlQueryTransaction loader = new SqlQueryTransaction(query);
+            loader.HaveTrackInfo += OnLoaderHaveTrackInfo;
+            Core.Library.TransactionManager.Register(loader);
+        }
+        
         public void LoadFromPlaylist(string name)
         {
             ClearModel();
@@ -175,7 +193,7 @@
             loader.HaveTrackInfo += OnLoaderHaveTrackInfo;
             Core.Library.TransactionManager.Register(loader);
         }
-        
+          
         public void LoadFromLibrary()
         {
             ClearModel();
diff -Naur -x CVS banshee/src/QueryBuilder.cs /home/ulas/development/banshee/src/QueryBuilder.cs
--- banshee/src/QueryBuilder.cs	2005-08-31 18:54:46.000000000 +0300
+++ /home/ulas/development/banshee/src/QueryBuilder.cs	2005-12-05 22:17:48.000000000 +0200
@@ -349,6 +349,13 @@
 			return query;
 		}
 	}
+	
+	public class QueryStatusArgs : EventArgs
+	{
+		public bool QueryStatus;
+	}
+	
+	public delegate void QueryStatusChangedHandler(object o, QueryStatusArgs args);
 
 	public class QueryBuilder : VBox
 	{
@@ -363,6 +370,10 @@
 		private Entry limitEntry;
 		private ComboBox limitComboBox;
 		private ComboBox orderComboBox;
+		
+		private Button searchButton;
+			
+		public event QueryStatusChangedHandler QueryStatusChanged;
 	
 		public QueryBuilder(QueryBuilderModel model) : base()
 		{
@@ -450,19 +461,38 @@
 				orderComboBox.AppendText(order);
 			orderComboBox.Active = 0;
 			limitFooter.PackStart(orderComboBox, false, false, 0);
-				
+			
+			searchButton = new Button("Search");
+			searchButton.Clicked += OnSearchButtonClicked;
+			searchButton.Show();
+			limitFooter.PackStart(searchButton, true, true, 0);
+			
 			limitCheckBox.Active = false;
 			OnLimitCheckBoxToggled(limitCheckBox, null);
 				
 			return limitFooter;
 		}
 		
+		private void OnSearchButtonClicked(object o, EventArgs args)
+		{
+			QueryStatusChangedHandler handler = QueryStatusChanged;
+			QueryStatusArgs statusArgs = new QueryStatusArgs();
+			statusArgs.QueryStatus = matchCheckBox.Active;
+			if(handler != null)
+				handler(o, statusArgs);
+		}
+		
 		private void OnMatchCheckBoxToggled(object o, EventArgs args)
 		{
 			matchesBox.Sensitive = matchCheckBox.Active;
 			matchLogicCombo.Sensitive = matchCheckBox.Active;
 			matchLabelFollowing.Sensitive = matchCheckBox.Active;
-		}
+			QueryStatusChangedHandler handler = QueryStatusChanged;
+			QueryStatusArgs statusArgs = new QueryStatusArgs();
+			statusArgs.QueryStatus = matchCheckBox.Active;
+			if(handler != null)
+				handler(o, statusArgs);
+			}
 		
 		private void OnLimitCheckBoxToggled(object o, EventArgs args)
 		{
diff -Naur -x CVS banshee/src/QueryBuilderModel.cs /home/ulas/development/banshee/src/QueryBuilderModel.cs
--- banshee/src/QueryBuilderModel.cs	2005-11-17 11:16:46.000000000 +0200
+++ /home/ulas/development/banshee/src/QueryBuilderModel.cs	2005-12-05 22:17:48.000000000 +0200
@@ -30,11 +30,12 @@
 using System;
 using GLib;
 using Gtk;
-using Sql;
 using System.Collections;
+using Sql;
 
 using Banshee.Widgets;
 
+
 namespace Banshee
 {
 	public sealed class QueryFilterOperation
@@ -128,9 +129,9 @@
 		{
 			get {	
 				string [] validOperations = {
+					QueryFilterOperation.Contains,
 					QueryFilterOperation.Is,
 					QueryFilterOperation.IsNot,
-					QueryFilterOperation.Contains,
 					QueryFilterOperation.DoesNotContain,
 					QueryFilterOperation.StartsWith,
 					QueryFilterOperation.EndsWith
@@ -274,7 +275,21 @@
 	{
 		private QueryBuilder builder;
 		private TracksQueryModel model;
-	
+		
+		private string built_query;
+ 		public event EventHandler SearchButtonClicked;
+		
+		
+		public string Query
+		{
+			get {
+				return built_query;
+			}
+			set {
+				built_query = value;
+			}
+		}
+		
 		public SqlBuilderUI()
 		{
 			Window win = new Window("SQL Builder");
@@ -300,6 +315,23 @@
 			btn.Clicked += OnButtonClicked;	
 		}
 		
+		public SqlBuilderUI(VBox parentVBox)
+ 		{	
+ 			VBox box = new VBox();
+ 			box.Show();
+ 			parentVBox.Add(box);
+ 			box.Spacing = 10;
+ 			
+ 			model = new TracksQueryModel();
+ 			builder = new QueryBuilder(model);
+			builder.QueryStatusChanged += OnQueryStatusChanged;
+ 			builder.Show();
+ 			builder.Spacing = 4;
+ 			
+ 			box.PackStart(builder, true, true, 0);
+ 	
+ 		}
+		
 		private void OnButtonClicked(object o, EventArgs args)
 		{
 			string query = "SELECT * FROM Tracks";
@@ -311,8 +343,17 @@
 			
 			if(builder.Limit && builder.LimitNumber > 0)
 				query += " LIMIT " + builder.LimitNumber;
-			
-			Console.WriteLine(query);
+				
+			built_query = query;
+
+			EventHandler handler = SearchButtonClicked;
+			if(handler != null)
+				handler(this, new EventArgs());
+		}
+		
+		private void OnQueryStatusChanged(object o, QueryStatusArgs args)
+		{
+			OnButtonClicked(this, new EventArgs());
 		}
 	}
 }


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