changeset 3393:3fa4ee796bd1

merge
author Cristi Magherusan <majeru@atheme-project.org>
date Wed, 22 Aug 2007 13:09:03 +0300
parents d538aabf6df5 (current diff) 5a39f264f9f5 (diff)
children f5e5e9653287
files
diffstat 17 files changed, 330 insertions(+), 522 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/lap.py	Tue Aug 14 01:51:52 2007 +0300
+++ b/contrib/lap.py	Wed Aug 22 13:09:03 2007 +0300
@@ -41,6 +41,10 @@
 import fnmatch, optparse, os, subprocess
 from dbus import Bus, DBusException
 
+# Support audtool as a fallback but don't depend on it
+try: import subprocess
+except ImportError: pass
+
 # Use readline if available but don't depend on it
 try: import readline
 except ImportError: pass
@@ -70,10 +74,17 @@
 
 def addTrack(path, play=False):
 	try:
+		file_url = 'file://' + path
 		mp = bus.get_object('org.freedesktop.MediaPlayer', '/TrackList')
-		mp.AddTrack('file://' + path, play)
+		mp.AddTrack(file_url, play)
 	except DBusException:
-		print "ERROR: Unable to contact media player."
+		try:
+			if subprocess.call(['audtool','playlist-addurl',file_url]):
+				print "ERROR: audtool fallback returned an error for: %s" % file_url
+			elif play:
+				os.system('audtool playlist-jump `audtool playlist-length`; audtool playback-play')
+		except OSError:
+			print "ERROR: Unable to call audtool as a fallback for: %s" % file_url
 
 def parseChoice(inString):
 	try:
--- a/mk/objective.mk	Tue Aug 14 01:51:52 2007 +0300
+++ b/mk/objective.mk	Wed Aug 22 13:09:03 2007 +0300
@@ -126,9 +126,10 @@
 	@if [ -f Makefile.in ]; then \
 		rm -f Makefile; \
 	fi
-	@if [ -f mk/rules.mk ]; then \
+	@if [ -f mk/rules.mk.in ]; then \
 		rm -f mk/rules.mk; \
 	fi
+	rm -f config.log config.status
 
 build: depend
 	$(MAKE) build-prehook
--- a/po/ja.po	Tue Aug 14 01:51:52 2007 +0300
+++ b/po/ja.po	Wed Aug 22 13:09:03 2007 +0300
@@ -14,7 +14,7 @@
 "Project-Id-Version: audacious HEAD\n"
 "Report-Msgid-Bugs-To: http://bugs.audacious-media-player.org\n"
 "POT-Creation-Date: 2007-07-29 17:21+0200\n"
-"PO-Revision-Date: 2007-06-03 22:33+0900\n"
+"PO-Revision-Date: 2007-08-07 14:14+0900\n"
 "Last-Translator: dai <d+po@vdr.jp>\n"
 "Language-Team: Japanese <ja@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -491,61 +491,56 @@
 msgstr "演奏する位置の入力:"
 
 #: src/audacious/ui_main.c:1659
-#, fuzzy, c-format
+#, c-format
 msgid "Seek to: %d:%-2.2d/%d:%-2.2d (%d%%)"
 msgstr "移動先: %d:%-2.2d/%d:%-2.2d (%d%%)"
 
 #: src/audacious/ui_main.c:1691
 #, c-format
 msgid "Volume: %d%%"
-msgstr ""
+msgstr "音量: %d%%"
 
 #: src/audacious/ui_main.c:1722
 #, c-format
 msgid "Balance: %d%% left"
-msgstr ""
+msgstr "バランス: %d%% 左"
 
 #: src/audacious/ui_main.c:1726
 msgid "Balance: center"
-msgstr ""
+msgstr "バランス: 中央"
 
 #: src/audacious/ui_main.c:1730
 #, c-format
 msgid "Balance: %d%% right"
-msgstr ""
+msgstr "バランス: %d%% 右"
 
 #: src/audacious/ui_main.c:2118
 msgid "Options Menu"
-msgstr ""
+msgstr "オプションメニュー"
 
 #: src/audacious/ui_main.c:2122
-#, fuzzy
 msgid "Disable 'Always On Top'"
-msgstr "常に最前面に配置する"
+msgstr "「常に最前面に配置」無効"
 
 #: src/audacious/ui_main.c:2124
-#, fuzzy
 msgid "Enable 'Always On Top'"
-msgstr "常に最前面に配置する"
+msgstr "「常に最前面に配置」有効"
 
 #: src/audacious/ui_main.c:2127
 msgid "File Info Box"
-msgstr ""
+msgstr "ファイル情報ボックス"
 
 #: src/audacious/ui_main.c:2131
-#, fuzzy
 msgid "Disable 'Doublesize'"
-msgstr "ダブルサイズ"
+msgstr "「ダブルサイズ」無効"
 
 #: src/audacious/ui_main.c:2133
-#, fuzzy
 msgid "Enable 'Doublesize'"
-msgstr "ダブルサイズ"
+msgstr "「ダブルサイズ」有効"
 
 #: src/audacious/ui_main.c:2136
-#, fuzzy
 msgid "Visualization Menu"
-msgstr "視覚化モード"
+msgstr "視覚化メニュー"
 
 #: src/audacious/ui_main.c:2184
 msgid ""
@@ -1114,12 +1109,11 @@
 
 #: src/audacious/ui_manager.c:398
 msgid "Last.fm radio"
-msgstr ""
+msgstr "Last.fm ラジオ"
 
 #: src/audacious/ui_manager.c:399
-#, fuzzy
 msgid "Play Last.fm radio"
-msgstr "場所を演奏"
+msgstr "Last.fm ラジオを演奏"
 
 #: src/audacious/ui_manager.c:401
 msgid "Preferences"
@@ -1423,14 +1417,12 @@
 "わからない場合は, 単純に検索しようとしているものの文字を入力します."
 
 #: src/audacious/ui_playlist.c:513
-#, fuzzy
 msgid "Title: "
-msgstr "タイトル"
+msgstr "タイトル: "
 
 #: src/audacious/ui_playlist.c:520
-#, fuzzy
 msgid "Album: "
-msgstr "アルバム名"
+msgstr "アルバム名: "
 
 #: src/audacious/ui_playlist.c:527
 msgid "Artist: "
@@ -1474,13 +1466,12 @@
 "%s のファイルの種類が不明です.\n"
 
 #: src/audacious/ui_playlist.c:965
-#, fuzzy
 msgid "Save as Static Playlist"
-msgstr "プレイリストの保存"
+msgstr "スタティックプレイリストとして保存"
 
 #: src/audacious/ui_playlist.c:972
 msgid "Use Relative Path"
-msgstr ""
+msgstr "相対パスを使う"
 
 #: src/audacious/ui_playlist.c:994
 msgid "Load Playlist"
@@ -1531,9 +1522,8 @@
 msgstr "フィルタ(_F):"
 
 #: src/audacious/ui_jumptotrack.c:597
-#, fuzzy
 msgid "Close on Jump"
-msgstr "開いたらダイアログを閉じる"
+msgstr "ジャンプしたらダイアログを閉じる"
 
 #: src/audacious/playback.c:223
 msgid ""
@@ -1668,9 +1658,8 @@
 msgstr "メインウィンドウで使用するフォントの選択"
 
 #: src/audacious/glade/prefswin.glade:1045
-#, fuzzy
 msgid "Select playlist font:"
-msgstr "メインウィンドウで使用するフォントの選択"
+msgstr "プレイリスで使用するフォントの選択"
 
 #: src/audacious/glade/prefswin.glade:1091
 msgid ""
@@ -1947,7 +1936,6 @@
 msgstr "現在の出力プラグイン:"
 
 #: src/audacious/glade/prefswin.glade:3541
-#, fuzzy
 msgid ""
 "<span size=\"small\">This is the amount of time to prebuffer audio streams "
 "by, in milliseconds.\n"
@@ -1955,9 +1943,11 @@
 "Please note however, that high values will result in Audacious performing "
 "poorly.</span>"
 msgstr ""
-"<span size=\"small\">オーディオストリームのプレバッファするための十分な時間を"
-"ミリ秒で指定します. 音飛びがあるなら, この値を増やします. しかし, 高い値は "
-"Audacious のパフォーマンスを悪くすることに注意してください.</span>"
+"<span size=\"small\">オーディオストリームをプレバッファするための十分な時間を"
+"ミリ秒で指定します.\n"
+"音飛びがあるならこの値を増やします.\n"
+"しかし, 高い値は Audacious のパフォーマンスを悪くすることに注意してください."
+"</span>"
 
 #: src/audacious/glade/prefswin.glade:3571
 msgid "Buffer size:"
@@ -2049,7 +2039,6 @@
 msgstr "サンプリングレート [Hz]:"
 
 #: src/audacious/glade/prefswin.glade:4334
-#, fuzzy
 msgid ""
 "<span size=\"small\">All streams will be converted to this sampling rate.\n"
 "This should be the max supported sampling rate of\n"
--- a/src/audacious/playlist.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/playlist.c	Wed Aug 22 13:09:03 2007 +0300
@@ -2504,6 +2504,14 @@
     return result;
 }
 
+static gboolean
+playlist_request_win_update(gpointer unused)
+{
+    Playlist *playlist = playlist_get_active();
+    playlistwin_update_list(playlist);
+    return FALSE; /* to be called only once */
+}
+
 static gpointer
 playlist_get_info_func(gpointer arg)
 {
@@ -2600,7 +2608,9 @@
         }
 
         if (update_playlistwin) {
-            playlistwin_update_list(playlist);
+            /* we are in a different thread, so we can't do UI updates directly;
+               instead, schedule a playlist update in the main loop --giacomo */
+            g_idle_add_full(G_PRIORITY_HIGH_IDLE, playlist_request_win_update, NULL, NULL);
             update_playlistwin = FALSE;
         }
 
--- a/src/audacious/tuple_formatter.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/tuple_formatter.c	Wed Aug 22 13:09:03 2007 +0300
@@ -124,16 +124,19 @@
                         level++;
                     }
                 }
-                else if (*iter == '}' && (sel == argument))
+                else if (*iter == '}')
                 {
                     level--;
-                    if (level == 0)
-                      break;
+                    if (sel == argument)
+                    {
+                        if (level == 0)
+                            break;
+                        else
+                            g_string_append_c(sel, *iter);
+                    }
                     else
-                      g_string_append_c(sel, *iter);
+                        break;
                 }
-                else if (*iter == '}' && ((sel != argument)))
-                    break;
                 else
                     g_string_append_c(sel, *iter);
             }
@@ -188,16 +191,19 @@
                         level++;
                     }
                 }
-                else if (*iter == '}' && (sel == argument))
+                else if (*iter == '}')
                 {
                     level--;
-                    if (level == 0)
-                      break;
+                    if (sel == argument)
+                    {
+                        if (level == 0)
+                            break;
+                        else
+                            g_string_append_c(sel, *iter);
+                    }
                     else
-                    g_string_append_c(sel, *iter);
+                        break;
                 }
-                else if (*iter == '}' && ((sel != argument)))
-                    break;
                 else
                     g_string_append_c(sel, *iter);
             }
@@ -519,7 +525,7 @@
 
     g_return_val_if_fail(tuple != NULL, NULL);
 
-    rv = tuple_formatter_process_construct(tuple, string);
+    rv = tuple_formatter_process_string(tuple, string);
 
     if(!rv || !strcmp(rv, "")) {
         g_free(rv);
--- a/src/audacious/ui/mainwin.ui	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui/mainwin.ui	Wed Aug 22 13:09:03 2007 +0300
@@ -127,9 +127,7 @@
 				<menuitem action="view easy move" />
 			</menu>
 			<separator />
-			<menu action="plugins" name="plugins-menu">
-			   <menuitem action="dummy" name="plugins-menu-dummy" />
-			</menu>
+			<menuitem action="plugins-menu" />
 			<separator />
 			<menuitem action="preferences" />
 			<menuitem action="quit" />
--- a/src/audacious/ui/playlist.ui	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui/playlist.ui	Wed Aug 22 13:09:03 2007 +0300
@@ -11,14 +11,14 @@
 			<separator />
 			<menuitem action="queue toggle" />
 			<separator />
-			<menu action="plugins" name="plugins-menu">
-			   <menuitem action="dummy" name="plugins-menu-dummy" />
-			</menu>
+			<menuitem action="plugins-menu" />
 		</menu>
 
 		<menu action="dummy" name="add-menu">
 			<menuitem action="playlist add url" />
 			<menuitem action="playlist add files" />
+			<separator />
+			<menuitem action="plugins-menu" />
 		</menu>
 
 		<menu action="dummy" name="del-menu">
@@ -34,6 +34,8 @@
 			<menuitem action="playlist remove all" />
 			<menuitem action="playlist remove unselected" />
 			<menuitem action="playlist remove selected" />
+			<separator />
+			<menuitem action="plugins-menu" />
 		</menu>
 
 		<menu action="dummy" name="select-menu">
@@ -43,6 +45,8 @@
 			<separator />
 			<menuitem action="playlist select none" />
 			<menuitem action="playlist select all" />
+			<separator />
+			<menuitem action="plugins-menu" />
 		</menu>
 
 		<menu action="dummy" name="misc-menu">
@@ -67,6 +71,8 @@
 				<menuitem action="playlist sort selected by track number" />
 				<menuitem action="playlist sort selected by playlist entry" />
 			</menu>
+			<separator />
+			<menuitem action="plugins-menu" />
 		</menu>
 
 		<menu action="dummy" name="playlist-menu">
@@ -81,10 +87,8 @@
 			<menuitem action="playlist save default" />
 			<separator />
 			<menuitem action="playlist manager" />
-         <separator />
-			<menu action="plugins" name="plugins-menu">
-			   <menuitem action="dummy" name="plugins-menu-dummy" />
-			</menu>
+			<separator />
+			<menuitem action="plugins-menu" />
 			<separator />
 			<menuitem action="playlist refresh" />
 			<separator />
--- a/src/audacious/ui_fileinfopopup.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_fileinfopopup.c	Wed Aug 22 13:09:03 2007 +0300
@@ -92,7 +92,7 @@
     GtkWidget *progressbar =
         g_object_get_data(G_OBJECT(filepopup_win), "progressbar");
     gchar *tooltip_file = g_object_get_data(G_OBJECT(filepopup_win), "file");
-    gchar *current_file;
+    gchar *current_file_u, *current_file;
     Playlist *pl;
     gint length =
         GPOINTER_TO_INT(g_object_get_data(G_OBJECT(filepopup_win), "length"));
@@ -105,9 +105,9 @@
 
     pos = playlist_get_position(pl);
 
-    current_file = playlist_get_filename(pl , pos);
-
-    g_return_val_if_fail(current_file != NULL, FALSE);
+    current_file_u = playlist_get_filename(pl , pos);
+    g_return_val_if_fail(current_file_u != NULL, FALSE);
+    current_file = g_filename_from_uri(current_file_u, NULL, NULL);
 
     if (playback_get_playing() && length != -1 &&
         current_file != NULL && tooltip_file != NULL &&
@@ -133,6 +133,7 @@
             gtk_widget_hide(progressbar);
     }
 
+    g_free( current_file );
     return TRUE;
 }
 
--- a/src/audacious/ui_main.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_main.c	Wed Aug 22 13:09:03 2007 +0300
@@ -436,17 +436,6 @@
 }
 
 gboolean
-mainwin_num_clicked(GtkWidget *widget, GdkEventButton *event)
-{
-    if (event->button == 1) {
-        change_timer_mode();
-    } else if (event->button == 3)
-        return FALSE;
-
-    return TRUE;
-}
-
-gboolean
 mainwin_vis_cb(GtkWidget *widget, GdkEventButton *event)
 {
     if (event->button == 1) {
@@ -2114,12 +2103,24 @@
     cfg.timer_mode = mode;
 }
 
+gboolean
+change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event)
+{
+    if (event->button == 1) {
+        change_timer_mode();
+    } else if (event->button == 3)
+        return FALSE;
+
+    return TRUE;
+}
+
 void change_timer_mode(void) {
     if (cfg.timer_mode == TIMER_ELAPSED)
         set_timer_mode(TIMER_REMAINING);
     else
         set_timer_mode(TIMER_ELAPSED);
-    mainwin_update_song_info();
+    if (playback_get_playing())
+        mainwin_update_song_info();
 }
 
 static void
@@ -2449,19 +2450,19 @@
     mainwin_playstatus = ui_skinned_playstatus_new(SKINNED_WINDOW(mainwin)->fixed, 24, 28);
 
     mainwin_minus_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 36, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_minus_num, "button-press-event", G_CALLBACK(mainwin_num_clicked), NULL);
+    g_signal_connect(mainwin_minus_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     mainwin_10min_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 48, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_10min_num, "button-press-event", G_CALLBACK(mainwin_num_clicked), NULL);
+    g_signal_connect(mainwin_10min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     mainwin_min_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 60, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_min_num, "button-press-event", G_CALLBACK(mainwin_num_clicked), NULL);
+    g_signal_connect(mainwin_min_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     mainwin_10sec_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 78, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_10sec_num, "button-press-event", G_CALLBACK(mainwin_num_clicked), NULL);
+    g_signal_connect(mainwin_10sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     mainwin_sec_num = ui_skinned_number_new(SKINNED_WINDOW(mainwin)->fixed, 90, 26, SKIN_NUMBERS);
-    g_signal_connect(mainwin_sec_num, "button-press-event", G_CALLBACK(mainwin_num_clicked), NULL);
+    g_signal_connect(mainwin_sec_num, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     mainwin_about = ui_skinned_button_new();
     ui_skinned_small_button_setup(mainwin_about, SKINNED_WINDOW(mainwin)->fixed, 247, 83, 20, 25);
@@ -2486,10 +2487,10 @@
     g_signal_connect(mainwin_sposition, "release", G_CALLBACK(mainwin_spos_release_cb), NULL);
 
     mainwin_stime_min = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 130, 4, 15, FALSE, SKIN_TEXT);
-    g_signal_connect(mainwin_stime_min, "clicked", change_timer_mode, NULL);
+    g_signal_connect(mainwin_stime_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     mainwin_stime_sec = ui_skinned_textbox_new(SKINNED_WINDOW(mainwin)->fixed, 147, 4, 10, FALSE, SKIN_TEXT);
-    g_signal_connect(mainwin_stime_sec, "clicked", change_timer_mode, NULL);
+    g_signal_connect(mainwin_stime_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     err = gtk_message_dialog_new(GTK_WINDOW(mainwin), GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_MODAL,
                                  GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Error in Audacious."));
--- a/src/audacious/ui_main.h	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_main.h	Wed Aug 22 13:09:03 2007 +0300
@@ -177,6 +177,7 @@
                                 gpointer user_data);
 
 void mainwin_setup_menus(void);
+gboolean change_timer_mode_cb(GtkWidget *widget, GdkEventButton *event);
 
 void mainwin_jump_to_file(void);
 void mainwin_jump_to_time(void);
@@ -190,5 +191,4 @@
                                 gint * frequency,
                                 gint * numchannels);
 
-
 #endif
--- a/src/audacious/ui_manager.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_manager.c	Wed Aug 22 13:09:03 2007 +0300
@@ -375,6 +375,8 @@
 
 	{ "dummy", NULL, "dummy" },
 
+	{ "plugins-menu", NULL, N_("Plugins") },
+
 	{ "current track info", AUD_STOCK_INFO , N_("View Track Details"), "I",
 	  N_("View track details"), G_CALLBACK(action_current_track_info) },
 
@@ -627,22 +629,14 @@
 static void
 ui_manager_create_menus_init_pmenu( gchar * path )
 {
-  GtkWidget *plugins_menu, *plugins_menu_item, *plugins_dummy_item;
-  GList *plugins_menu_children = NULL;
-  gchar *path_dummy = g_strjoin( NULL , path , "/plugins-menu-dummy" , NULL );
-  /* remove the dummy item placed in plugins-menu as a workaround */
-  plugins_dummy_item = gtk_ui_manager_get_widget( ui_manager , path_dummy );
-  if ( plugins_dummy_item )
-    gtk_widget_destroy( plugins_dummy_item );
-  /* take note of the initial count of items in the "empty" plugins-menu */
-  plugins_menu_item = gtk_ui_manager_get_widget( ui_manager , path );
-  plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
-  plugins_menu_children = gtk_container_get_children( GTK_CONTAINER(plugins_menu) );
-  g_object_set_data( G_OBJECT(plugins_menu) , "ic" , GINT_TO_POINTER(g_list_length(plugins_menu_children)) );
-  g_list_free( plugins_menu_children );
-  /* last, hide the plugins-menu by default */
-  gtk_widget_hide( plugins_menu_item );
-  g_free( path_dummy );
+  GtkWidget *plugins_menu_item = gtk_ui_manager_get_widget( ui_manager , path );
+  if ( plugins_menu_item )
+  {
+    /* initially set count of items under plugins_menu_item to 0 */
+    g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(0) );
+    /* and since it's 0, hide the plugins_menu_item */
+    gtk_widget_hide( plugins_menu_item );
+  }
   return;
 }
 
@@ -692,6 +686,10 @@
 
   /* initialize plugins-menu for playlist-menus */
   ui_manager_create_menus_init_pmenu( "/playlist-menus/playlist-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/add-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/del-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/select-menu/plugins-menu" );
+  ui_manager_create_menus_init_pmenu( "/playlist-menus/misc-menu/plugins-menu" );
   ui_manager_create_menus_init_pmenu( "/playlist-menus/playlist-rightclick-menu/plugins-menu" );
 
   gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/equalizer.ui" , &gerr );
@@ -765,6 +763,32 @@
 /******************************/
 /* plugin-available functions */
 
+#define _MP_GWID(y) gtk_ui_manager_get_widget( ui_manager , y )
+
+static GtkWidget*
+audacious_menu_plugin_menuwid( menu_id )
+{
+  switch (menu_id)
+  {
+    case AUDACIOUS_MENU_MAIN:
+      return _MP_GWID("/mainwin-menus/main-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST:
+      return _MP_GWID("/playlist-menus/playlist-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_RCLICK:
+      return _MP_GWID("/playlist-menus/playlist-rightclick-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_ADD:
+      return _MP_GWID("/playlist-menus/add-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_REMOVE:
+      return _MP_GWID("/playlist-menus/del-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_SELECT:
+      return _MP_GWID("/playlist-menus/select-menu/plugins-menu");
+    case AUDACIOUS_MENU_PLAYLIST_MISC:
+      return _MP_GWID("/playlist-menus/misc-menu/plugins-menu");
+    default:
+      return NULL;
+  }
+}
+
 
 gint
 audacious_menu_plugin_item_add( gint menu_id , GtkWidget * item )
@@ -772,46 +796,27 @@
   if ( menu_created )
   {
     GtkWidget *plugins_menu = NULL;
-    GtkWidget *plugins_menu_item = NULL;
-
-    switch (menu_id)
-    {
-      case AUDACIOUS_MENU_MAIN:
-        plugins_menu_item = gtk_ui_manager_get_widget( ui_manager ,
-          "/mainwin-menus/main-menu/plugins-menu" );
-        break;
-
-      case AUDACIOUS_MENU_PLAYLIST:
-        plugins_menu_item = gtk_ui_manager_get_widget( ui_manager ,
-          "/playlist-menus/playlist-menu/plugins-menu" );
-        break;
-
-      case AUDACIOUS_MENU_PLAYLIST_RCLICK:
-        plugins_menu_item = gtk_ui_manager_get_widget( ui_manager ,
-          "/playlist-menus/playlist-rightclick-menu/plugins-menu" );
-        break;
-
-      default:
-        return -1;
-    }
-
+    GtkWidget *plugins_menu_item = audacious_menu_plugin_menuwid( menu_id );
     if ( plugins_menu_item )
     {
-      plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
-      if ( plugins_menu )
+      gint ic = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(plugins_menu_item),"ic"));
+      if ( ic == 0 ) /* no items under plugins_menu_item, create the submenu */
       {
-        gtk_menu_shell_append( GTK_MENU_SHELL(plugins_menu) , item );
-        gtk_widget_show( plugins_menu_item );
-        return 0; /* success */
+        plugins_menu = gtk_menu_new();
+        gtk_menu_item_set_submenu( GTK_MENU_ITEM(plugins_menu_item), plugins_menu );
       }
-      else
-        return -1;
+      else /* items available under plugins_menu_item, pick the existing submenu */
+      {
+        plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
+        if ( !plugins_menu ) return -1;
+      }
+      gtk_menu_shell_append( GTK_MENU_SHELL(plugins_menu) , item );
+      gtk_widget_show( plugins_menu_item );
+      g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(++ic) );
+      return 0; /* success */
     }
-    else
-      return -1;
   }
-  else
-    return -1;
+  return -1; /* failure */
 }
 
 
@@ -821,52 +826,28 @@
   if ( menu_created )
   {
     GtkWidget *plugins_menu = NULL;
-    GtkWidget *plugins_menu_item = NULL;
-    GList *plugins_menu_children = NULL;
-
-    switch (menu_id)
-    {
-      case AUDACIOUS_MENU_MAIN:
-        plugins_menu_item = gtk_ui_manager_get_widget( ui_manager ,
-          "/mainwin-menus/main-menu/plugins-menu" );
-        break;
-
-      case AUDACIOUS_MENU_PLAYLIST:
-        plugins_menu_item = gtk_ui_manager_get_widget( ui_manager ,
-          "/playlist-menus/playlist-menu/plugins-menu" );
-        break;
-
-      case AUDACIOUS_MENU_PLAYLIST_RCLICK:
-        plugins_menu_item = gtk_ui_manager_get_widget( ui_manager ,
-          "/playlist-menus/playlist-rightclick-menu/plugins-menu" );
-        break;
-
-      default:
-        return -1;
-    }
-
+    GtkWidget *plugins_menu_item = audacious_menu_plugin_menuwid( menu_id );
     if ( plugins_menu_item )
     {
-      plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
-      if ( plugins_menu )
+      gint ic = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(plugins_menu_item),"ic"));
+      if ( ic > 0 )
       {
-        /* remove the plugin-added entry */
-        gtk_container_remove( GTK_CONTAINER(plugins_menu) , item );
-        /* check the current number of items in plugins-menu against its initial count
-           of items; if these are equal, it means that the menu is "empty", so hide it */
-        gint ic = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(plugins_menu),"ic"));
-        plugins_menu_children = gtk_container_get_children( GTK_CONTAINER(plugins_menu) );
-        if ( ic == g_list_length(plugins_menu_children) )
-          gtk_widget_hide( plugins_menu_item );
-        g_list_free( plugins_menu_children );
-        return 0; /* success */
+        plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) );
+        if ( plugins_menu )
+        {
+          /* remove the plugin-added entry */
+          gtk_container_remove( GTK_CONTAINER(plugins_menu) , item );
+          g_object_set_data( G_OBJECT(plugins_menu_item) , "ic" , GINT_TO_POINTER(--ic) );
+          if ( ic == 0 ) /* if the menu is empty now, destroy it */
+          {
+            gtk_menu_item_remove_submenu( GTK_MENU_ITEM(plugins_menu_item) );
+            gtk_widget_destroy( plugins_menu );
+            gtk_widget_hide( plugins_menu_item );
+          }
+          return 0; /* success */
+        }
       }
-      else
-        return -1;
     }
-    else
-      return -1;
   }
-  else
-    return -1;
+  return -1; /* failure */
 }
--- a/src/audacious/ui_playlist.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_playlist.c	Wed Aug 22 13:09:03 2007 +0300
@@ -999,8 +999,6 @@
 {
     gint xpos, ypos;
     GtkRequisition req;
-    Playlist *playlist = playlist_get_active();
-    gint idx = 0;
 
     gtk_window_get_position(GTK_WINDOW(playlistwin), &xpos, &ypos);
 
@@ -1064,12 +1062,6 @@
                    event->button,
                    event->time);
     }
-    else if (event->button == 1 && REGION_R(82, 54, 15, 9)) {
-        if (cfg.timer_mode == TIMER_ELAPSED)
-            cfg.timer_mode = TIMER_REMAINING;
-        else
-            cfg.timer_mode = TIMER_ELAPSED;
-    }
     else if (event->button == 1 && event->type == GDK_BUTTON_PRESS &&
              (cfg.easy_move || event->y < 14))
     {
@@ -1085,15 +1077,7 @@
             dock_move_release(GTK_WINDOW(playlistwin));
         return TRUE;
     }
-    else if (event->button == 3 &&
-               (event->y >= cfg.playlist_height - 29 &&
-                event->y < cfg.playlist_height - 11 &&
-                ((event->x >= 12 && event->x < 37) ||
-                 (event->x >= 41 && event->x < 66) ||
-                 (event->x >= 70 && event->x < 95) ||
-                 (event->x >= 99 && event->x < 124) ||
-                 (event->x >= playlistwin_get_width() - 46 &&
-                  event->x < playlistwin_get_width() - 23)))) {
+    else if (event->button == 3) {
         /*
          * Pop up the main menu a few pixels down to avoid
          * anything to be selected initially.
@@ -1101,18 +1085,6 @@
         ui_manager_popup_menu_show(GTK_MENU(mainwin_general_menu), event->x_root,
                                 event->y_root + 2, 3, event->time);
     }
-    else if (event->button == 1 && (event->state & GDK_MOD1_MASK))
-    {
-        GList *node;
-
-        node = playlist_get_selected(playlist);
-
-        if (node != NULL)
-        {
-            idx = GPOINTER_TO_INT(playlist_get_selected(playlist)->data);
-            playlist_queue_position(playlist, idx);
-        }
-    }
 
     return FALSE;
 }
@@ -1436,11 +1408,13 @@
     playlistwin_time_min = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
                        playlistwin_get_width() - 82,
                        cfg.playlist_height - 15, 15, FALSE, SKIN_TEXT);
+    g_signal_connect(playlistwin_time_min, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     /* track time (second) */
     playlistwin_time_sec = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
                        playlistwin_get_width() - 64,
                        cfg.playlist_height - 15, 10, FALSE, SKIN_TEXT);
+    g_signal_connect(playlistwin_time_sec, "button-press-event", G_CALLBACK(change_timer_mode_cb), NULL);
 
     /* playlist information (current track length / total track length) */
     playlistwin_info = ui_skinned_textbox_new(SKINNED_WINDOW(playlistwin)->fixed,
--- a/src/audacious/ui_plugin_menu.h	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_plugin_menu.h	Wed Aug 22 13:09:03 2007 +0300
@@ -31,6 +31,10 @@
 #define AUDACIOUS_MENU_MAIN             0
 #define AUDACIOUS_MENU_PLAYLIST         1
 #define AUDACIOUS_MENU_PLAYLIST_RCLICK  2
+#define AUDACIOUS_MENU_PLAYLIST_ADD     3
+#define AUDACIOUS_MENU_PLAYLIST_REMOVE  4
+#define AUDACIOUS_MENU_PLAYLIST_SELECT  5
+#define AUDACIOUS_MENU_PLAYLIST_MISC    6
 
 gint audacious_menu_plugin_item_add( gint , GtkWidget * );
 gint audacious_menu_plugin_item_remove( gint , GtkWidget * );
--- a/src/audacious/ui_preferences.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_preferences.c	Wed Aug 22 13:09:03 2007 +0300
@@ -80,6 +80,12 @@
     PLUGIN_VIEW_N_COLS
 };
 
+enum PluginViewType {
+    PLUGIN_VIEW_TYPE_INPUT,
+    PLUGIN_VIEW_TYPE_GENERAL,
+    PLUGIN_VIEW_TYPE_VIS,
+    PLUGIN_VIEW_TYPE_EFFECT
+};
 
 typedef struct {
     const gchar *icon_path;
@@ -185,41 +191,6 @@
     gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), index);
 }
 
-
-static void
-input_plugin_open_prefs(GtkTreeView * treeview,
-                        gpointer data)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-    input_configure(id);
-}
-
-static void
-input_plugin_open_info(GtkTreeView * treeview,
-                       gpointer data)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-    input_about(id);
-}
-
 static void
 output_plugin_open_prefs(GtkComboBox * cbox,
                          gpointer data)
@@ -235,40 +206,6 @@
 }
 
 static void
-general_plugin_open_prefs(GtkTreeView * treeview,
-                          gpointer data)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-    general_configure(id);
-}
-
-static void
-general_plugin_open_info(GtkTreeView * treeview,
-			 gpointer data)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-	return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-    general_about(id);
-}
-
-static void
 input_plugin_toggle(GtkCellRendererToggle * cell,
                     const gchar * path_str,
                     gpointer data)
@@ -1176,8 +1113,65 @@
 }
 
 static void
-input_plugin_enable_prefs(GtkTreeView * treeview,
-                          GtkButton * button)
+plugin_treeview_open_prefs(GtkTreeView *treeview)
+{
+    GtkTreeSelection *selection;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    gint id;
+
+    selection = gtk_tree_view_get_selection(treeview);
+    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
+        return;
+    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
+
+    switch(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview), "plugin_type"))) {
+        case PLUGIN_VIEW_TYPE_INPUT:
+            input_configure(id);
+            break;
+        case PLUGIN_VIEW_TYPE_GENERAL:
+            general_configure(id);
+            break;
+        case PLUGIN_VIEW_TYPE_VIS:
+            vis_configure(id);
+            break;
+        case PLUGIN_VIEW_TYPE_EFFECT:
+            effect_configure(id);
+            break;
+    }
+}
+
+static void
+plugin_treeview_open_info(GtkTreeView *treeview)
+{
+    GtkTreeSelection *selection;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    gint id;
+
+    selection = gtk_tree_view_get_selection(treeview);
+    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
+        return;
+    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
+
+    switch(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview), "plugin_type"))) {
+        case PLUGIN_VIEW_TYPE_INPUT:
+            input_about(id);
+            break;
+        case PLUGIN_VIEW_TYPE_GENERAL:
+            general_about(id);
+            break;
+        case PLUGIN_VIEW_TYPE_VIS:
+            vis_about(id);
+            break;
+        case PLUGIN_VIEW_TYPE_EFFECT:
+            effect_about(id);
+            break;
+    }
+}
+
+static void
+plugin_treeview_enable_prefs(GtkTreeView * treeview, GtkButton * button)
 {
     GtkTreeSelection *selection;
     GtkTreeModel *model;
@@ -1192,7 +1186,22 @@
 
     gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
 
-    plist = get_input_list();
+    switch(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview), "plugin_type"))) {
+        case PLUGIN_VIEW_TYPE_INPUT:
+            plist = get_input_list();
+            break;
+        case PLUGIN_VIEW_TYPE_GENERAL:
+            plist = get_general_list();
+            break;
+        case PLUGIN_VIEW_TYPE_VIS:
+            plist = get_vis_list();
+            break;
+        case PLUGIN_VIEW_TYPE_EFFECT:
+            plist = get_effect_list();
+            break;
+        default:
+            return;
+    }
     plist = g_list_nth(plist, id);
 
     gtk_widget_set_sensitive(GTK_WIDGET(button),
@@ -1200,8 +1209,7 @@
 }
 
 static void
-input_plugin_enable_info(GtkTreeView * treeview,
-                         GtkButton * button)
+plugin_treeview_enable_info(GtkTreeView * treeview, GtkButton * button)
 {
     GtkTreeSelection *selection;
     GtkTreeModel *model;
@@ -1215,7 +1223,22 @@
 
     gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
 
-    plist = get_input_list();
+    switch(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview), "plugin_type"))) {
+        case PLUGIN_VIEW_TYPE_INPUT:
+            plist = get_input_list();
+            break;
+        case PLUGIN_VIEW_TYPE_GENERAL:
+            plist = get_general_list();
+            break;
+        case PLUGIN_VIEW_TYPE_VIS:
+            plist = get_vis_list();
+            break;
+        case PLUGIN_VIEW_TYPE_EFFECT:
+            plist = get_effect_list();
+            break;
+        default:
+            return;
+    }
     plist = g_list_nth(plist, id);
 
     gtk_widget_set_sensitive(GTK_WIDGET(button),
@@ -1250,222 +1273,6 @@
                              OUTPUT_PLUGIN(plist->data)->configure != NULL);
 }
 
-
-static void
-general_plugin_enable_info(GtkTreeView * treeview,
-                           GtkButton * button)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    GList *plist;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-
-    plist = get_general_list();
-    plist = g_list_nth(plist, id);
-
-    gtk_widget_set_sensitive(GTK_WIDGET(button),
-                             GENERAL_PLUGIN(plist->data)->about != NULL);
-}
-
-static void
-general_plugin_enable_prefs(GtkTreeView * treeview,
-                            GtkButton * button)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    GList *plist;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-
-    plist = get_general_list();
-    plist = g_list_nth(plist, id);
-
-    gtk_widget_set_sensitive(GTK_WIDGET(button),
-                             GENERAL_PLUGIN(plist->data)->configure != NULL);
-}
-
-
-
-static void
-vis_plugin_enable_prefs(GtkTreeView * treeview,
-                            GtkButton * button)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    GList *plist;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-
-    plist = get_vis_list();
-    plist = g_list_nth(plist, id);
-
-    gtk_widget_set_sensitive(GTK_WIDGET(button),
-                             VIS_PLUGIN(plist->data)->configure != NULL);
-}
-
-static void
-vis_plugin_enable_info(GtkTreeView * treeview,
-                           GtkButton * button)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    GList *plist;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-
-    plist = get_vis_list();
-    plist = g_list_nth(plist, id);
-
-    gtk_widget_set_sensitive(GTK_WIDGET(button),
-                             VIS_PLUGIN(plist->data)->about != NULL);
-}
-
-static void
-vis_plugin_open_prefs(GtkTreeView * treeview,
-                          gpointer data)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-    vis_configure(id);
-}
-
-
-static void
-vis_plugin_open_info(GtkTreeView * treeview,
-			 gpointer data)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-	return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-    vis_about(id);
-}
-
-
-
-
-
-
-static void
-effect_plugin_enable_prefs(GtkTreeView * treeview,
-                            GtkButton * button)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    GList *plist;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-
-    plist = get_effect_list();
-    plist = g_list_nth(plist, id);
-
-    gtk_widget_set_sensitive(GTK_WIDGET(button),
-                             EFFECT_PLUGIN(plist->data)->configure != NULL);
-}
-
-static void
-effect_plugin_enable_info(GtkTreeView * treeview,
-                           GtkButton * button)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    GList *plist;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-
-    plist = get_effect_list();
-    plist = g_list_nth(plist, id);
-
-    gtk_widget_set_sensitive(GTK_WIDGET(button),
-                             EFFECT_PLUGIN(plist->data)->about != NULL);
-}
-
-static void
-effect_plugin_open_prefs(GtkTreeView * treeview,
-                          gpointer data)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-        return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-    effect_configure(id);
-}
-
-
-static void
-effect_plugin_open_info(GtkTreeView * treeview,
-			 gpointer data)
-{
-    GtkTreeSelection *selection;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    gint id;
-
-    selection = gtk_tree_view_get_selection(treeview);
-    if (!gtk_tree_selection_get_selected(selection, &model, &iter))
-	return;
-
-    gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_ID, &id, -1);
-    effect_about(id);
-}
-
 static void
 on_output_plugin_bufsize_realize(GtkSpinButton *button,
 				 gpointer data)
@@ -2445,19 +2252,23 @@
 
     widget = glade_xml_get_widget(xml, "input_plugin_view");
     widget2 = glade_xml_get_widget(xml, "input_plugin_prefs");
+    g_object_set_data(G_OBJECT(widget), "plugin_type" , GINT_TO_POINTER(PLUGIN_VIEW_TYPE_INPUT));
+    g_signal_connect(G_OBJECT(widget), "row-activated",
+                     G_CALLBACK(plugin_treeview_open_prefs),
+                     NULL);
     g_signal_connect(G_OBJECT(widget), "cursor-changed",
-                     G_CALLBACK(input_plugin_enable_prefs),
+                     G_CALLBACK(plugin_treeview_enable_prefs),
                      widget2);
 
     g_signal_connect_swapped(G_OBJECT(widget2), "clicked",
-                             G_CALLBACK(input_plugin_open_prefs),
+                             G_CALLBACK(plugin_treeview_open_prefs),
                              widget);
     widget2 = glade_xml_get_widget(xml, "input_plugin_info");
     g_signal_connect(G_OBJECT(widget), "cursor-changed",
-                     G_CALLBACK(input_plugin_enable_info),
+                     G_CALLBACK(plugin_treeview_enable_info),
                      widget2);
     g_signal_connect_swapped(G_OBJECT(widget2), "clicked",
-                             G_CALLBACK(input_plugin_open_info),
+                             G_CALLBACK(plugin_treeview_open_info),
                              widget);
 
     /* plugin->output page */
@@ -2483,21 +2294,26 @@
     /* plugin->general page */
 
     widget = glade_xml_get_widget(xml, "general_plugin_view");
+    g_object_set_data(G_OBJECT(widget), "plugin_type" , GINT_TO_POINTER(PLUGIN_VIEW_TYPE_GENERAL));
+    g_signal_connect(G_OBJECT(widget), "row-activated",
+                     G_CALLBACK(plugin_treeview_open_prefs),
+                     NULL);
 
     widget2 = glade_xml_get_widget(xml, "general_plugin_prefs");
     g_signal_connect(G_OBJECT(widget), "cursor-changed",
-                     G_CALLBACK(general_plugin_enable_prefs),
+                     G_CALLBACK(plugin_treeview_enable_prefs),
                      widget2);
+
     g_signal_connect_swapped(G_OBJECT(widget2), "clicked",
-                             G_CALLBACK(general_plugin_open_prefs),
+                             G_CALLBACK(plugin_treeview_open_prefs),
                              widget);
 
     widget2 = glade_xml_get_widget(xml, "general_plugin_info");
     g_signal_connect(G_OBJECT(widget), "cursor-changed",
-                     G_CALLBACK(general_plugin_enable_info),
+                     G_CALLBACK(plugin_treeview_enable_info),
                      widget2);
     g_signal_connect_swapped(G_OBJECT(widget2), "clicked",
-                             G_CALLBACK(general_plugin_open_info),
+                             G_CALLBACK(plugin_treeview_open_info),
                              widget);
 
 
@@ -2506,18 +2322,22 @@
     widget = glade_xml_get_widget(xml, "vis_plugin_view");
     widget2 = glade_xml_get_widget(xml, "vis_plugin_prefs");
 
+    g_object_set_data(G_OBJECT(widget), "plugin_type" , GINT_TO_POINTER(PLUGIN_VIEW_TYPE_VIS));
+    g_signal_connect(G_OBJECT(widget), "row-activated",
+                     G_CALLBACK(plugin_treeview_open_prefs),
+                     NULL);
     g_signal_connect_swapped(G_OBJECT(widget2), "clicked",
-                             G_CALLBACK(vis_plugin_open_prefs),
+                             G_CALLBACK(plugin_treeview_open_prefs),
                              widget);
     g_signal_connect(G_OBJECT(widget), "cursor-changed",
-                     G_CALLBACK(vis_plugin_enable_prefs), widget2);
+                     G_CALLBACK(plugin_treeview_enable_prefs), widget2);
 
 
     widget2 = glade_xml_get_widget(xml, "vis_plugin_info");
     g_signal_connect(G_OBJECT(widget), "cursor-changed",
-                     G_CALLBACK(vis_plugin_enable_info), widget2);
+                     G_CALLBACK(plugin_treeview_enable_info), widget2);
     g_signal_connect_swapped(G_OBJECT(widget2), "clicked",
-                             G_CALLBACK(vis_plugin_open_info),
+                             G_CALLBACK(plugin_treeview_open_info),
                              widget);
 
 
@@ -2526,18 +2346,22 @@
     widget = glade_xml_get_widget(xml, "effect_plugin_view");
     widget2 = glade_xml_get_widget(xml, "effect_plugin_prefs");
 
+    g_object_set_data(G_OBJECT(widget), "plugin_type" , GINT_TO_POINTER(PLUGIN_VIEW_TYPE_EFFECT));
+    g_signal_connect(G_OBJECT(widget), "row-activated",
+                     G_CALLBACK(plugin_treeview_open_prefs),
+                     NULL);
     g_signal_connect_swapped(G_OBJECT(widget2), "clicked",
-                             G_CALLBACK(effect_plugin_open_prefs),
+                             G_CALLBACK(plugin_treeview_open_prefs),
                              widget);
     g_signal_connect(G_OBJECT(widget), "cursor-changed",
-                     G_CALLBACK(effect_plugin_enable_prefs), widget2);
+                     G_CALLBACK(plugin_treeview_enable_prefs), widget2);
 
 
     widget2 = glade_xml_get_widget(xml, "effect_plugin_info");
     g_signal_connect(G_OBJECT(widget), "cursor-changed",
-                     G_CALLBACK(effect_plugin_enable_info), widget2);
+                     G_CALLBACK(plugin_treeview_enable_info), widget2);
     g_signal_connect_swapped(G_OBJECT(widget2), "clicked",
-                             G_CALLBACK(effect_plugin_open_info),
+                             G_CALLBACK(plugin_treeview_open_info),
                              widget);
 
     /* playlist page */
--- a/src/audacious/ui_skinned_button.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_skinned_button.c	Wed Aug 22 13:09:03 2007 +0300
@@ -533,6 +533,7 @@
     if (ny > -1) priv->ny = ny;
     if (px > -1) priv->px = px;
     if (py > -1) priv->py = py;
+    gtk_widget_queue_draw(button);
 }
 
 void ui_skinned_button_set_skin_index(GtkWidget *button, SkinPixmapId si) {
--- a/src/audacious/ui_skinned_playlist.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_skinned_playlist.c	Wed Aug 22 13:09:03 2007 +0300
@@ -799,11 +799,6 @@
     UiSkinnedPlaylist *pl = UI_SKINNED_PLAYLIST (widget);
     UiSkinnedPlaylistPrivate *priv = UI_SKINNED_PLAYLIST_GET_PRIVATE(widget);
 
-    if (event->button == 3) {
-        ui_manager_popup_menu_show(GTK_MENU(playlistwin_popup_menu),
-                                   event->x_root, event->y_root + 5,
-                                   event->button, event->time);
-    }
     gint nr;
     Playlist *playlist = playlist_get_active();
 
@@ -812,6 +807,9 @@
         return FALSE;
 
     if (event->button == 3) {
+        ui_manager_popup_menu_show(GTK_MENU(playlistwin_popup_menu),
+                                   event->x_root, event->y_root + 5,
+                                   event->button, event->time);
         GList* selection = playlist_get_selected(playlist);
         if (g_list_find(selection, GINT_TO_POINTER(nr)) == NULL) {
             playlist_select_all(playlist, FALSE);
@@ -821,6 +819,9 @@
         if (!(event->state & GDK_CONTROL_MASK))
             playlist_select_all(playlist, FALSE);
 
+        if ((event->state & GDK_MOD1_MASK))
+            playlist_queue_position(playlist, nr);
+
         if (event->state & GDK_SHIFT_MASK && pl->prev_selected != -1) {
             playlist_select_range(playlist, pl->prev_selected, nr, TRUE);
             pl->prev_min = pl->prev_selected;
--- a/src/audacious/ui_skinned_textbox.c	Tue Aug 14 01:51:52 2007 +0300
+++ b/src/audacious/ui_skinned_textbox.c	Wed Aug 22 13:09:03 2007 +0300
@@ -353,7 +353,9 @@
 
     if (event->type == GDK_BUTTON_PRESS) {
         textbox = UI_SKINNED_TEXTBOX(widget);
-        if (event->button == 1) {
+        if (event->button == 3 && !g_signal_has_handler_pending(widget, textbox_signals[RIGHT_CLICKED], 0, TRUE))
+            return FALSE;
+        else if (event->button == 1) {
             if (priv->scroll_allowed) {
                 if ((priv->pixmap_width > textbox->width) && priv->is_scrollable) {
                     priv->is_dragging = TRUE;