Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save musically-ut/1978836 to your computer and use it in GitHub Desktop.
Save musically-ut/1978836 to your computer and use it in GitHub Desktop.
Rhythmbox patch for Ratings in notification.
From 15b12ffc5b4b22ab104cf796e7173db4eeaefe90 Mon Sep 17 00:00:00 2001
From: Utkarsh Upadhyay <musically.ut@gmail.com>
Date: Fri, 2 Mar 2012 11:56:32 +0530
Subject: [PATCH] Notification rating plugin.
---
data/org.gnome.rhythmbox.gschema.xml | 10 +
plugins/notification/Makefile.am | 6 +
plugins/notification/notification-preferences.ui | 28 +++
plugins/notification/rb-notification-plugin.c | 243 ++++++++++++++++++++-
4 files changed, 275 insertions(+), 12 deletions(-)
create mode 100644 plugins/notification/notification-preferences.ui
diff --git a/data/org.gnome.rhythmbox.gschema.xml b/data/org.gnome.rhythmbox.gschema.xml
index 4d6458c..457daa5 100644
--- a/data/org.gnome.rhythmbox.gschema.xml
+++ b/data/org.gnome.rhythmbox.gschema.xml
@@ -268,6 +268,16 @@
<child name='source' schema='org.gnome.rhythmbox.source'/>
</schema>
+ <schema id="org.gnome.rhythmbox.plugins.notifications">
+ <key name="ratings" type="b">
+ <default>true</default>
+ <summary>Whether to show ratings button in notifications.</summary>
+ <description>
+ If true, the buttons to increase/decrease ratings will be displayed in the notifications.
+ </description>
+ </key>
+ </schema>
+
<schema id="org.gnome.rhythmbox.plugins.audioscrobbler.service">
<key name="enabled" type="b">
<default>true</default>
diff --git a/plugins/notification/Makefile.am b/plugins/notification/Makefile.am
index f6c3db1..c027af5 100644
--- a/plugins/notification/Makefile.am
+++ b/plugins/notification/Makefile.am
@@ -1,6 +1,7 @@
NULL =
plugindir = $(PLUGINDIR)/notification
+plugindatadir = $(PLUGINDATADIR)/notification
plugin_LTLIBRARIES = libnotification.la
libnotification_la_SOURCES = \
@@ -33,6 +34,10 @@ INCLUDES = \
$(NOTIFY_CFLAGS) \
-D_BSD_SOURCE
+gtkbuilderdir = $(plugindatadir)
+gtkbuilder_DATA = \
+ notification-preferences.ui
+
plugin_in_files = notification.plugin.in
%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
@@ -47,6 +52,7 @@ plugin_DATA = \
EXTRA_DIST = \
$(plugin_in_files) \
+ $(gtkbuilder_DATA) \
$(NULL)
CLEANFILES = \
diff --git a/plugins/notification/notification-preferences.ui b/plugins/notification/notification-preferences.ui
new file mode 100644
index 0000000..a0949c0
--- /dev/null
+++ b/plugins/notification/notification-preferences.ui
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkVBox" id="config">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="rating_buttons_enabled_check">
+ <property name="label" translatable="yes">Show rating buttons</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/plugins/notification/rb-notification-plugin.c b/plugins/notification/rb-notification-plugin.c
index 0671b3d..ae8a14f 100644
--- a/plugins/notification/rb-notification-plugin.c
+++ b/plugins/notification/rb-notification-plugin.c
@@ -28,6 +28,12 @@
#include <config.h>
+#include <libpeas-gtk/peas-gtk.h>
+
+#include <lib/rb-builder-helpers.h>
+#include <lib/rb-file-helpers.h>
+#include <plugins/rb-plugin-macros.h>
+
#include <string.h>
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
@@ -53,19 +59,30 @@
#define RB_IS_NOTIFICATION_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_NOTIFICATION_PLUGIN))
#define RB_NOTIFICATION_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_NOTIFICATION_PLUGIN, RBNotificationPluginClass))
+#define NOTIFICATION_SETTINGS_SCHEMA "org.gnome.rhythmbox.plugins.notifications"
+#define NOTIFICATION_SETTINGS_PATH "/org/gnome/rhythmbox/plugins/notifications"
+#define NOTIFICATION_RATING_ENABLED_KEY "ratings"
+
typedef struct
{
PeasExtensionBase parent;
+ GtkWidget *config_dialog;
+
/* current playing data */
char *current_title;
- char *current_album_and_artist; /* from _album_ by _artist_ */
+ char *current_album_artist_rating; /* from _album_ by _artist_ rated _rating_ */
+ gdouble rating;
gchar *notify_art_path;
NotifyNotification *notification;
gboolean notify_supports_actions;
gboolean notify_supports_icon_buttons;
gboolean notify_supports_persistence;
+ gboolean rating_buttons_enabled;
+
+ GtkWidget *rating_buttons_enabled_check;
+ GSettings *notification_settings;
RBShellPlayer *shell_player;
RhythmDB *db;
@@ -79,7 +96,14 @@ typedef struct
G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module);
-RB_DEFINE_PLUGIN(RB_TYPE_NOTIFICATION_PLUGIN, RBNotificationPlugin, rb_notification_plugin,)
+static GtkWidget *impl_create_configure_widget (PeasGtkConfigurable *bplugin);
+static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface);
+
+RB_DEFINE_PLUGIN(RB_TYPE_NOTIFICATION_PLUGIN,
+ RBNotificationPlugin,
+ rb_notification_plugin,
+ (G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE,
+ peas_gtk_configurable_iface_init)))
static gchar *
markup_escape (const char *text)
@@ -113,6 +137,90 @@ notification_playpause_cb (NotifyNotification *notification,
}
static void
+notification_ratedown_cb (NotifyNotification *notification,
+ const char *action,
+ RBNotificationPlugin *plugin)
+{
+ rb_debug ("notification action: %s", action);
+
+ RhythmDBEntry *playing;
+
+ playing = rb_shell_player_get_playing_entry (plugin->shell_player);
+ if (playing == NULL) {
+ rb_debug ("no song is playing!");
+ return;
+ }
+
+ gdouble rating = rhythmdb_entry_get_double (playing, RHYTHMDB_PROP_RATING);
+
+ /* To keep with the increase button, we'll start from rating = 2 */
+ if (rating == 0) {
+ rating = 2;
+ } else {
+ rating--;
+ }
+
+ if (rating < 1) {
+ rating = 1;
+ }
+
+ rb_debug ("new rating: %lf", rating);
+
+ GValue value = { 0, };
+
+ g_value_init (&value, G_TYPE_DOUBLE);
+ g_value_set_double (&value, rating);
+ rhythmdb_entry_set (plugin->db, playing, RHYTHMDB_PROP_RATING, &value);
+ g_value_unset (&value);
+
+ rhythmdb_commit (plugin->db);
+
+ rhythmdb_entry_unref (playing);
+}
+
+static void
+notification_rateup_cb (NotifyNotification *notification,
+ const char *action,
+ RBNotificationPlugin *plugin)
+{
+ rb_debug ("notification action: %s", action);
+
+ RhythmDBEntry *playing;
+
+ playing = rb_shell_player_get_playing_entry (plugin->shell_player);
+ if (playing == NULL) {
+ rb_debug ("no song is playing!");
+ return;
+ }
+
+ gdouble rating = rhythmdb_entry_get_double (playing, RHYTHMDB_PROP_RATING);
+
+ /* pushing the increase button 5 times is un-cool, so we'll start from rating = 4 */
+ if (rating == 0) {
+ rating = 4;
+ } else {
+ rating++;
+ }
+
+ if (rating > 5) {
+ rating = 5;
+ }
+
+ rb_debug ("new rating: %lf", rating);
+
+ GValue value = { 0, };
+
+ g_value_init (&value, G_TYPE_DOUBLE);
+ g_value_set_double (&value, rating);
+ rhythmdb_entry_set (plugin->db, playing, RHYTHMDB_PROP_RATING, &value);
+ g_value_unset (&value);
+
+ rhythmdb_commit (plugin->db);
+
+ rhythmdb_entry_unref (playing);
+}
+
+static void
notification_previous_cb (NotifyNotification *notification,
const char *action,
RBNotificationPlugin *plugin)
@@ -122,6 +230,57 @@ notification_previous_cb (NotifyNotification *notification,
}
static void
+notification_settings_changed_cb (GSettings *settings,
+ const char *key,
+ RBNotificationPlugin *plugin) {
+
+ rb_debug ("notification setting changed for key: %s", key);
+ if (g_strcmp0 (key, NOTIFICATION_RATING_ENABLED_KEY) != 0) {
+ return;
+ }
+
+ plugin->rating_buttons_enabled = g_settings_get_boolean (settings, key);
+ rb_debug ("ratings buttons are now: %s",
+ plugin->rating_buttons_enabled ? "enabled" : "disabled");
+}
+
+static GtkWidget *
+impl_create_configure_widget (PeasGtkConfigurable *bplugin)
+{
+ RBNotificationPlugin *plugin;
+ char *builderfile;
+ GtkBuilder *builder;
+ GtkWidget *widget;
+
+ rb_debug("initializing configuration widget");
+ plugin = RB_NOTIFICATION_PLUGIN (bplugin);
+
+ builderfile = rb_find_plugin_data_file (G_OBJECT (plugin), "notification-preferences.ui");
+ if (builderfile == NULL) {
+ g_warning ("can't find notification-preferences.ui");
+ return NULL;
+ }
+
+ builder = rb_builder_load (builderfile, plugin);
+ g_free (builderfile);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "config"));
+ g_object_ref_sink (widget);
+
+ plugin->rating_buttons_enabled_check = GTK_WIDGET (gtk_builder_get_object (builder, "rating_buttons_enabled_check"));
+ g_settings_bind (plugin->notification_settings, NOTIFICATION_RATING_ENABLED_KEY, plugin->rating_buttons_enabled_check, "active", G_SETTINGS_BIND_DEFAULT);
+ g_object_unref (builder);
+ return widget;
+}
+
+static void
+peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface)
+{
+ rb_debug("setting initializer function");
+ iface->create_configure_widget = impl_create_configure_widget;
+}
+
+static void
do_notify (RBNotificationPlugin *plugin,
guint timeout,
const char *primary,
@@ -217,6 +376,23 @@ do_notify (RBNotificationPlugin *plugin,
(NotifyActionCallback) notification_playpause_cb,
plugin,
NULL);
+
+ if (plugin->rating_buttons_enabled) {
+ notify_notification_add_action (notification,
+ "go-down",
+ _("Rating Down"),
+ (NotifyActionCallback) notification_ratedown_cb,
+ plugin,
+ NULL);
+ notify_notification_add_action (notification,
+ "go-up",
+ _("Rating Up"),
+ (NotifyActionCallback) notification_rateup_cb,
+ plugin,
+ NULL);
+
+ }
+
notify_notification_set_hint (notification, "action-icons", g_variant_new_boolean (TRUE));
}
@@ -251,7 +427,7 @@ notify_playing_entry (RBNotificationPlugin *plugin, gboolean requested)
do_notify (plugin,
PLAYING_ENTRY_NOTIFY_TIME * 1000,
plugin->current_title,
- plugin->current_album_and_artist,
+ plugin->current_album_artist_rating,
plugin->notify_art_path,
TRUE);
}
@@ -300,8 +476,10 @@ shell_notify_custom_cb (RBShell *shell,
static void
get_artist_album_templates (const char *artist,
const char *album,
+ const char *rating,
const char **artist_template,
- const char **album_template)
+ const char **album_template,
+ const char **rating_template)
{
PangoDirection tag_dir;
PangoDirection template_dir;
@@ -310,6 +488,8 @@ get_artist_album_templates (const char *artist,
*artist_template = _("by <i>%s</i>");
/* Translators: from Album */
*album_template = _("from <i>%s</i>");
+ /* Translators: rated Rating*/
+ *rating_template = _("rated <i>%s</i>");
/* find the direction (left-to-right or right-to-left) of the
* track's tags and the localized templates
@@ -320,6 +500,9 @@ get_artist_album_templates (const char *artist,
} else if (album != NULL && album[0] != '\0') {
tag_dir = pango_find_base_dir (album, -1);
template_dir = pango_find_base_dir (*album_template, -1);
+ } else if (rating != 0) {
+ tag_dir = pango_find_base_dir (rating, -1);
+ template_dir = pango_find_base_dir (*rating_template, -1);
} else {
return;
}
@@ -338,6 +521,7 @@ get_artist_album_templates (const char *artist,
*/
*artist_template = "<i>%s</i>";
*album_template = "/ <i>%s</i>";
+ *rating_template = "/ (<i>%s</i>)";
}
}
@@ -373,26 +557,30 @@ update_current_playing_data (RBNotificationPlugin *plugin, RhythmDBEntry *entry)
char *artist = NULL;
char *album = NULL;
char *title = NULL;
+ char rating_str[10];
+ gdouble rating;
GString *secondary;
RBExtDBKey *key;
const char *artist_template = NULL;
const char *album_template = NULL;
+ const char *rating_template = NULL;
g_free (plugin->current_title);
- g_free (plugin->current_album_and_artist);
+ g_free (plugin->current_album_artist_rating);
g_free (plugin->notify_art_path);
plugin->current_title = NULL;
- plugin->current_album_and_artist = NULL;
+ plugin->current_album_artist_rating = NULL;
+ plugin->rating = 0;
plugin->notify_art_path = NULL;
if (entry == NULL) {
plugin->current_title = g_strdup (_("Not Playing"));
- plugin->current_album_and_artist = g_strdup ("");
+ plugin->current_album_artist_rating = g_strdup ("");
return;
}
- secondary = g_string_sized_new (100);
+ secondary = g_string_sized_new (150);
/* request album art */
key = rhythmdb_entry_create_ext_db_key (entry, RHYTHMDB_PROP_ALBUM);
@@ -427,7 +615,11 @@ update_current_playing_data (RBNotificationPlugin *plugin, RhythmDBEntry *entry)
album = markup_escape (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM));
}
- get_artist_album_templates (artist, album, &artist_template, &album_template);
+ /* get ratings */
+ rating = rhythmdb_entry_get_double (entry, RHYTHMDB_PROP_RATING);
+ sprintf (rating_str, "%d", (int) rating);
+
+ get_artist_album_templates (artist, album, rating_str, &artist_template, &album_template, &rating_template);
if (artist != NULL && artist[0] != '\0') {
g_string_append_printf (secondary, artist_template, artist);
@@ -442,6 +634,14 @@ update_current_playing_data (RBNotificationPlugin *plugin, RhythmDBEntry *entry)
}
g_free (album);
+ if (rating != 0) {
+ if (secondary->len != 0)
+ g_string_append_c (secondary, ' ');
+
+ g_string_append_printf (secondary, rating_template, rating_str);
+ }
+
+
/* get title and possibly stream name.
* if we have a streaming song title, the entry's title
* property is the stream name.
@@ -475,8 +675,9 @@ update_current_playing_data (RBNotificationPlugin *plugin, RhythmDBEntry *entry)
title = g_strdup (_("Unknown"));
}
+ plugin->rating = rating;
plugin->current_title = title;
- plugin->current_album_and_artist = g_string_free (secondary, FALSE);
+ plugin->current_album_artist_rating = g_string_free (secondary, FALSE);
}
static void
@@ -547,6 +748,12 @@ impl_activate (PeasActivatable *bplugin)
G_CALLBACK (db_stream_metadata_cb), plugin, 0);
g_signal_connect_object (plugin->db, "entry_extra_metadata_notify::" RHYTHMDB_PROP_STREAM_SONG_ALBUM,
G_CALLBACK (db_stream_metadata_cb), plugin, 0);
+ g_signal_connect_object (plugin->notification_settings,
+ "changed",
+ G_CALLBACK (notification_settings_changed_cb),
+ plugin, 0);
+
+ notification_settings_changed_cb (plugin->notification_settings, NOTIFICATION_RATING_ENABLED_KEY, plugin);
plugin->art_store = rb_ext_db_new ("album-art");
@@ -563,6 +770,11 @@ impl_deactivate (PeasActivatable *bplugin)
plugin = RB_NOTIFICATION_PLUGIN (bplugin);
+ if (plugin->notification_settings != NULL) {
+ g_object_unref (plugin->notification_settings);
+ plugin->notification_settings = NULL;
+ }
+
g_object_get (plugin, "object", &shell, NULL);
cleanup_notification (plugin);
@@ -590,10 +802,10 @@ impl_deactivate (PeasActivatable *bplugin)
/* forget what's playing */
g_free (plugin->current_title);
- g_free (plugin->current_album_and_artist);
+ g_free (plugin->current_album_artist_rating);
g_free (plugin->notify_art_path);
plugin->current_title = NULL;
- plugin->current_album_and_artist = NULL;
+ plugin->current_album_artist_rating = NULL;
plugin->notify_art_path = NULL;
g_object_unref (shell);
@@ -602,6 +814,10 @@ impl_deactivate (PeasActivatable *bplugin)
static void
rb_notification_plugin_init (RBNotificationPlugin *plugin)
{
+ rb_debug("RBNotificationPlugin initialising");
+
+ plugin->notification_settings = g_settings_new_with_path (NOTIFICATION_SETTINGS_SCHEMA,
+ NOTIFICATION_SETTINGS_PATH "/Ratings");
}
G_MODULE_EXPORT void
@@ -611,4 +827,7 @@ peas_register_types (PeasObjectModule *module)
peas_object_module_register_extension_type (module,
PEAS_TYPE_ACTIVATABLE,
RB_TYPE_NOTIFICATION_PLUGIN);
+ peas_object_module_register_extension_type (module,
+ PEAS_GTK_TYPE_CONFIGURABLE,
+ RB_TYPE_NOTIFICATION_PLUGIN);
}
--
1.7.7.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment