rhythmbox r5729 - in trunk: . rhythmdb sources



Author: jmatthew
Date: Sun Jun  8 14:37:16 2008
New Revision: 5729
URL: http://svn.gnome.org/viewvc/rhythmbox?rev=5729&view=rev

Log:
2008-06-09  Jonathan Matthew  <jonathan d14n org>

	* rhythmdb/rhythmdb-query-model.c:
	(rhythmdb_query_model_class_init),
	(rhythmdb_query_model_drag_data_received):
	* rhythmdb/rhythmdb-query-model.h:
	Add a new signal, 'filter-entry-drop', allowing model owners (sources,
	mostly) to filter out existing entries being dropped in.

	* sources/rb-source.c: (_rb_source_check_entry_type):
	* sources/rb-source.h:
	Add a helper function for checking entry types against a source's
	entry type.

	* sources/rb-playlist-source.c:
	(rb_playlist_source_entry_added_cb):
	Filter out newly added entries that don't match the playlist's entry
	type, but were in the location map (drag and drop from outside
	rhythmbox).

	* sources/rb-static-playlist-source.c:
	(rb_static_playlist_source_constructor),
	(rb_static_playlist_source_add_location_internal),
	(rb_static_playlist_source_filter_entry_drop):
	Use the query model filter-entry-drop signal to filter out drops of
	entries that don't match the playlist entry type.  Fixes #508267.


Modified:
   trunk/ChangeLog
   trunk/rhythmdb/rhythmdb-query-model.c
   trunk/rhythmdb/rhythmdb-query-model.h
   trunk/sources/rb-playlist-source.c
   trunk/sources/rb-source.c
   trunk/sources/rb-source.h
   trunk/sources/rb-static-playlist-source.c

Modified: trunk/rhythmdb/rhythmdb-query-model.c
==============================================================================
--- trunk/rhythmdb/rhythmdb-query-model.c	(original)
+++ trunk/rhythmdb/rhythmdb-query-model.c	Sun Jun  8 14:37:16 2008
@@ -270,6 +270,7 @@
 	ENTRY_REMOVED,
 	NON_ENTRY_DROPPED,
 	POST_ENTRY_DELETE,
+	FILTER_ENTRY_DROP,
 	LAST_SIGNAL
 };
 
@@ -403,6 +404,25 @@
 			      g_cclosure_marshal_VOID__BOXED,
 			      G_TYPE_NONE,
 			      1, RHYTHMDB_TYPE_ENTRY);
+	/**
+	 * RhythmDBQueryModel::filter-entry-drop:
+	 * @model: the #RhythmDBQueryModel
+	 * @entry: the #RhythmDBEntry being dropped
+	 *
+	 * Emitted when an entry is being added to a model by drag-and-drop.
+	 * This allows the owner of the model to filter out entries that should
+	 * not be added to the model (based on entry type, for instance).
+	 * If the signal handler returns %FALSE, the entry will not be added.
+	 */
+	rhythmdb_query_model_signals[FILTER_ENTRY_DROP] =
+		g_signal_new ("filter-entry-drop",
+			      RHYTHMDB_TYPE_QUERY_MODEL,
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RhythmDBQueryModelClass, filter_entry_drop),
+			      NULL, NULL,
+			      rb_marshal_BOOLEAN__BOXED,
+			      G_TYPE_BOOLEAN,
+			      1, RHYTHMDB_TYPE_ENTRY);
 
 	g_type_class_add_private (klass, sizeof (RhythmDBQueryModelPrivate));
 }
@@ -1889,8 +1909,20 @@
 
 				old_ptr = g_hash_table_lookup (model->priv->reverse_map, entry);
 				/* trying to drag drop an entry on itself ! */
-				if (old_ptr == ptr)
+				if (old_ptr == ptr) {
 					continue;
+				} else if (old_ptr == NULL) {
+					gboolean allow;
+
+					g_signal_emit (G_OBJECT (model),
+						       rhythmdb_query_model_signals[FILTER_ENTRY_DROP],
+						       0, entry, &allow);
+					if (allow == FALSE) {
+						rb_debug ("dropping of entry %s disallowed by filter",
+							  rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+						continue;
+					}
+				}
 
 				/* take temporary ref */
 				rhythmdb_entry_ref (entry);

Modified: trunk/rhythmdb/rhythmdb-query-model.h
==============================================================================
--- trunk/rhythmdb/rhythmdb-query-model.h	(original)
+++ trunk/rhythmdb/rhythmdb-query-model.h	Sun Jun  8 14:37:16 2008
@@ -86,6 +86,8 @@
 					 RhythmDBEntry *entry);
 	void	(*post_entry_delete)	(RhythmDBQueryModel *model,
 					 RhythmDBEntry *entry);
+	gboolean (*filter_entry_drop)	(RhythmDBQueryModel *model,
+					 RhythmDBEntry *entry);
 
 } RhythmDBQueryModelClass;
 

Modified: trunk/sources/rb-playlist-source.c
==============================================================================
--- trunk/sources/rb-playlist-source.c	(original)
+++ trunk/sources/rb-playlist-source.c	Sun Jun  8 14:37:16 2008
@@ -809,8 +809,12 @@
 	location = rhythmdb_entry_get_refstring (entry, RHYTHMDB_PROP_LOCATION);
 
 	if (g_hash_table_lookup (source->priv->entries, location)) {
-		rhythmdb_query_model_add_entry (source->priv->model, entry, -1);
-		source->priv->dirty = TRUE;
+		if (_rb_source_check_entry_type (RB_SOURCE (source), entry)) {
+			rhythmdb_query_model_add_entry (source->priv->model, entry, -1);
+			source->priv->dirty = TRUE;
+		} else {
+			g_hash_table_remove (source->priv->entries, location);
+		}
 	}
 
 	rb_refstring_unref (location);

Modified: trunk/sources/rb-source.c
==============================================================================
--- trunk/sources/rb-source.c	(original)
+++ trunk/sources/rb-source.c	Sun Jun  8 14:37:16 2008
@@ -1695,6 +1695,30 @@
 	return group;
 }
 
+/**
+ * _rb_source_check_entry_type:
+ * @source: a #RBSource
+ * @entry: a #RhythmDBEntry
+ *
+ * Checks if a database entry matches the entry type for the source.
+ *
+ * Return value: %TRUE if the entry matches the source's entry type.
+ */
+gboolean
+_rb_source_check_entry_type (RBSource *source, RhythmDBEntry *entry)
+{
+	RhythmDBEntryType entry_type;
+	gboolean ret = TRUE;
+
+	g_object_get (source, "entry-type", &entry_type, NULL);
+	if (entry_type != RHYTHMDB_ENTRY_TYPE_INVALID &&
+	    rhythmdb_entry_get_entry_type (entry) != entry_type) {
+		ret = FALSE;
+	}
+	g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
+	return ret;
+}
+
 /* This should really be standard. */
 #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
 

Modified: trunk/sources/rb-source.h
==============================================================================
--- trunk/sources/rb-source.h	(original)
+++ trunk/sources/rb-source.h	Sun Jun  8 14:37:16 2008
@@ -215,6 +215,8 @@
 						  GtkActionEntry *actions,
 						  int num_actions,
 						  gpointer user_data);
+gboolean	_rb_source_check_entry_type	(RBSource *source,
+						 RhythmDBEntry *entry);
 
 G_END_DECLS
 

Modified: trunk/sources/rb-static-playlist-source.c
==============================================================================
--- trunk/sources/rb-static-playlist-source.c	(original)
+++ trunk/sources/rb-static-playlist-source.c	Sun Jun  8 14:37:16 2008
@@ -92,6 +92,9 @@
 						    GtkTreePath *path,
 						    GtkTreeIter *iter,
 						    RBStaticPlaylistSource *source);
+static gboolean rb_static_playlist_source_filter_entry_drop (RhythmDBQueryModel *model,
+							     RhythmDBEntry *entry,
+							     RBStaticPlaylistSource *source);
 static void rb_static_playlist_source_non_entry_dropped (GtkTreeModel *model,
 							 const char *uri,
 							 int position,
@@ -267,6 +270,10 @@
 	priv->base_model = rb_playlist_source_get_query_model (RB_PLAYLIST_SOURCE (psource));
 	g_object_set (priv->base_model, "show-hidden", TRUE, NULL);
 	g_object_ref (priv->base_model);
+	g_signal_connect_object (priv->base_model,
+				 "filter-entry-drop",
+				 G_CALLBACK (rb_static_playlist_source_filter_entry_drop),
+				 source, 0);
 
 	priv->paned = gtk_vpaned_new ();
 
@@ -708,21 +715,12 @@
 	entry = rhythmdb_entry_lookup_by_location (db, location);
 	if (entry) {
 		RBStaticPlaylistSourcePrivate *priv = RB_STATIC_PLAYLIST_SOURCE_GET_PRIVATE (source);
-		RhythmDBEntryType entry_type;
 
-		g_object_get (source, "entry-type", &entry_type, NULL);
-		if (entry_type != RHYTHMDB_ENTRY_TYPE_INVALID &&
-		    rhythmdb_entry_get_entry_type (entry) != entry_type) {
-			g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
-			rb_debug ("attempting to add an entry of the wrong type to playlist");
-			return;
+		if (_rb_source_check_entry_type (RB_SOURCE (source), entry)) {
+			rhythmdb_entry_ref (entry);
+			rhythmdb_query_model_add_entry (priv->base_model, entry, index);
+			rhythmdb_entry_unref (entry);
 		}
-
-		rhythmdb_entry_ref (entry);
-		rhythmdb_query_model_add_entry (priv->base_model, entry, index);
-		rhythmdb_entry_unref (entry);
-
-		g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, entry_type);
 	}
 
 	rb_playlist_source_add_to_map (psource, location);
@@ -867,6 +865,18 @@
 	rb_playlist_source_mark_dirty (RB_PLAYLIST_SOURCE (source));
 }
 
+static gboolean
+rb_static_playlist_source_filter_entry_drop (RhythmDBQueryModel *model,
+					     RhythmDBEntry *entry, 
+					     RBStaticPlaylistSource *source)
+{
+	if (_rb_source_check_entry_type (RB_SOURCE (source), entry)) {
+		rb_debug ("allowing drop of entry %s", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+		return TRUE;
+	}
+	rb_debug ("preventing drop of entry %s", rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION));
+	return FALSE;
+}
 
 static GList *
 impl_get_search_actions (RBSource *source)



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