# HG changeset patch # User Cristi Magherusan # Date 1186759073 -10800 # Node ID 218bf0a3466247540ccb2583c65392ee57e13a6c # Parent 3e9bc5fd5c369f078f963ded3e601ebdbd681a9b# Parent 6e3ae4fd65f1604c0a4a929495a4bb2fbae04e29 merge diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/Makefile --- a/src/audacious/Makefile Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/Makefile Fri Aug 10 18:17:53 2007 +0300 @@ -56,6 +56,7 @@ tuple_formatter.h \ ui_fileinfopopup.h \ ui_lastfm.h\ + ui_plugin_menu.h \ ui_preferences.h \ util.h \ vfs.h \ diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/main.c --- a/src/audacious/main.c Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/main.c Fri Aug 10 18:17:53 2007 +0300 @@ -629,7 +629,7 @@ cfg.mainwin_font = g_strdup(MAINWIN_DEFAULT_FONT); if (!cfg.gentitle_format) - cfg.gentitle_format = g_strdup("%{?artist:${artist} - }${?album:${album} - }${title}"); + cfg.gentitle_format = g_strdup("${?artist:${artist} - }${?album:${album} - }${title}"); if (!cfg.outputplugin) { gint iter; @@ -1193,6 +1193,16 @@ init_dbus(); #endif mowgli_init(); + + if (options.headless != 1) + { + /* UIManager + NOTE: this needs to be called before plugin init, cause + plugin init functions may want to add custom menu entries */ + ui_manager_init(); + ui_manager_create_menus(); + } + plugin_system_init(); /* Initialize the playlist system. */ @@ -1207,10 +1217,6 @@ gtk_accel_map_load(bmp_paths[BMP_PATH_ACCEL_FILE]); - /* uimanager */ - ui_manager_init(); - ui_manager_create_menus(); - if (!init_skins(cfg.skin)) { run_load_skin_error_dialog(cfg.skin); exit(EXIT_FAILURE); diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/tuple_formatter.c --- a/src/audacious/tuple_formatter.c Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/tuple_formatter.c Fri Aug 10 18:17:53 2007 +0300 @@ -64,6 +64,7 @@ TupleFormatterContext *ctx; const gchar *iter; gchar *out; + gint level = 0; g_return_val_if_fail(tuple != NULL, NULL); g_return_val_if_fail(string != NULL, NULL); @@ -75,21 +76,31 @@ for (iter = string; *iter != '\0'; iter++) { /* if it's raw text, just copy the byte */ - if (*iter != '$' && *iter != '%') + if (*iter != '$' && *iter != '%' && (*iter != '}' || (*iter == '}' && level > 0))) + { + level--; g_string_append_c(ctx->str, *iter); - else if (*iter == '$' && *(iter + 1) == '{') + } + else if (g_str_has_prefix(iter, "${") == TRUE) { GString *expression = g_string_new(""); GString *argument = g_string_new(""); GString *sel = expression; gchar *result; - gint level = 0; + gboolean rewind = FALSE; for (iter += 2; *iter != '\0'; iter++) { if (*iter == ':') { - sel = argument; + level++; + if (sel != argument) + { + sel = argument; + continue; + } + else + g_string_append_c(sel, *iter); continue; } @@ -101,14 +112,18 @@ level++; } } - else if (*iter == '}' && (sel == argument && --level > 0)) - g_string_append_c(sel, *iter); - else if (*iter == '}' && ((sel != argument) || (sel == argument && level <= 0))) + else if (*iter == '}' && (sel == argument)) { - if (sel == argument) + level--; + if (level + 1 > 0) + { iter++; + rewind = *(iter - 1) == '}' && *iter != '}'; + break; + } + } + else if (*iter == '}' && ((sel != argument))) break; - } else g_string_append_c(sel, *iter); } @@ -132,19 +147,23 @@ if (*iter == '\0') break; + + if (rewind) + iter--; } - else if (*iter == '%' && *(iter + 1) == '{') + else if (g_str_has_prefix(iter, "%{") == TRUE) { GString *expression = g_string_new(""); GString *argument = g_string_new(""); GString *sel = expression; gchar *result; - gint level = 0; + gboolean rewind = FALSE; for (iter += 2; *iter != '\0'; iter++) { if (*iter == ':') { + level++; sel = argument; continue; } @@ -157,14 +176,18 @@ level++; } } - else if (*iter == '}' && (sel == argument && --level > 0)) - g_string_append_c(sel, *iter); - else if (*iter == '}' && ((sel != argument) || (sel == argument && level <= 0))) + else if (*iter == '}' && (sel == argument)) { - if (sel == argument) + level--; + if (level + 1 > 0) + { iter++; + rewind = *(iter - 1) == '}' && *iter != '}'; + break; + } + } + else if (*iter == '}' && ((sel != argument))) break; - } else g_string_append_c(sel, *iter); } @@ -188,6 +211,9 @@ if (*iter == '\0') break; + + if (rewind) + iter--; } } diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/ui/mainwin.ui --- a/src/audacious/ui/mainwin.ui Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/ui/mainwin.ui Fri Aug 10 18:17:53 2007 +0300 @@ -128,6 +128,10 @@ + + + + diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/ui/playlist.ui --- a/src/audacious/ui/playlist.ui Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/ui/playlist.ui Fri Aug 10 18:17:53 2007 +0300 @@ -78,6 +78,11 @@ + + + + + diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/ui_equalizer.c --- a/src/audacious/ui_equalizer.c Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/ui_equalizer.c Fri Aug 10 18:17:53 2007 +0300 @@ -309,19 +309,6 @@ return FALSE; } -static gboolean -equalizerwin_configure(GtkWidget * window, - GdkEventConfigure * event, - gpointer data) -{ - if (!GTK_WIDGET_VISIBLE(window)) - return FALSE; - - cfg.equalizer_x = event->x; - cfg.equalizer_y = event->y; - return FALSE; -} - static void equalizerwin_close_cb(void) { @@ -572,8 +559,6 @@ G_CALLBACK(equalizerwin_press), NULL); g_signal_connect(equalizerwin, "button_release_event", G_CALLBACK(equalizerwin_release), NULL); - g_signal_connect(equalizerwin, "configure_event", - G_CALLBACK(equalizerwin_configure), NULL); g_signal_connect(equalizerwin, "key_press_event", G_CALLBACK(equalizerwin_keypress), NULL); } diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/ui_main.c --- a/src/audacious/ui_main.c Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/ui_main.c Fri Aug 10 18:17:53 2007 +0300 @@ -1107,23 +1107,6 @@ gtk_widget_grab_default(jump); } -static gboolean -mainwin_configure(GtkWidget * window, - GdkEventConfigure * event, - gpointer data) -{ - if (!GTK_WIDGET_VISIBLE(window)) - return FALSE; - - if (cfg.show_wm_decorations) - gdk_window_get_root_origin(window->window, - &cfg.player_x, &cfg.player_y); - else - gdk_window_get_deskrelative_origin(window->window, - &cfg.player_x, &cfg.player_y); - return FALSE; -} - /* * Rewritten 09/13/06: * @@ -2648,8 +2631,6 @@ G_CALLBACK(mainwin_scrolled), NULL); g_signal_connect(mainwin, "button_release_event", G_CALLBACK(mainwin_mouse_button_release), NULL); - g_signal_connect(mainwin, "configure_event", - G_CALLBACK(mainwin_configure), NULL); bmp_drag_dest_set(mainwin); diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/ui_manager.c --- a/src/audacious/ui_manager.c Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/ui_manager.c Fri Aug 10 18:17:53 2007 +0300 @@ -26,6 +26,9 @@ #include "actions-playlist.h" #include "actions-equalizer.h" +/* this header contains prototypes for plugin-available menu functions */ +#include "ui_plugin_menu.h" + /* TODO ui_main.h is only included because ui_manager.c needs the values of TimerMode enum; move that enum elsewhere so we can get rid of this include */ #include "ui_main.h" @@ -33,7 +36,8 @@ #include "icons-stock.h" -static GtkUIManager *ui_manager; +static GtkUIManager *ui_manager = NULL; +static gboolean menu_created = FALSE; /* toggle action entries */ @@ -396,6 +400,8 @@ { "lastfm", NULL, N_("Last.fm radio"), "L", N_("Play Last.fm radio"), G_CALLBACK(action_lastfm) }, + { "plugins", NULL , N_("Plugins") }, + { "preferences", GTK_STOCK_PREFERENCES , N_("Preferences"), "P", N_("Open preferences window"), G_CALLBACK(action_preferences) }, @@ -625,6 +631,29 @@ } +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 ); + return; +} + + void ui_manager_create_menus ( void ) { @@ -648,6 +677,9 @@ mainwin_view_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu/view" ); mainwin_general_menu = ui_manager_get_popup_menu( ui_manager , "/mainwin-menus/main-menu" ); + /* initialize plugins-menu for mainwin-menus */ + ui_manager_create_menus_init_pmenu( "/mainwin-menus/main-menu/plugins-menu" ); + gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/playlist.ui" , &gerr ); if ( gerr != NULL ) @@ -665,6 +697,9 @@ playlistwin_plsort_menu = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/misc-menu"); playlistwin_pllist_menu = ui_manager_get_popup_menu(ui_manager, "/playlist-menus/playlist-menu"); + /* initialize plugins-menu for playlist-menus */ + ui_manager_create_menus_init_pmenu( "/playlist-menus/playlist-menu/plugins-menu" ); + gtk_ui_manager_add_ui_from_file( ui_manager , DATA_DIR "/ui/equalizer.ui" , &gerr ); if ( gerr != NULL ) @@ -676,6 +711,8 @@ equalizerwin_presets_menu = ui_manager_get_popup_menu(ui_manager, "/equalizer-menus/preset-menu"); + menu_created = TRUE; + return; } @@ -728,3 +765,96 @@ gtk_menu_popup( menu , NULL , NULL , (GtkMenuPositionFunc) menu_popup_pos_func , pos , button , time ); } + + + +/******************************/ +/* plugin-available functions */ + + +gint +audacious_menu_plugin_item_add( gint menu_id , GtkWidget * item ) +{ + if ( menu_created ) + { + switch (menu_id) + { + case AUDACIOUS_MENU_MAIN: + { + GtkWidget *plugins_menu_item = gtk_ui_manager_get_widget( ui_manager , + "/mainwin-menus/main-menu/plugins-menu" ); + GtkWidget *plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) ); + gtk_menu_shell_append( GTK_MENU_SHELL(plugins_menu) , item ); + gtk_widget_show( plugins_menu_item ); + return 0; + } + + case AUDACIOUS_MENU_PLAYLIST: + { + GtkWidget *plugins_menu_item = gtk_ui_manager_get_widget( ui_manager , + "/playlist-menus/playlist-menu/plugins-menu" ); + GtkWidget *plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) ); + gtk_menu_shell_append( GTK_MENU_SHELL(plugins_menu) , item ); + gtk_widget_show( plugins_menu_item ); + return 0; + } + + default: + return -1; + } + } + else + return -1; +} + + +gint +audacious_menu_plugin_item_remove( gint menu_id , GtkWidget * item ) +{ + 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" ); + plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) ); + gtk_container_remove( GTK_CONTAINER(plugins_menu) , item ); + break; + } + + case AUDACIOUS_MENU_PLAYLIST: + { + plugins_menu_item = gtk_ui_manager_get_widget( ui_manager , + "/playlist-menus/playlist-menu/plugins-menu" ); + plugins_menu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(plugins_menu_item) ); + gtk_container_remove( GTK_CONTAINER(plugins_menu) , item ); + break; + } + + default: + return -1; + } + + if ( plugins_menu ) + { + /* 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; + } + else + return -1; + } + else + return -1; +} diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/ui_playlist.c --- a/src/audacious/ui_playlist.c Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/ui_playlist.c Fri Aug 10 18:17:53 2007 +0300 @@ -1594,6 +1594,7 @@ void playlistwin_show(void) { + gtk_window_move(GTK_WINDOW(playlistwin), cfg.playlist_x, cfg.playlist_y); GtkAction *action = gtk_action_group_get_action( toggleaction_group_others , "show playlist editor" ); gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(action) , TRUE ); @@ -1608,7 +1609,6 @@ gtk_widget_show_all(playlistwin); if (!cfg.playlist_shaded) gtk_widget_hide(playlistwin_sinfo); - ui_skinned_textbox_set_text(playlistwin_info, " "); gtk_window_present(GTK_WINDOW(playlistwin)); } diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/ui_plugin_menu.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audacious/ui_plugin_menu.h Fri Aug 10 18:17:53 2007 +0300 @@ -0,0 +1,38 @@ +/* Audacious - Cross-platform multimedia player + * Copyright (C) 2005-2007 Audacious development team. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +/* these functions are currently implemented in ui_manager.c */ + +#ifndef AUD_UIPLUGINMENU_H +#define AUD_UIPLUGINMENU_H + + +#include +#include +#include + + +#define AUDACIOUS_MENU_MAIN 0 +#define AUDACIOUS_MENU_PLAYLIST 1 + +gint audacious_menu_plugin_item_add( gint , GtkWidget * ); +gint audacious_menu_plugin_item_remove( gint , GtkWidget * ); + + +#endif /* AUD_UIPLUGINMENU_H */ diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/ui_skinned_window.c --- a/src/audacious/ui_skinned_window.c Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/ui_skinned_window.c Fri Aug 10 18:17:53 2007 +0300 @@ -79,6 +79,26 @@ if (widget_class->configure_event != NULL) widget_class->configure_event(widget, event); + if (!GTK_WIDGET_VISIBLE(widget)) + return FALSE; + + switch(window->type) { + case WINDOW_MAIN: + if (cfg.show_wm_decorations) + gdk_window_get_root_origin(widget->window, &cfg.player_x, &cfg.player_y); + else + gdk_window_get_deskrelative_origin(widget->window, &cfg.player_x, &cfg.player_y); + break; + case WINDOW_EQ: + cfg.equalizer_x = event->x; + cfg.equalizer_y = event->y; + break; + case WINDOW_PLAYLIST: + cfg.playlist_x = event->x; + cfg.playlist_y = event->y; + break; + } + window->x = event->x; window->y = event->y; diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/audacious/util.h --- a/src/audacious/util.h Fri Aug 10 14:21:21 2007 +0300 +++ b/src/audacious/util.h Fri Aug 10 18:17:53 2007 +0300 @@ -115,8 +115,10 @@ gchar *audacious_get_localdir(void); +/* menu-related function */ void audacious_menu_main_show(gint x, gint y, guint button, guint time); + G_END_DECLS #endif diff -r 3e9bc5fd5c36 -r 218bf0a34662 src/tests/tuple_formatter_test.c --- a/src/tests/tuple_formatter_test.c Fri Aug 10 14:21:21 2007 +0300 +++ b/src/tests/tuple_formatter_test.c Fri Aug 10 18:17:53 2007 +0300 @@ -106,6 +106,30 @@ } g_free(tstr); + tstr = tuple_formatter_process_string(tuple, "${?splork:${splork} - }${splork}"); + if (g_ascii_strcasecmp(tstr, "moo - moo")) + { + g_print("fail 10: '%s'\n", tstr); + return EXIT_FAILURE; + } + g_free(tstr); + + tstr = tuple_formatter_process_string(tuple, "${?splork:${?splork:${splork}} - }${splork}"); + if (g_ascii_strcasecmp(tstr, "moo - moo")) + { + g_print("fail 11: '%s'\n", tstr); + return EXIT_FAILURE; + } + g_free(tstr); + + tstr = tuple_formatter_process_string(tuple, "${?splork:${splork} - }${?splork:${splork} - }${splork}"); + if (g_ascii_strcasecmp(tstr, "moo - moo - moo")) + { + g_print("fail 12: '%s'\n", tstr); + return EXIT_FAILURE; + } + g_free(tstr); + mowgli_object_unref(tuple); return EXIT_SUCCESS;