static void
rb_source_finalize (GObject *object)
{
	RBSource *source;
	RBSourcePrivate *priv;

	g_return_if_fail (object != NULL);
	g_return_if_fail (RB_IS_SOURCE (object));

	source = RB_SOURCE (object);
	priv = RB_SOURCE_GET_PRIVATE (source);
	g_return_if_fail (priv != NULL);

	rb_debug ("Finalizing source %p: '%s'", source, priv->name);

	if (priv->query_model != NULL) {
		rb_debug ("Unreffing model %p count: %d", priv->query_model, G_OBJECT (priv->query_model)->ref_count);
		g_object_unref (priv->query_model);
	}

	if (priv->pixbuf != NULL) {
		g_object_unref (priv->pixbuf);
	}

	g_free (priv->name);

	G_OBJECT_CLASS (rb_source_parent_class)->finalize (object);
}
static void
rb_source_set_query_model_internal (RBSource *source,
				    RhythmDBQueryModel *model)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	if (priv->query_model == model) {
		return;
	}

	if (priv->query_model != NULL) {
		g_signal_handlers_disconnect_by_func (priv->query_model,
						      G_CALLBACK (rb_source_post_entry_deleted_cb),
						      source);
		g_signal_handlers_disconnect_by_func (priv->query_model,
						      G_CALLBACK (rb_source_row_inserted_cb),
						      source);
		g_object_unref (priv->query_model);
	}

	priv->query_model = model;
	if (priv->query_model != NULL) {
		g_object_ref (priv->query_model);
		g_signal_connect_object (model, "post-entry-delete",
					 G_CALLBACK (rb_source_post_entry_deleted_cb),
					 source, 0);
		g_signal_connect_object (model, "row_inserted",
					 G_CALLBACK (rb_source_row_inserted_cb),
					 source, 0);
	}

	/* g_object_notify (G_OBJECT (source), "query-model"); */
	rb_source_notify_status_changed (source);
}
static void
rb_source_dispose (GObject *object)
{
	RBSource *source;
	RBSourcePrivate *priv;

	g_return_if_fail (object != NULL);
	g_return_if_fail (RB_IS_SOURCE (object));

	source = RB_SOURCE (object);
	priv = RB_SOURCE_GET_PRIVATE (source);
	g_return_if_fail (priv != NULL);

	rb_debug ("Disposing source %p: '%s'", source, priv->name);

	if (priv->update_visibility_id != 0) {
		g_source_remove (priv->update_visibility_id);
		priv->update_visibility_id = 0;
	}
	if (priv->update_status_id != 0) {
		g_source_remove (priv->update_status_id);
		priv->update_status_id = 0;
	}

	G_OBJECT_CLASS (rb_source_parent_class)->dispose (object);
}
static void
rb_source_get_property (GObject *object,
			guint prop_id,
			GValue *value,
			GParamSpec *pspec)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (object);

	switch (prop_id) {
	case PROP_NAME:
		g_value_set_string (value, priv->name);
		break;
	case PROP_ICON:
		g_value_set_object (value, priv->pixbuf);
		break;
	case PROP_SHELL:
		g_value_set_object (value, priv->shell);
		break;
	case PROP_VISIBLE:
		g_value_set_boolean (value, priv->visible);
		break;
	case PROP_UI_MANAGER:
	{
		GtkUIManager *manager;
		g_object_get (priv->shell,
			      "ui-manager", &manager,
			      NULL);
		g_value_set_object (value, manager);
		g_object_unref (manager);
		break;
	}
	case PROP_QUERY_MODEL:
		g_value_set_object (value, priv->query_model);
		break;
	case PROP_SOURCE_GROUP:
		g_value_set_boxed (value, priv->source_group);
		break;
	case PROP_ENTRY_TYPE:
		g_value_set_boxed (value, priv->entry_type);
		break;
	case PROP_PLUGIN:
		g_value_set_object (value, priv->plugin);
		break;
	case PROP_BASE_QUERY_MODEL:
		/* unless the subclass overrides it, just assume the
		 * current query model is the base model.
		 */
		g_value_set_object (value, priv->query_model);
		break;
	case PROP_PLAY_ORDER:
		g_value_set_object (value, NULL);		/* ? */
		break;
	case PROP_SEARCH_TYPE:
		g_value_set_enum (value, priv->search_type);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
Esempio n. 5
0
static void
default_move_to_trash (RBSource *source)
{
	GList *sel, *tem;
	RBEntryView *entry_view;
	RhythmDB *db;
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	g_object_get (priv->shell, "db", &db, NULL);

	sel = NULL;
	entry_view = rb_source_get_entry_view (source);
	if (entry_view != NULL) {
		sel = rb_entry_view_get_selected_entries (entry_view);
	}

	for (tem = sel; tem != NULL; tem = tem->next) {
		rhythmdb_entry_move_to_trash (db, (RhythmDBEntry *)tem->data);
		rhythmdb_commit (db);
	}

	g_list_foreach (sel, (GFunc)rhythmdb_entry_unref, NULL);
	g_list_free (sel);
	g_object_unref (db);
}
static void
rb_source_post_entry_deleted_cb (GtkTreeModel *model,
				 RhythmDBEntry *entry,
				 RBSource *source)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	if (priv->update_status_id == 0)
		priv->update_status_id = g_idle_add ((GSourceFunc)_update_status_idle, source);
}
static void
queue_update_visibility (RBSource *source)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	if (priv->update_visibility_id != 0) {
		g_source_remove (priv->update_visibility_id);
	}
	priv->update_visibility_id = g_idle_add ((GSourceFunc) update_visibility_idle, source);
}
/**
 * _rb_source_show_popup:
 * @source: a #RBSource
 * @ui_path: UI path to the popup to show
 *
 * Source implementations can use this as a shortcut to
 * display a popup that has been loaded into the UI manager.
 */
void
_rb_source_show_popup (RBSource *source, const char *ui_path)
{
	GtkUIManager *uimanager;

	g_object_get (RB_SOURCE_GET_PRIVATE (source)->shell,
		      "ui-manager", &uimanager, NULL);
	rb_gtk_action_popup_menu (uimanager, ui_path);
	g_object_unref (uimanager);

}
static void
rb_source_row_inserted_cb (GtkTreeModel *model,
			   GtkTreePath *path,
			   GtkTreeIter *iter,
			   RBSource *source)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	if (priv->update_status_id == 0)
		priv->update_status_id = g_idle_add ((GSourceFunc)_update_status_idle, source);
}
/**
 * rb_source_can_rename:
 * @source: a #RBSource.
 *
 * Return value: TRUE if this source can be renamed
 */
gboolean
rb_source_can_rename (RBSource *source)
{
	RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	if (rb_shell_get_party_mode (priv->shell)) {
		return FALSE;
	}

	return klass->impl_can_rename (source);
}
static gboolean
_update_status_idle (RBSource *source)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	rb_source_notify_status_changed (source);

	if (priv->hidden_when_empty)
		update_visibility_idle (source);

	priv->update_status_id = 0;
	return FALSE;
}
/**
 * rb_source_set_hidden_when_empty:
 * @source: a #RBSource
 * @hidden: if TRUE, the source should not be displayed in
 *   the source list when there are no entries in it
 */
void
rb_source_set_hidden_when_empty (RBSource *source,
				 gboolean  hidden)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	g_return_if_fail (RB_IS_SOURCE (source));

	if (priv->hidden_when_empty != hidden) {
		priv->hidden_when_empty = hidden;
		queue_update_visibility (source);
	}
}
static void
rb_source_set_property (GObject *object,
			guint prop_id,
			const GValue *value,
			GParamSpec *pspec)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (object);
	RBSource *source = RB_SOURCE (object);

	switch (prop_id) {
	case PROP_NAME:
		g_free (priv->name);
		priv->name = g_strdup (g_value_get_string (value));
		break;
	case PROP_ICON:
		rb_source_set_pixbuf (source, g_value_get_object (value));
		break;
	case PROP_SHELL:
		priv->shell = g_value_get_object (value);
		break;
	case PROP_VISIBLE:
		priv->visible = g_value_get_boolean (value);
		rb_debug ("Setting %s visibility to %u",
			  priv->name,
			  priv->visible);
		break;
	case PROP_HIDDEN_WHEN_EMPTY:
		rb_source_set_hidden_when_empty (source, g_value_get_boolean (value));
		break;
	case PROP_QUERY_MODEL:
		rb_source_set_query_model_internal (source, g_value_get_object (value));
		break;
	case PROP_SOURCE_GROUP:
		priv->source_group = g_value_get_boxed (value);
		break;
	case PROP_ENTRY_TYPE:
		priv->entry_type = g_value_get_boxed (value);
		break;
	case PROP_PLUGIN:
		priv->plugin = g_value_get_object (value);
		break;
	case PROP_SEARCH_TYPE:
		priv->search_type = g_value_get_enum (value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
/**
 * rb_source_set_pixbuf:
 * @source: a #RBSource
 * @pixbuf: new GdkPixbuf for the source
 *
 * Sets the pixbuf for the source.
 */
void
rb_source_set_pixbuf (RBSource  *source,
		      GdkPixbuf *pixbuf)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	g_return_if_fail (RB_IS_SOURCE (source));

	if (priv->pixbuf != NULL) {
		g_object_unref (priv->pixbuf);
	}

	priv->pixbuf = pixbuf;

	if (priv->pixbuf != NULL) {
		g_object_ref (priv->pixbuf);
	}
}
static gboolean
update_visibility_idle (RBSource *source)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);
	gboolean visibility;

	GDK_THREADS_ENTER ();

	gint count = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (priv->query_model), NULL);

	visibility = (count > 0);

	if (visibility != priv->visible) {
		g_object_set (G_OBJECT (source), "visibility", visibility, NULL);
	}

	priv->update_visibility_id = 0;
	GDK_THREADS_LEAVE ();
	return FALSE;
}
static void
default_get_status (RBSource *source,
		    char **text,
		    char **progress_text,
		    float *progress)
{
	RBSourcePrivate *priv = RB_SOURCE_GET_PRIVATE (source);

	/* hack to get these strings marked for translation */
	if (0) {
		ngettext ("%d song", "%d songs", 0);
	}

	if (priv->query_model) {
		*text = rhythmdb_query_model_compute_status_normal (priv->query_model,
								    "%d song",
								    "%d songs");
		if (rhythmdb_query_model_has_pending_changes (priv->query_model))
			*progress = -1.0f;
	} else {
		*text = g_strdup ("");
	}
}
static void
rb_source_init (RBSource *source)
{
	RB_SOURCE_GET_PRIVATE (source)->visible = TRUE;
}