00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 # include "config.h"
00022 #endif
00023
00024 #include <glib.h>
00025 #include <gtk/gtk.h>
00026 #include <string.h>
00027 #include <stddef.h>
00028 #include <stdio.h>
00029 #include <sys/types.h>
00030 #include <dirent.h>
00031 #include <unistd.h>
00032 #include <errno.h>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <gdk/gdkkeysyms.h>
00036
00037 #include <libaudcore/hook.h>
00038
00039 #include "audconfig.h"
00040 #include "compatibility.h"
00041 #include "debug.h"
00042 #include "i18n.h"
00043 #include "misc.h"
00044 #include "playback.h"
00045 #include "plugin.h"
00046 #include "pluginenum.h"
00047 #include "plugins.h"
00048 #include "effect.h"
00049 #include "general.h"
00050 #include "output.h"
00051 #include "playlist.h"
00052 #include "playlist-utils.h"
00053 #include "visualization.h"
00054 #include "util.h"
00055 #include "configdb.h"
00056 #include "preferences.h"
00057
00058 #include "ui_preferences.h"
00059
00060 #define TITLESTRING_UPDATE_TIMEOUT 3
00061
00062 static void sw_volume_toggled (void);
00063
00064 enum CategoryViewCols {
00065 CATEGORY_VIEW_COL_ICON,
00066 CATEGORY_VIEW_COL_NAME,
00067 CATEGORY_VIEW_COL_ID,
00068 CATEGORY_VIEW_N_COLS
00069 };
00070
00071 enum PluginViewCols {
00072 PLUGIN_VIEW_COL_ACTIVE,
00073 PLUGIN_VIEW_COL_DESC,
00074 PLUGIN_VIEW_COL_FILENAME,
00075 PLUGIN_VIEW_COL_ID,
00076 PLUGIN_VIEW_COL_PLUGIN_PTR,
00077 PLUGIN_VIEW_N_COLS
00078 };
00079
00080 enum PluginViewType {
00081 PLUGIN_VIEW_TYPE_INPUT,
00082 PLUGIN_VIEW_TYPE_GENERAL,
00083 PLUGIN_VIEW_TYPE_VIS,
00084 PLUGIN_VIEW_TYPE_EFFECT
00085 };
00086
00087 typedef struct {
00088 const gchar *icon_path;
00089 const gchar *name;
00090 } Category;
00091
00092 typedef struct {
00093 const gchar *name;
00094 const gchar *tag;
00095 } TitleFieldTag;
00096
00097 typedef struct {
00098 gint x;
00099 gint y;
00100 } MenuPos;
00101
00102 static void * prefswin = NULL;
00103 static GtkWidget *filepopup_settings = NULL;
00104 static GtkWidget *category_treeview = NULL;
00105 static GtkWidget *category_notebook = NULL;
00106 GtkWidget *filepopupbutton = NULL;
00107
00108
00109 GtkWidget *filepopup_settings_cover_name_include;
00110 GtkWidget *filepopup_settings_cover_name_exclude;
00111 GtkWidget *filepopup_settings_recurse_for_cover;
00112 GtkWidget *filepopup_settings_recurse_for_cover_depth;
00113 GtkWidget *filepopup_settings_recurse_for_cover_depth_box;
00114 GtkWidget *filepopup_settings_use_file_cover;
00115 GtkWidget *filepopup_settings_showprogressbar;
00116 GtkWidget *filepopup_settings_delay;
00117
00118
00119 GtkWidget *titlestring_entry;
00120 GtkWidget *filepopup_for_tuple_settings_button;
00121 static gint titlestring_timeout_counter = 0;
00122
00123 static Category categories[] = {
00124 {DATA_DIR "/images/audio.png", N_("Audio")},
00125 {DATA_DIR "/images/replay_gain.png", N_("Replay Gain")},
00126 {DATA_DIR "/images/connectivity.png", N_("Network")},
00127 {DATA_DIR "/images/playback.png", N_("Playback")},
00128 {DATA_DIR "/images/playlist.png", N_("Playlist")},
00129 {DATA_DIR "/images/plugins.png", N_("Plugins")},
00130 };
00131
00132 static gint n_categories = G_N_ELEMENTS(categories);
00133
00134 static TitleFieldTag title_field_tags[] = {
00135 { N_("Artist") , "${artist}" },
00136 { N_("Album") , "${album}" },
00137 { N_("Title") , "${title}" },
00138 { N_("Tracknumber"), "${track-number}" },
00139 { N_("Genre") , "${genre}" },
00140 { N_("Filename") , "${file-name}" },
00141 { N_("Filepath") , "${file-path}" },
00142 { N_("Date") , "${date}" },
00143 { N_("Year") , "${year}" },
00144 { N_("Comment") , "${comment}" },
00145 { N_("Codec") , "${codec}" },
00146 { N_("Quality") , "${quality}" },
00147 };
00148 static const guint n_title_field_tags = G_N_ELEMENTS(title_field_tags);
00149
00150 static ComboBoxElements chardet_detector_presets[] = {
00151 { N_("None") , N_("None") },
00152 { N_("Japanese") , N_("Japanese") },
00153 { N_("Taiwanese"), N_("Taiwanese") },
00154 { N_("Chinese") , N_("Chinese") },
00155 { N_("Korean") , N_("Korean") },
00156 { N_("Russian") , N_("Russian") },
00157 { N_("Greek") , N_("Greek") },
00158 { N_("Hebrew") , N_("Hebrew") },
00159 { N_("Turkish") , N_("Turkish") },
00160 { N_("Arabic") , N_("Arabic") },
00161 { N_("Polish") , N_("Polish") },
00162 { N_("Baltic") , N_("Baltic") },
00163 { N_("Universal"), N_("Universal") }
00164 };
00165
00166 static ComboBoxElements bitdepth_elements[] = {
00167 { GINT_TO_POINTER(16), "16" },
00168 { GINT_TO_POINTER(24), "24" },
00169 { GINT_TO_POINTER(32), "32" },
00170 {GINT_TO_POINTER (0), "Floating point"},
00171 };
00172
00173 typedef struct {
00174 void *next;
00175 GtkWidget *container;
00176 const gchar * pg_name;
00177 const gchar * img_url;
00178 } CategoryQueueEntry;
00179
00180 CategoryQueueEntry *category_queue = NULL;
00181
00182 static PreferencesWidget audio_page_widgets[] = {
00183 {WIDGET_LABEL, N_("<b>Bit Depth</b>"), NULL, NULL, NULL, FALSE},
00184 {WIDGET_COMBO_BOX, N_("Output bit depth:"), &cfg.output_bit_depth, NULL,
00185 N_("All streams will be converted to this bit depth.\n"
00186 "This should be the max supported bit depth of\nthe sound card or output plugin."), FALSE,
00187 {.combo = {bitdepth_elements, G_N_ELEMENTS(bitdepth_elements), TRUE}}, VALUE_INT},
00188 {WIDGET_LABEL, N_("<b>Volume Control</b>"), NULL, NULL, NULL, FALSE},
00189 {WIDGET_CHK_BTN, N_("Use software volume control"),
00190 & cfg.software_volume_control, sw_volume_toggled,
00191 N_("Use software volume control. This may be useful for situations where your audio system does not support controlling the playback volume."), FALSE},
00192 };
00193
00194 static PreferencesWidget rg_params_elements[] = {
00195 {WIDGET_SPIN_BTN, N_("Preamp:"), &cfg.replay_gain_preamp, NULL, NULL, FALSE, {.spin_btn = {-15, 15, 0.01, N_("dB")}}, VALUE_FLOAT},
00196 {WIDGET_SPIN_BTN, N_("Default gain:"), &cfg.default_gain, NULL, N_("This gain will be used if file doesn't contain Replay Gain metadata."), FALSE, {.spin_btn = {-15, 15, 0.01, N_("dB")}}, VALUE_FLOAT},
00197 {WIDGET_LABEL, N_("<span size=\"small\">Please remember that the most efficient way to prevent signal clipping is not to use positive values above.</span>"), NULL, NULL, NULL, FALSE, {.label = {"gtk-info"}}},
00198 };
00199
00200 static PreferencesWidget replay_gain_page_widgets[] = {
00201 {WIDGET_LABEL, N_("<b>Replay Gain configuration</b>"), NULL, NULL, NULL, FALSE},
00202 {WIDGET_CHK_BTN, N_("Enable Replay Gain"), &cfg.enable_replay_gain, NULL, NULL, FALSE},
00203 {WIDGET_LABEL, N_("<b>Replay Gain mode</b>"), NULL, NULL, NULL, TRUE},
00204 {WIDGET_RADIO_BTN, N_("Track gain/peak"), &cfg.replay_gain_track, NULL, NULL, TRUE},
00205 {WIDGET_RADIO_BTN, N_("Album gain/peak"), &cfg.replay_gain_album, NULL, NULL, TRUE},
00206 {WIDGET_LABEL, N_("<b>Miscellaneous</b>"), NULL, NULL, NULL, TRUE},
00207 {WIDGET_CHK_BTN, N_("Enable peak info clipping prevention"), &cfg.enable_clipping_prevention, NULL,
00208 N_("Use peak value from Replay Gain info for clipping prevention"), TRUE},
00209 {WIDGET_TABLE, NULL, NULL, NULL, NULL, TRUE, {.table = {rg_params_elements, G_N_ELEMENTS(rg_params_elements)}}},
00210 };
00211
00212 static PreferencesWidget proxy_host_port_elements[] = {
00213 {WIDGET_ENTRY, N_("Proxy hostname:"), "proxy_host", NULL, NULL, FALSE, {.entry = {FALSE}}, VALUE_CFG_STRING},
00214 {WIDGET_ENTRY, N_("Proxy port:"), "proxy_port", NULL, NULL, FALSE, {.entry = {FALSE}}, VALUE_CFG_STRING},
00215 };
00216
00217 static PreferencesWidget proxy_auth_elements[] = {
00218 {WIDGET_ENTRY, N_("Proxy username:"), "proxy_user", NULL, NULL, FALSE, {.entry = {FALSE}}, VALUE_CFG_STRING},
00219 {WIDGET_ENTRY, N_("Proxy password:"), "proxy_pass", NULL, NULL, FALSE, {.entry = {TRUE}}, VALUE_CFG_STRING},
00220 };
00221
00222 static PreferencesWidget connectivity_page_widgets[] = {
00223 {WIDGET_LABEL, N_("<b>Proxy Configuration</b>"), NULL, NULL, NULL, FALSE},
00224 {WIDGET_CHK_BTN, N_("Enable proxy usage"), "use_proxy", NULL, NULL, FALSE,
00225 .cfg_type = VALUE_CFG_BOOLEAN},
00226 {WIDGET_TABLE, NULL, NULL, NULL, NULL, TRUE, {.table = {proxy_host_port_elements, G_N_ELEMENTS(proxy_host_port_elements)}}},
00227 {WIDGET_CHK_BTN, N_("Use authentication with proxy"), "proxy_use_auth",
00228 NULL, NULL, FALSE, .cfg_type = VALUE_CFG_BOOLEAN},
00229 {WIDGET_TABLE, NULL, NULL, NULL, NULL, TRUE, {.table = {proxy_auth_elements, G_N_ELEMENTS(proxy_auth_elements)}}},
00230 {WIDGET_LABEL, N_("<span size=\"small\">Changing these settings will require a restart of Audacious.</span>"), NULL, NULL, NULL, FALSE, {.label = {"gtk-dialog-warning"}}},
00231 };
00232
00233 static PreferencesWidget playback_page_widgets[] = {
00234 {WIDGET_LABEL, N_("<b>Playback</b>"), NULL, NULL, NULL, FALSE},
00235 {WIDGET_CHK_BTN, N_("Continue playback on startup"), &cfg.resume_playback_on_startup, NULL,
00236 N_("When Audacious starts, automatically begin playing from the point where we stopped before."), FALSE},
00237 {WIDGET_CHK_BTN, N_("Don't advance in the playlist"), &cfg.no_playlist_advance, NULL,
00238 N_("When finished playing a song, don't automatically advance to the next."), FALSE},
00239 {WIDGET_CHK_BTN, N_("Clear current playlist when opening new files"),
00240 & cfg.clear_playlist, NULL, NULL, FALSE},
00241 };
00242
00243 static PreferencesWidget chardet_elements[] = {
00244 {WIDGET_COMBO_BOX, N_("Auto character encoding detector for:"), &cfg.chardet_detector, NULL, NULL, TRUE,
00245 {.combo = {chardet_detector_presets, G_N_ELEMENTS(chardet_detector_presets),
00246 #ifdef USE_CHARDET
00247 TRUE
00248 #else
00249 FALSE
00250 #endif
00251 }}, VALUE_STRING},
00252 {WIDGET_ENTRY, N_("Fallback character encodings:"), &cfg.chardet_fallback, aud_config_chardet_update, N_("List of character encodings used for fall back conversion of metadata. If automatic character encoding detector failed or has been disabled, encodings in this list would be treated as candidates of the encoding of metadata, and fall back conversion from these encodings to UTF-8 would be attempted."), TRUE, {.entry = {FALSE}}, VALUE_STRING},
00253 };
00254
00255 static PreferencesWidget playlist_page_widgets[] = {
00256 {WIDGET_LABEL, N_("<b>Metadata</b>"), NULL, NULL, NULL, FALSE},
00257 {WIDGET_TABLE, NULL, NULL, NULL, NULL, TRUE, {.table = {chardet_elements, G_N_ELEMENTS(chardet_elements)}}},
00258 };
00259
00260 static void prefswin_page_queue_destroy(CategoryQueueEntry *ent);
00261 void create_plugin_preferences_page(PluginPreferences *settings);
00262 void destroy_plugin_preferences_page(PluginPreferences *settings);
00263
00264 static void output_about (OutputPlugin * plugin)
00265 {
00266 if (plugin->about != NULL)
00267 plugin->about ();
00268 }
00269
00270 static void output_configure (OutputPlugin * plugin)
00271 {
00272 if (plugin->configure != NULL)
00273 plugin->configure ();
00274 }
00275
00276 static void
00277 change_category(GtkNotebook * notebook,
00278 GtkTreeSelection * selection)
00279 {
00280 GtkTreeModel *model;
00281 GtkTreeIter iter;
00282 gint index;
00283
00284 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
00285 return;
00286
00287 gtk_tree_model_get(model, &iter, CATEGORY_VIEW_COL_ID, &index, -1);
00288 gtk_notebook_set_current_page(notebook, index);
00289 }
00290
00291 static void output_plugin_open_prefs (GtkComboBox * combo, void * unused)
00292 {
00293 output_configure (g_list_nth_data (get_output_list (),
00294 gtk_combo_box_get_active (combo)));
00295 }
00296
00297 static void output_plugin_open_info (GtkComboBox * combo, void * unused)
00298 {
00299 output_about (g_list_nth_data (get_output_list (), gtk_combo_box_get_active
00300 (combo)));
00301 }
00302
00303 static void
00304 plugin_toggle(GtkCellRendererToggle * cell,
00305 const gchar * path_str,
00306 gpointer data)
00307 {
00308 GtkTreeModel *model = GTK_TREE_MODEL(data);
00309 GtkTreeIter iter;
00310 GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
00311 Plugin *plugin = NULL;
00312 gint plugin_type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), "plugin_type"));
00313 gboolean enabled;
00314
00315
00316 gtk_tree_model_get_iter(model, &iter, path);
00317
00318 gtk_tree_model_get (model, & iter, PLUGIN_VIEW_COL_ACTIVE, & enabled,
00319 PLUGIN_VIEW_COL_PLUGIN_PTR, & plugin, -1);
00320 enabled = ! enabled;
00321
00322 switch (plugin_type)
00323 {
00324 case PLUGIN_VIEW_TYPE_INPUT:
00325 plugin_set_enabled (plugin_by_header (plugin), enabled);
00326 break;
00327 case PLUGIN_VIEW_TYPE_GENERAL:
00328 general_plugin_enable (plugin_by_header (plugin), enabled);
00329 break;
00330 case PLUGIN_VIEW_TYPE_VIS:
00331 vis_plugin_enable (plugin_by_header (plugin), enabled);
00332 break;
00333 case PLUGIN_VIEW_TYPE_EFFECT:
00334 effect_plugin_enable (plugin_by_header (plugin), enabled);
00335 break;
00336 }
00337
00338 gtk_list_store_set ((GtkListStore *) model, & iter, PLUGIN_VIEW_COL_ACTIVE,
00339 enabled, -1);
00340
00341 if (plugin && plugin->settings && plugin->settings->type == PREFERENCES_PAGE) {
00342 if (enabled)
00343 create_plugin_preferences_page(plugin->settings);
00344 else
00345 destroy_plugin_preferences_page(plugin->settings);
00346 }
00347
00348 gtk_tree_path_free(path);
00349 }
00350
00351 static void on_output_plugin_cbox_changed (GtkComboBox * combo, void * unused)
00352 {
00353 set_current_output_plugin (g_list_nth_data (get_output_list (),
00354 gtk_combo_box_get_active (combo)));
00355 }
00356
00357 static void
00358 on_output_plugin_cbox_realize(GtkComboBox * cbox,
00359 gpointer data)
00360 {
00361 GList *olist = get_output_list();
00362 OutputPlugin * op;
00363 gint i = 0, selected = 0;
00364
00365 if (olist == NULL) {
00366 gtk_widget_set_sensitive(GTK_WIDGET(cbox), FALSE);
00367 return;
00368 }
00369
00370 for (i = 0; olist != NULL; i++, olist = g_list_next(olist)) {
00371 op = OUTPUT_PLUGIN(olist->data);
00372
00373 if (olist->data == current_output_plugin)
00374 selected = i;
00375
00376 gtk_combo_box_append_text(cbox, op->description);
00377 }
00378
00379 gtk_combo_box_set_active(cbox, selected);
00380 g_signal_connect(cbox, "changed",
00381 G_CALLBACK(on_output_plugin_cbox_changed), NULL);
00382 }
00383
00384 static void
00385 on_plugin_view_realize(GtkTreeView * treeview,
00386 GCallback callback,
00387 gpointer data,
00388 gint plugin_type)
00389 {
00390 GtkListStore *store;
00391 GtkTreeIter iter;
00392
00393 GtkCellRenderer *renderer;
00394 GtkTreeViewColumn *column;
00395
00396 GList *ilist;
00397 gchar *description[2];
00398 gint id = 0;
00399
00400 GList *list = (GList *) data;
00401
00402 store = gtk_list_store_new(PLUGIN_VIEW_N_COLS,
00403 G_TYPE_BOOLEAN, G_TYPE_STRING,
00404 G_TYPE_STRING, G_TYPE_INT, G_TYPE_POINTER);
00405 g_object_set_data(G_OBJECT(store), "plugin_type" , GINT_TO_POINTER(plugin_type));
00406
00407 column = gtk_tree_view_column_new();
00408 gtk_tree_view_column_set_title(column, _("Enabled"));
00409 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
00410 gtk_tree_view_column_set_spacing(column, 4);
00411 gtk_tree_view_column_set_resizable(column, FALSE);
00412 gtk_tree_view_column_set_fixed_width(column, 50);
00413
00414 renderer = gtk_cell_renderer_toggle_new();
00415 g_signal_connect(renderer, "toggled",
00416 G_CALLBACK(callback), store);
00417 gtk_tree_view_column_pack_start(column, renderer, TRUE);
00418 gtk_tree_view_column_set_attributes(column, renderer, "active",
00419 PLUGIN_VIEW_COL_ACTIVE, NULL);
00420
00421 gtk_tree_view_append_column(treeview, column);
00422
00423 column = gtk_tree_view_column_new();
00424 gtk_tree_view_column_set_title(column, _("Description"));
00425 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
00426 gtk_tree_view_column_set_spacing(column, 4);
00427 gtk_tree_view_column_set_resizable(column, TRUE);
00428
00429
00430 renderer = gtk_cell_renderer_text_new();
00431 gtk_tree_view_column_pack_start(column, renderer, FALSE);
00432 gtk_tree_view_column_set_attributes(column, renderer,
00433 "text", PLUGIN_VIEW_COL_DESC, NULL);
00434 gtk_tree_view_append_column(treeview, column);
00435
00436 column = gtk_tree_view_column_new();
00437
00438 gtk_tree_view_column_set_title(column, _("Filename"));
00439 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
00440 gtk_tree_view_column_set_spacing(column, 4);
00441 gtk_tree_view_column_set_resizable(column, TRUE);
00442
00443 renderer = gtk_cell_renderer_text_new();
00444 gtk_tree_view_column_pack_start(column, renderer, TRUE);
00445 gtk_tree_view_column_set_attributes(column, renderer, "text",
00446 PLUGIN_VIEW_COL_FILENAME, NULL);
00447
00448 gtk_tree_view_append_column(treeview, column);
00449
00450 MOWGLI_ITER_FOREACH(ilist, list)
00451 {
00452 Plugin *plugin = PLUGIN(ilist->data);
00453 gboolean enabled = plugin_get_enabled (plugin_by_header (plugin));
00454
00455 description[0] = g_strdup(plugin->description);
00456 description[1] = g_strdup(plugin->filename);
00457
00458 gtk_list_store_append(store, &iter);
00459 gtk_list_store_set(store, &iter,
00460 PLUGIN_VIEW_COL_ACTIVE, enabled,
00461 PLUGIN_VIEW_COL_DESC, description[0],
00462 PLUGIN_VIEW_COL_FILENAME, description[1],
00463 PLUGIN_VIEW_COL_ID, id++,
00464 PLUGIN_VIEW_COL_PLUGIN_PTR, plugin, -1);
00465
00466 g_free(description[1]);
00467 g_free(description[0]);
00468 }
00469
00470 gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
00471 }
00472
00473 static void
00474 on_input_plugin_view_realize(GtkTreeView * treeview,
00475 gpointer data)
00476 {
00477 on_plugin_view_realize (treeview, (GCallback) plugin_toggle, plugin_get_list(PLUGIN_TYPE_INPUT), PLUGIN_VIEW_TYPE_INPUT);
00478 }
00479
00480 static void
00481 on_effect_plugin_view_realize(GtkTreeView * treeview,
00482 gpointer data)
00483 {
00484 on_plugin_view_realize (treeview, (GCallback) plugin_toggle, plugin_get_list
00485 (PLUGIN_TYPE_EFFECT), PLUGIN_VIEW_TYPE_EFFECT);
00486 }
00487
00488 static void
00489 on_general_plugin_view_realize(GtkTreeView * treeview,
00490 gpointer data)
00491 {
00492 on_plugin_view_realize (treeview, (GCallback) plugin_toggle, plugin_get_list
00493 (PLUGIN_TYPE_GENERAL), PLUGIN_VIEW_TYPE_GENERAL);
00494 }
00495
00496 static void
00497 on_vis_plugin_view_realize(GtkTreeView * treeview,
00498 gpointer data)
00499 {
00500 on_plugin_view_realize(treeview, G_CALLBACK(plugin_toggle), plugin_get_list(PLUGIN_TYPE_VIS), PLUGIN_VIEW_TYPE_VIS);
00501 }
00502
00503 static void
00504 editable_insert_text(GtkEditable * editable,
00505 const gchar * text,
00506 gint * pos)
00507 {
00508 gtk_editable_insert_text(editable, text, strlen(text), pos);
00509 }
00510
00511 static void
00512 titlestring_tag_menu_callback(GtkMenuItem * menuitem,
00513 gpointer data)
00514 {
00515 const gchar *separator = " - ";
00516 gint item = GPOINTER_TO_INT(data);
00517 gint pos;
00518
00519 pos = gtk_editable_get_position(GTK_EDITABLE(titlestring_entry));
00520
00521
00522 if (g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(titlestring_entry)), -1) > 0)
00523 editable_insert_text(GTK_EDITABLE(titlestring_entry), separator, &pos);
00524
00525 editable_insert_text(GTK_EDITABLE(titlestring_entry), _(title_field_tags[item].tag),
00526 &pos);
00527
00528 gtk_editable_set_position(GTK_EDITABLE(titlestring_entry), pos);
00529 }
00530
00531 static void
00532 util_menu_position(GtkMenu * menu, gint * x, gint * y,
00533 gboolean * push_in, gpointer data)
00534 {
00535 GtkRequisition requisition;
00536 gint screen_width;
00537 gint screen_height;
00538 MenuPos *pos = data;
00539
00540 gtk_widget_size_request(GTK_WIDGET(menu), &requisition);
00541
00542 screen_width = gdk_screen_width();
00543 screen_height = gdk_screen_height();
00544
00545 *x = CLAMP(pos->x - 2, 0, MAX(0, screen_width - requisition.width));
00546 *y = CLAMP(pos->y - 2, 0, MAX(0, screen_height - requisition.height));
00547 }
00548
00549 static void
00550 on_titlestring_help_button_clicked(GtkButton * button,
00551 gpointer data)
00552 {
00553 GtkMenu *menu;
00554 MenuPos *pos = g_newa(MenuPos, 1);
00555 GdkWindow *parent, *window;
00556
00557 gint x_ro, y_ro;
00558 gint x_widget, y_widget;
00559 gint x_size, y_size;
00560
00561 g_return_if_fail (button != NULL);
00562 g_return_if_fail (GTK_IS_MENU (data));
00563
00564 parent = gtk_widget_get_parent_window(GTK_WIDGET(button));
00565 window = gtk_widget_get_window(GTK_WIDGET(button));
00566
00567 gdk_drawable_get_size(parent, &x_size, &y_size);
00568 gdk_window_get_root_origin(window, &x_ro, &y_ro);
00569 gdk_window_get_position(window, &x_widget, &y_widget);
00570
00571 pos->x = x_size + x_ro;
00572 pos->y = y_size + y_ro - 100;
00573
00574 menu = GTK_MENU(data);
00575 gtk_menu_popup (menu, NULL, NULL, util_menu_position, pos,
00576 0, GDK_CURRENT_TIME);
00577 }
00578
00579
00580 static void
00581 on_titlestring_entry_realize(GtkWidget * entry,
00582 gpointer data)
00583 {
00584 gtk_entry_set_text(GTK_ENTRY(entry), cfg.gentitle_format);
00585 }
00586
00587 static gboolean
00588 titlestring_timeout_proc (gpointer data)
00589 {
00590 titlestring_timeout_counter--;
00591
00592 if(titlestring_timeout_counter <= 0) {
00593 titlestring_timeout_counter = 0;
00594 playlist_reformat_titles ();
00595 return FALSE;
00596 } else {
00597 return TRUE;
00598 }
00599 }
00600
00601 static void
00602 on_titlestring_entry_changed(GtkWidget * entry,
00603 gpointer data)
00604 {
00605 g_free(cfg.gentitle_format);
00606 cfg.gentitle_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
00607
00608 if(titlestring_timeout_counter == 0) {
00609 g_timeout_add_seconds (1, (GSourceFunc) titlestring_timeout_proc, NULL);
00610 }
00611
00612 titlestring_timeout_counter = TITLESTRING_UPDATE_TIMEOUT;
00613 }
00614
00615 static void
00616 on_titlestring_cbox_realize(GtkWidget * cbox,
00617 gpointer data)
00618 {
00619 gtk_combo_box_set_active(GTK_COMBO_BOX(cbox), cfg.titlestring_preset);
00620 gtk_widget_set_sensitive(GTK_WIDGET(data),
00621 (cfg.titlestring_preset == (gint)n_titlestring_presets));
00622 }
00623
00624 static void
00625 on_titlestring_cbox_changed(GtkWidget * cbox,
00626 gpointer data)
00627 {
00628 gint position = gtk_combo_box_get_active(GTK_COMBO_BOX(cbox));
00629
00630 cfg.titlestring_preset = position;
00631 gtk_widget_set_sensitive(GTK_WIDGET(data), (position == 6));
00632
00633 playlist_reformat_titles ();
00634 }
00635
00636 static void
00637 on_font_btn_realize(GtkFontButton * button, gchar **cfg)
00638 {
00639 gtk_font_button_set_font_name(button, *cfg);
00640 }
00641
00642 static void
00643 on_font_btn_font_set(GtkFontButton * button, gchar **config)
00644 {
00645 g_free(*config);
00646 *config = g_strdup(gtk_font_button_get_font_name(button));
00647 AUDDBG("Returned font name: \"%s\"\n", *config);
00648 void (*callback) (void) = g_object_get_data(G_OBJECT(button), "callback");
00649 if (callback != NULL) callback();
00650 }
00651
00652 static void
00653 plugin_preferences_ok(GtkWidget *widget, PluginPreferences *settings)
00654 {
00655 if (settings->apply)
00656 settings->apply();
00657
00658 gtk_widget_destroy(GTK_WIDGET(settings->data));
00659 }
00660
00661 static void
00662 plugin_preferences_apply(GtkWidget *widget, PluginPreferences *settings)
00663 {
00664 if (settings->apply)
00665 settings->apply();
00666 }
00667
00668 static void
00669 plugin_preferences_cancel(GtkWidget *widget, PluginPreferences *settings)
00670 {
00671 if (settings->cancel)
00672 settings->cancel();
00673
00674 gtk_widget_destroy(GTK_WIDGET(settings->data));
00675 }
00676
00677 static void
00678 plugin_preferences_destroy(GtkWidget *widget, PluginPreferences *settings)
00679 {
00680 gtk_widget_destroy(widget);
00681
00682 if (settings->cleanup)
00683 settings->cleanup();
00684
00685 settings->data = NULL;
00686 }
00687
00688 static void
00689 create_plugin_preferences(PluginPreferences *settings)
00690 {
00691 GtkWidget *window;
00692 GtkWidget *vbox, *bbox, *ok, *apply, *cancel;
00693
00694 if (settings->data != NULL) {
00695 gtk_widget_show(GTK_WIDGET(settings->data));
00696 return;
00697 }
00698
00699 if (settings->init)
00700 settings->init();
00701
00702 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00703 gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DIALOG);
00704 gtk_window_set_title(GTK_WINDOW(window), _(settings->title));
00705 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
00706
00707 g_signal_connect(G_OBJECT(window), "destroy",
00708 G_CALLBACK(plugin_preferences_destroy), settings);
00709
00710 vbox = gtk_vbox_new(FALSE, 10);
00711 create_widgets(GTK_BOX(vbox), settings->prefs, settings->n_prefs);
00712 gtk_container_add(GTK_CONTAINER(window), vbox);
00713
00714 bbox = gtk_hbutton_box_new();
00715 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
00716 gtk_box_set_spacing(GTK_BOX(bbox), 5);
00717 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
00718
00719 ok = gtk_button_new_from_stock(GTK_STOCK_OK);
00720 g_signal_connect(G_OBJECT(ok), "clicked",
00721 G_CALLBACK(plugin_preferences_ok), settings);
00722 gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0);
00723 gtk_widget_set_can_default (ok, TRUE);
00724 gtk_widget_grab_default(ok);
00725
00726 apply = gtk_button_new_from_stock(GTK_STOCK_APPLY);
00727 g_signal_connect(G_OBJECT(apply), "clicked",
00728 G_CALLBACK(plugin_preferences_apply), settings);
00729 gtk_box_pack_start(GTK_BOX(bbox), apply, TRUE, TRUE, 0);
00730
00731 cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
00732 g_signal_connect(G_OBJECT(cancel), "clicked",
00733 G_CALLBACK(plugin_preferences_cancel), settings);
00734 gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
00735
00736 gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(prefswin));
00737 gtk_widget_show_all(window);
00738 settings->data = (gpointer)window;
00739 }
00740
00741 static void
00742 plugin_treeview_open_prefs(GtkTreeView *treeview)
00743 {
00744 GtkTreeSelection *selection;
00745 GtkTreeModel *model;
00746 GtkTreeIter iter;
00747 Plugin *plugin = NULL;
00748
00749 selection = gtk_tree_view_get_selection(treeview);
00750 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
00751 return;
00752 gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_PLUGIN_PTR, &plugin, -1);
00753
00754 g_return_if_fail(plugin != NULL);
00755 g_return_if_fail((plugin->configure != NULL) ||
00756 ((plugin->settings != NULL) && (plugin->settings->type == PREFERENCES_WINDOW)));
00757
00758 if (plugin->configure != NULL)
00759 plugin->configure();
00760 else
00761 create_plugin_preferences(plugin->settings);
00762 }
00763
00764 static void
00765 plugin_treeview_open_info(GtkTreeView *treeview)
00766 {
00767 GtkTreeSelection *selection;
00768 GtkTreeModel *model;
00769 GtkTreeIter iter;
00770 Plugin *plugin = NULL;
00771
00772 selection = gtk_tree_view_get_selection(treeview);
00773 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
00774 return;
00775 gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_PLUGIN_PTR, &plugin, -1);
00776
00777 g_return_if_fail(plugin != NULL);
00778 plugin->about();
00779 }
00780
00781 static void
00782 plugin_treeview_enable_prefs(GtkTreeView * treeview, GtkButton * button)
00783 {
00784 GtkTreeSelection *selection;
00785 GtkTreeModel *model;
00786 GtkTreeIter iter;
00787 Plugin *plugin = NULL;
00788
00789 selection = gtk_tree_view_get_selection(treeview);
00790 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
00791 return;
00792
00793 gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_PLUGIN_PTR, &plugin, -1);
00794
00795 g_return_if_fail(plugin != NULL);
00796
00797 gtk_widget_set_sensitive(GTK_WIDGET(button),
00798 ((plugin->configure != NULL) ||
00799 (plugin->settings ? (plugin->settings->type == PREFERENCES_WINDOW) : FALSE)));
00800 }
00801
00802 static void
00803 plugin_treeview_enable_info(GtkTreeView * treeview, GtkButton * button)
00804 {
00805 GtkTreeSelection *selection;
00806 GtkTreeModel *model;
00807 GtkTreeIter iter;
00808 Plugin *plugin = NULL;
00809
00810 selection = gtk_tree_view_get_selection(treeview);
00811 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
00812 return;
00813
00814 gtk_tree_model_get(model, &iter, PLUGIN_VIEW_COL_PLUGIN_PTR, &plugin, -1);
00815
00816 g_return_if_fail(plugin != NULL);
00817
00818 gtk_widget_set_sensitive(GTK_WIDGET(button), plugin->about != NULL);
00819 }
00820
00821
00822 static void
00823 output_plugin_enable_info(GtkComboBox * cbox, GtkButton * button)
00824 {
00825 GList *plist;
00826
00827 gint id = gtk_combo_box_get_active(cbox);
00828
00829 plist = get_output_list();
00830 plist = g_list_nth(plist, id);
00831
00832 gtk_widget_set_sensitive(GTK_WIDGET(button),
00833 OUTPUT_PLUGIN(plist->data)->about != NULL);
00834 }
00835
00836 static void
00837 output_plugin_enable_prefs(GtkComboBox * cbox, GtkButton * button)
00838 {
00839 GList *plist;
00840 gint id = gtk_combo_box_get_active(cbox);
00841
00842 plist = get_output_list();
00843 plist = g_list_nth(plist, id);
00844
00845 gtk_widget_set_sensitive(GTK_WIDGET(button),
00846 OUTPUT_PLUGIN(plist->data)->configure != NULL);
00847 }
00848
00849 static void
00850 on_output_plugin_bufsize_realize(GtkSpinButton *button,
00851 gpointer data)
00852 {
00853 gtk_spin_button_set_value(button, cfg.output_buffer_size);
00854 }
00855
00856 static void
00857 on_output_plugin_bufsize_value_changed(GtkSpinButton *button,
00858 gpointer data)
00859 {
00860 cfg.output_buffer_size = gtk_spin_button_get_value_as_int(button);
00861 }
00862
00863 static void
00864 on_spin_btn_realize_gint(GtkSpinButton *button, gint *cfg)
00865 {
00866 gtk_spin_button_set_value(button, *cfg);
00867 }
00868
00869 static void
00870 on_spin_btn_changed_gint(GtkSpinButton *button, gint *cfg)
00871 {
00872 *cfg = gtk_spin_button_get_value_as_int(button);
00873 }
00874
00875 static void
00876 on_spin_btn_realize_gfloat(GtkSpinButton *button, gfloat *cfg)
00877 {
00878 gtk_spin_button_set_value(button, (gdouble) *cfg);
00879 }
00880
00881 static void
00882 on_spin_btn_changed_gfloat(GtkSpinButton *button, gfloat *cfg)
00883 {
00884 *cfg = (gfloat) gtk_spin_button_get_value(button);
00885 }
00886
00887
00888 static void
00889 on_category_treeview_realize(GtkTreeView * treeview,
00890 GtkNotebook * notebook)
00891 {
00892 GtkListStore *store;
00893 GtkCellRenderer *renderer;
00894 GtkTreeViewColumn *column;
00895 GtkTreeSelection *selection;
00896 GtkTreeIter iter;
00897 GdkPixbuf *img;
00898 CategoryQueueEntry *qlist;
00899 gint i;
00900
00901 column = gtk_tree_view_column_new();
00902 gtk_tree_view_column_set_title(column, _("Category"));
00903 gtk_tree_view_append_column(treeview, column);
00904 gtk_tree_view_column_set_spacing(column, 2);
00905
00906 renderer = gtk_cell_renderer_pixbuf_new();
00907 gtk_tree_view_column_pack_start(column, renderer, FALSE);
00908 gtk_tree_view_column_set_attributes(column, renderer, "pixbuf", 0, NULL);
00909
00910 renderer = gtk_cell_renderer_text_new();
00911 gtk_tree_view_column_pack_start(column, renderer, FALSE);
00912 gtk_tree_view_column_set_attributes(column, renderer, "text", 1, NULL);
00913
00914 gint width, height;
00915 gtk_widget_get_size_request(GTK_WIDGET(treeview), &width, &height);
00916 g_object_set(G_OBJECT(renderer), "wrap-width", width - 64 - 24, "wrap-mode",
00917 PANGO_WRAP_WORD_CHAR, NULL);
00918
00919 store = gtk_list_store_new(CATEGORY_VIEW_N_COLS,
00920 GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);
00921 gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
00922
00923 for (i = 0; i < n_categories; i++) {
00924 img = gdk_pixbuf_new_from_file(categories[i].icon_path, NULL);
00925 gtk_list_store_append(store, &iter);
00926 gtk_list_store_set(store, &iter,
00927 CATEGORY_VIEW_COL_ICON, img,
00928 CATEGORY_VIEW_COL_NAME,
00929 gettext(categories[i].name), CATEGORY_VIEW_COL_ID,
00930 i, -1);
00931 g_object_unref(img);
00932 }
00933
00934 selection = gtk_tree_view_get_selection(treeview);
00935
00936 g_signal_connect_swapped(selection, "changed",
00937 G_CALLBACK(change_category), notebook);
00938
00939
00940 category_treeview = GTK_WIDGET(treeview);
00941
00942
00943 for (qlist = category_queue; qlist != NULL; qlist = category_queue)
00944 {
00945 CategoryQueueEntry *ent = (CategoryQueueEntry *) qlist;
00946
00947 prefswin_page_new(ent->container, ent->pg_name, ent->img_url);
00948 prefswin_page_queue_destroy(ent);
00949 }
00950 }
00951
00952 static void
00953 on_show_filepopup_for_tuple_realize(GtkToggleButton * button, gpointer data)
00954 {
00955 gtk_toggle_button_set_active(button, cfg.show_filepopup_for_tuple);
00956 filepopupbutton = GTK_WIDGET(button);
00957
00958 gtk_widget_set_sensitive(filepopup_for_tuple_settings_button, cfg.show_filepopup_for_tuple);
00959 }
00960
00961 static void
00962 on_show_filepopup_for_tuple_toggled(GtkToggleButton * button, gpointer data)
00963 {
00964 cfg.show_filepopup_for_tuple = gtk_toggle_button_get_active(button);
00965
00966 gtk_widget_set_sensitive(filepopup_for_tuple_settings_button, cfg.show_filepopup_for_tuple);
00967 }
00968
00969 static void
00970 on_recurse_for_cover_toggled(GtkToggleButton *button, gpointer data)
00971 {
00972 gtk_widget_set_sensitive(GTK_WIDGET(data),
00973 gtk_toggle_button_get_active(button));
00974 }
00975
00976 static void
00977 on_filepopup_for_tuple_settings_clicked(GtkButton *button, gpointer data)
00978 {
00979 gtk_entry_set_text(GTK_ENTRY(filepopup_settings_cover_name_include), cfg.cover_name_include);
00980 gtk_entry_set_text(GTK_ENTRY(filepopup_settings_cover_name_exclude), cfg.cover_name_exclude);
00981 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(filepopup_settings_recurse_for_cover), cfg.recurse_for_cover);
00982 gtk_spin_button_set_value(GTK_SPIN_BUTTON(filepopup_settings_recurse_for_cover_depth), cfg.recurse_for_cover_depth);
00983 on_recurse_for_cover_toggled(GTK_TOGGLE_BUTTON(filepopup_settings_recurse_for_cover), filepopup_settings_recurse_for_cover_depth_box);
00984 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(filepopup_settings_use_file_cover), cfg.use_file_cover);
00985 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(filepopup_settings_showprogressbar), cfg.filepopup_showprogressbar);
00986 gtk_spin_button_set_value(GTK_SPIN_BUTTON(filepopup_settings_delay), cfg.filepopup_delay);
00987
00988 gtk_widget_show(filepopup_settings);
00989 }
00990
00991 static void
00992 on_filepopup_settings_ok_clicked(GtkButton *button, gpointer data)
00993 {
00994 g_free(cfg.cover_name_include);
00995 cfg.cover_name_include = g_strdup(gtk_entry_get_text(GTK_ENTRY(filepopup_settings_cover_name_include)));
00996
00997 g_free(cfg.cover_name_exclude);
00998 cfg.cover_name_exclude = g_strdup(gtk_entry_get_text(GTK_ENTRY(filepopup_settings_cover_name_exclude)));
00999
01000 cfg.recurse_for_cover = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filepopup_settings_recurse_for_cover));
01001 cfg.recurse_for_cover_depth = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filepopup_settings_recurse_for_cover_depth));
01002 cfg.use_file_cover = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filepopup_settings_use_file_cover));
01003 cfg.filepopup_showprogressbar = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filepopup_settings_showprogressbar));
01004 cfg.filepopup_delay = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filepopup_settings_delay));
01005
01006 gtk_widget_hide(filepopup_settings);
01007 }
01008
01009 static void
01010 on_filepopup_settings_cancel_clicked(GtkButton *button, gpointer data)
01011 {
01012 gtk_widget_hide(filepopup_settings);
01013 }
01014
01015 static void
01016 on_toggle_button_toggled(GtkToggleButton * button, gboolean *cfg)
01017 {
01018 *cfg = gtk_toggle_button_get_active(button);
01019 void (*callback) (void) = g_object_get_data(G_OBJECT(button), "callback");
01020 if (callback != NULL) callback();
01021 GtkWidget *child = g_object_get_data(G_OBJECT(button), "child");
01022 if (child) gtk_widget_set_sensitive(GTK_WIDGET(child), *cfg);
01023 }
01024
01025 static void
01026 on_toggle_button_realize(GtkToggleButton * button, gboolean *cfg)
01027 {
01028 gtk_toggle_button_set_active(button, cfg ? *cfg : FALSE);
01029 GtkWidget *child = g_object_get_data(G_OBJECT(button), "child");
01030 if (child) gtk_widget_set_sensitive(GTK_WIDGET(child), cfg ? *cfg : FALSE);
01031 }
01032
01033 static void
01034 on_toggle_button_cfg_toggled(GtkToggleButton *button, gchar *cfg)
01035 {
01036 g_return_if_fail(cfg != NULL);
01037
01038 mcs_handle_t *db;
01039 gboolean ret = gtk_toggle_button_get_active(button);
01040
01041 db = cfg_db_open();
01042 cfg_db_set_bool(db, NULL, cfg, ret);
01043 cfg_db_close(db);
01044 }
01045
01046 static void
01047 on_toggle_button_cfg_realize(GtkToggleButton *button, gchar *cfg)
01048 {
01049 mcs_handle_t *db;
01050 gboolean ret;
01051
01052 g_return_if_fail(cfg != NULL);
01053
01054 db = cfg_db_open();
01055
01056 if (cfg_db_get_bool(db, NULL, cfg, &ret) != FALSE)
01057 gtk_toggle_button_set_active(button, ret);
01058
01059 cfg_db_close(db);
01060 }
01061
01062 static void
01063 on_entry_realize(GtkEntry *entry, gchar **cfg)
01064 {
01065 g_return_if_fail(cfg != NULL);
01066
01067 if (*cfg)
01068 gtk_entry_set_text(entry, *cfg);
01069 }
01070
01071 static void
01072 on_entry_changed(GtkEntry *entry, gchar **cfg)
01073 {
01074 void (*callback) (void) = g_object_get_data(G_OBJECT(entry), "callback");
01075 const gchar *ret;
01076
01077 g_return_if_fail(cfg != NULL);
01078
01079 g_free(*cfg);
01080
01081 ret = gtk_entry_get_text(entry);
01082
01083 if (ret == NULL)
01084 *cfg = g_strdup("");
01085 else
01086 *cfg = g_strdup(ret);
01087
01088 if (callback != NULL) callback();
01089 }
01090
01091 static void
01092 on_entry_cfg_realize(GtkEntry *entry, gchar *cfg)
01093 {
01094 mcs_handle_t *db;
01095 gchar *ret;
01096
01097 g_return_if_fail(cfg != NULL);
01098
01099 db = cfg_db_open();
01100
01101 if (cfg_db_get_string(db, NULL, cfg, &ret) != FALSE)
01102 gtk_entry_set_text(entry, ret);
01103
01104 cfg_db_close(db);
01105 }
01106
01107 static void
01108 on_entry_cfg_changed(GtkEntry *entry, gchar *cfg)
01109 {
01110 mcs_handle_t *db;
01111 gchar *ret = g_strdup(gtk_entry_get_text(entry));
01112
01113 g_return_if_fail(cfg != NULL);
01114
01115 db = cfg_db_open();
01116 cfg_db_set_string(db, NULL, cfg, ret);
01117 cfg_db_close(db);
01118
01119 g_free(ret);
01120 }
01121
01122 static void
01123 on_cbox_changed_int(GtkComboBox * combobox, PreferencesWidget *widget)
01124 {
01125 gint position = 0;
01126
01127 position = gtk_combo_box_get_active(GTK_COMBO_BOX(combobox));
01128 *((gint *)widget->cfg) = GPOINTER_TO_INT(widget->data.combo.elements[position].value);
01129 }
01130
01131 static void
01132 on_cbox_changed_string(GtkComboBox * combobox, PreferencesWidget *widget)
01133 {
01134 gint position = 0;
01135
01136 position = gtk_combo_box_get_active(GTK_COMBO_BOX(combobox));
01137
01138 g_free(*((gchar **)widget->cfg));
01139
01140 *((gchar **)widget->cfg) = g_strdup(widget->data.combo.elements[position].value);
01141 }
01142
01143 static void
01144 on_cbox_realize(GtkComboBox *combobox, PreferencesWidget * widget)
01145 {
01146 guint i=0,index=0;
01147
01148 for(i=0; i<widget->data.combo.n_elements; i++) {
01149 gtk_combo_box_append_text(combobox, _(widget->data.combo.elements[i].label));
01150 }
01151
01152 if (widget->data.combo.enabled) {
01153 switch (widget->cfg_type) {
01154 case VALUE_INT:
01155 g_signal_connect(combobox, "changed",
01156 G_CALLBACK(on_cbox_changed_int), widget);
01157 for(i=0; i<widget->data.combo.n_elements; i++) {
01158 if (GPOINTER_TO_INT(widget->data.combo.elements[i].value) == *((gint *) widget->cfg)) {
01159 index = i;
01160 break;
01161 }
01162 }
01163 break;
01164 case VALUE_STRING:
01165 g_signal_connect(combobox, "changed",
01166 G_CALLBACK(on_cbox_changed_string), widget);
01167 for(i=0; i<widget->data.combo.n_elements; i++) {
01168 if(!strcmp((gchar *)widget->data.combo.elements[i].value, *((gchar **)widget->cfg))) {
01169 index = i;
01170 break;
01171 }
01172 }
01173 break;
01174 case VALUE_NULL:
01175 break;
01176 default:
01177 g_warning("Unhandled cbox value type");
01178 break;
01179 }
01180 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), index);
01181 } else {
01182 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), -1);
01183 gtk_widget_set_sensitive(GTK_WIDGET(combobox), 0);
01184 }
01185 }
01186
01187 void
01188 create_filepopup_settings(void)
01189 {
01190 GtkWidget *vbox;
01191 GtkWidget *table;
01192
01193 GtkWidget *label_cover_retrieve;
01194 GtkWidget *label_cover_search;
01195 GtkWidget *label_exclude;
01196 GtkWidget *label_include;
01197 GtkWidget *label_search_depth;
01198 GtkWidget *label_misc;
01199 GtkWidget *label_delay;
01200
01201 GtkObject *recurse_for_cover_depth_adj;
01202 GtkObject *delay_adj;
01203 GtkWidget *alignment;
01204
01205 GtkWidget *hbox;
01206 GtkWidget *hbuttonbox;
01207 GtkWidget *btn_cancel;
01208 GtkWidget *btn_ok;
01209
01210 filepopup_settings = gtk_window_new(GTK_WINDOW_TOPLEVEL);
01211 gtk_container_set_border_width(GTK_CONTAINER(filepopup_settings), 12);
01212 gtk_window_set_title(GTK_WINDOW(filepopup_settings), _("Popup Information Settings"));
01213 gtk_window_set_position(GTK_WINDOW(filepopup_settings), GTK_WIN_POS_CENTER_ON_PARENT);
01214 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(filepopup_settings), TRUE);
01215 gtk_window_set_type_hint(GTK_WINDOW(filepopup_settings), GDK_WINDOW_TYPE_HINT_DIALOG);
01216 gtk_window_set_transient_for(GTK_WINDOW(filepopup_settings), GTK_WINDOW(prefswin));
01217
01218 vbox = gtk_vbox_new(FALSE, 12);
01219 gtk_container_add(GTK_CONTAINER(filepopup_settings), vbox);
01220
01221 label_cover_retrieve = gtk_label_new(_("<b>Cover image retrieve</b>"));
01222 gtk_box_pack_start(GTK_BOX(vbox), label_cover_retrieve, FALSE, FALSE, 0);
01223 gtk_label_set_use_markup(GTK_LABEL(label_cover_retrieve), TRUE);
01224 gtk_misc_set_alignment(GTK_MISC(label_cover_retrieve), 0, 0.5);
01225
01226 label_cover_search = gtk_label_new(_("While searching for the album's cover, Audacious looks for certain words in the filename. You can specify those words in the lists below, separated using commas."));
01227 gtk_box_pack_start(GTK_BOX(vbox), label_cover_search, FALSE, FALSE, 0);
01228 gtk_label_set_line_wrap(GTK_LABEL(label_cover_search), TRUE);
01229 gtk_misc_set_alignment(GTK_MISC(label_cover_search), 0, 0);
01230 gtk_misc_set_padding(GTK_MISC(label_cover_search), 12, 0);
01231
01232 table = gtk_table_new(2, 2, FALSE);
01233 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
01234 gtk_table_set_row_spacings(GTK_TABLE(table), 4);
01235 gtk_table_set_col_spacings(GTK_TABLE(table), 4);
01236
01237 filepopup_settings_cover_name_include = gtk_entry_new();
01238 gtk_table_attach(GTK_TABLE(table), filepopup_settings_cover_name_include, 1, 2, 0, 1,
01239 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
01240 (GtkAttachOptions) (0), 0, 0);
01241 gtk_entry_set_activates_default(GTK_ENTRY(filepopup_settings_cover_name_include), TRUE);
01242
01243 label_exclude = gtk_label_new(_("Exclude:"));
01244 gtk_table_attach(GTK_TABLE(table), label_exclude, 0, 1, 1, 2,
01245 (GtkAttachOptions) (0),
01246 (GtkAttachOptions) (0), 0, 0);
01247 gtk_misc_set_alignment(GTK_MISC(label_exclude), 0, 0.5);
01248 gtk_misc_set_padding(GTK_MISC(label_exclude), 12, 0);
01249
01250 label_include = gtk_label_new(_("Include:"));
01251 gtk_table_attach(GTK_TABLE(table), label_include, 0, 1, 0, 1,
01252 (GtkAttachOptions) (0),
01253 (GtkAttachOptions) (0), 0, 0);
01254 gtk_misc_set_alignment(GTK_MISC(label_include), 0, 0.5);
01255 gtk_misc_set_padding(GTK_MISC(label_include), 12, 0);
01256
01257 filepopup_settings_cover_name_exclude = gtk_entry_new();
01258 gtk_table_attach(GTK_TABLE(table), filepopup_settings_cover_name_exclude, 1, 2, 1, 2,
01259 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
01260 (GtkAttachOptions) (0), 0, 0);
01261 gtk_entry_set_activates_default(GTK_ENTRY(filepopup_settings_cover_name_exclude), TRUE);
01262
01263 alignment = gtk_alignment_new(0.5, 0.5, 1, 1);
01264 gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0);
01265 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
01266
01267 filepopup_settings_recurse_for_cover = gtk_check_button_new_with_mnemonic(_("Recursively search for cover"));
01268 gtk_container_add(GTK_CONTAINER(alignment), filepopup_settings_recurse_for_cover);
01269
01270 alignment = gtk_alignment_new(0.5, 0.5, 1, 1);
01271 gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
01272 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 45, 0);
01273
01274 filepopup_settings_recurse_for_cover_depth_box = gtk_hbox_new(FALSE, 0);
01275 gtk_container_add(GTK_CONTAINER(alignment), filepopup_settings_recurse_for_cover_depth_box);
01276
01277 label_search_depth = gtk_label_new(_("Search depth: "));
01278 gtk_box_pack_start(GTK_BOX(filepopup_settings_recurse_for_cover_depth_box), label_search_depth, TRUE, TRUE, 0);
01279 gtk_misc_set_padding(GTK_MISC(label_search_depth), 4, 0);
01280
01281 recurse_for_cover_depth_adj = gtk_adjustment_new(0, 0, 100, 1, 10, 0);
01282 filepopup_settings_recurse_for_cover_depth = gtk_spin_button_new(GTK_ADJUSTMENT(recurse_for_cover_depth_adj), 1, 0);
01283 gtk_box_pack_start(GTK_BOX(filepopup_settings_recurse_for_cover_depth_box), filepopup_settings_recurse_for_cover_depth, TRUE, TRUE, 0);
01284 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(filepopup_settings_recurse_for_cover_depth), TRUE);
01285
01286 alignment = gtk_alignment_new(0.5, 0.5, 1, 1);
01287 gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0);
01288 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
01289
01290 filepopup_settings_use_file_cover = gtk_check_button_new_with_mnemonic(_("Use per-file cover"));
01291 gtk_container_add(GTK_CONTAINER(alignment), filepopup_settings_use_file_cover);
01292
01293 label_misc = gtk_label_new(_("<b>Miscellaneous</b>"));
01294 gtk_box_pack_start(GTK_BOX(vbox), label_misc, FALSE, FALSE, 0);
01295 gtk_label_set_use_markup(GTK_LABEL(label_misc), TRUE);
01296 gtk_misc_set_alignment(GTK_MISC(label_misc), 0, 0.5);
01297
01298 alignment = gtk_alignment_new(0.5, 0.5, 1, 1);
01299 gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
01300 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
01301
01302 filepopup_settings_showprogressbar = gtk_check_button_new_with_mnemonic(_("Show Progress bar for the current track"));
01303 gtk_container_add(GTK_CONTAINER(alignment), filepopup_settings_showprogressbar);
01304
01305 alignment = gtk_alignment_new(0, 0.5, 1, 1);
01306 gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0);
01307 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
01308
01309 hbox = gtk_hbox_new(FALSE, 0);
01310 gtk_container_add(GTK_CONTAINER(alignment), hbox);
01311
01312 label_delay = gtk_label_new(_("Delay until filepopup comes up: "));
01313 gtk_box_pack_start(GTK_BOX(hbox), label_delay, TRUE, TRUE, 0);
01314 gtk_misc_set_alignment(GTK_MISC(label_delay), 0, 0.5);
01315 gtk_misc_set_padding(GTK_MISC(label_delay), 12, 0);
01316
01317 delay_adj = gtk_adjustment_new(0, 0, 100, 1, 10, 0);
01318 filepopup_settings_delay = gtk_spin_button_new(GTK_ADJUSTMENT(delay_adj), 1, 0);
01319 gtk_box_pack_start(GTK_BOX(hbox), filepopup_settings_delay, TRUE, TRUE, 0);
01320 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(filepopup_settings_delay), TRUE);
01321
01322 hbuttonbox = gtk_hbutton_box_new();
01323 gtk_box_pack_start(GTK_BOX(vbox), hbuttonbox, FALSE, FALSE, 0);
01324 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END);
01325 gtk_box_set_spacing(GTK_BOX(hbuttonbox), 6);
01326
01327 btn_cancel = gtk_button_new_from_stock("gtk-cancel");
01328 gtk_container_add(GTK_CONTAINER(hbuttonbox), btn_cancel);
01329
01330 btn_ok = gtk_button_new_from_stock("gtk-ok");
01331 gtk_container_add(GTK_CONTAINER(hbuttonbox), btn_ok);
01332 gtk_widget_set_can_default(btn_ok, TRUE);
01333
01334 g_signal_connect(G_OBJECT(filepopup_settings), "delete_event",
01335 G_CALLBACK(gtk_widget_hide_on_delete),
01336 NULL);
01337 g_signal_connect(G_OBJECT(btn_cancel), "clicked",
01338 G_CALLBACK(on_filepopup_settings_cancel_clicked),
01339 NULL);
01340 g_signal_connect(G_OBJECT(btn_ok), "clicked",
01341 G_CALLBACK(on_filepopup_settings_ok_clicked),
01342 NULL);
01343 g_signal_connect(G_OBJECT(filepopup_settings_recurse_for_cover), "toggled",
01344 G_CALLBACK(on_recurse_for_cover_toggled),
01345 filepopup_settings_recurse_for_cover_depth_box);
01346
01347 gtk_widget_grab_default(btn_ok);
01348 gtk_widget_show_all(vbox);
01349 }
01350
01351 static void create_spin_button (PreferencesWidget * widget, GtkWidget * *
01352 label_pre, GtkWidget * * spin_btn, GtkWidget * * label_past, const gchar *
01353 domain)
01354 {
01355 g_return_if_fail(widget->type == WIDGET_SPIN_BTN);
01356
01357 * label_pre = gtk_label_new (dgettext (domain, widget->label));
01358 gtk_misc_set_alignment(GTK_MISC(*label_pre), 0, 0.5);
01359 gtk_misc_set_padding(GTK_MISC(*label_pre), 4, 0);
01360
01361 *spin_btn = gtk_spin_button_new_with_range(widget->data.spin_btn.min,
01362 widget->data.spin_btn.max,
01363 widget->data.spin_btn.step);
01364
01365
01366 if (widget->tooltip)
01367 gtk_widget_set_tooltip_text (* spin_btn, dgettext (domain,
01368 widget->tooltip));
01369
01370 if (widget->data.spin_btn.right_label) {
01371 * label_past = gtk_label_new (dgettext (domain,
01372 widget->data.spin_btn.right_label));
01373 gtk_misc_set_alignment(GTK_MISC(*label_past), 0, 0.5);
01374 gtk_misc_set_padding(GTK_MISC(*label_past), 4, 0);
01375 }
01376
01377 switch (widget->cfg_type) {
01378 case VALUE_INT:
01379 g_signal_connect(G_OBJECT(*spin_btn), "value_changed",
01380 G_CALLBACK(on_spin_btn_changed_gint),
01381 widget->cfg);
01382 g_signal_connect(G_OBJECT(*spin_btn), "realize",
01383 G_CALLBACK(on_spin_btn_realize_gint),
01384 widget->cfg);
01385 break;
01386 case VALUE_FLOAT:
01387 g_signal_connect(G_OBJECT(*spin_btn), "value_changed",
01388 G_CALLBACK(on_spin_btn_changed_gfloat),
01389 widget->cfg);
01390 g_signal_connect(G_OBJECT(*spin_btn), "realize",
01391 G_CALLBACK(on_spin_btn_realize_gfloat),
01392 widget->cfg);
01393 break;
01394 case VALUE_NULL:
01395 break;
01396 default:
01397 g_warning("Unsupported value type for spin button");
01398 }
01399 }
01400
01401 void create_font_btn (PreferencesWidget * widget, GtkWidget * * label,
01402 GtkWidget * * font_btn, const gchar * domain)
01403 {
01404 *font_btn = gtk_font_button_new();
01405 gtk_font_button_set_use_font(GTK_FONT_BUTTON(*font_btn), TRUE);
01406 gtk_font_button_set_use_size(GTK_FONT_BUTTON(*font_btn), TRUE);
01407 if (widget->label) {
01408 * label = gtk_label_new_with_mnemonic (dgettext (domain, widget->label));
01409 gtk_label_set_use_markup(GTK_LABEL(*label), TRUE);
01410 gtk_misc_set_alignment(GTK_MISC(*label), 1, 0.5);
01411 gtk_label_set_justify(GTK_LABEL(*label), GTK_JUSTIFY_RIGHT);
01412 gtk_label_set_mnemonic_widget(GTK_LABEL(*label), *font_btn);
01413 }
01414
01415 if (widget->data.font_btn.title)
01416 gtk_font_button_set_title (GTK_FONT_BUTTON (* font_btn),
01417 dgettext (domain, widget->data.font_btn.title));
01418
01419 g_object_set_data ((GObject *) (* font_btn), "callback", (void *)
01420 widget->callback);
01421
01422 g_signal_connect(G_OBJECT(*font_btn), "font_set",
01423 G_CALLBACK(on_font_btn_font_set),
01424 (gchar**)widget->cfg);
01425 g_signal_connect(G_OBJECT(*font_btn), "realize",
01426 G_CALLBACK(on_font_btn_realize),
01427 (gchar**)widget->cfg);
01428 }
01429
01430 static void create_entry (PreferencesWidget * widget, GtkWidget * * label,
01431 GtkWidget * * entry, const gchar * domain)
01432 {
01433 *entry = gtk_entry_new();
01434 gtk_entry_set_visibility(GTK_ENTRY(*entry), !widget->data.entry.password);
01435
01436 if (widget->label)
01437 * label = gtk_label_new (dgettext (domain, widget->label));
01438
01439 if (widget->tooltip)
01440 gtk_widget_set_tooltip_text (* entry, dgettext (domain, widget->tooltip));
01441
01442 g_object_set_data ((GObject *) (* entry), "callback", (void *)
01443 widget->callback);
01444
01445 switch (widget->cfg_type) {
01446 case VALUE_STRING:
01447 g_signal_connect(G_OBJECT(*entry), "realize",
01448 G_CALLBACK(on_entry_realize),
01449 widget->cfg);
01450 g_signal_connect(G_OBJECT(*entry), "changed",
01451 G_CALLBACK(on_entry_changed),
01452 widget->cfg);
01453 break;
01454 case VALUE_CFG_STRING:
01455 g_signal_connect(G_OBJECT(*entry), "realize",
01456 G_CALLBACK(on_entry_cfg_realize),
01457 widget->cfg);
01458 g_signal_connect(G_OBJECT(*entry), "changed",
01459 G_CALLBACK(on_entry_cfg_changed),
01460 widget->cfg);
01461 break;
01462 default:
01463 g_warning("Unhandled entry value type %d", widget->cfg_type);
01464 }
01465 }
01466
01467 static void create_label (PreferencesWidget * widget, GtkWidget * * label,
01468 GtkWidget * * icon, const gchar * domain)
01469 {
01470 if (widget->data.label.stock_id)
01471 *icon = gtk_image_new_from_stock(widget->data.label.stock_id, GTK_ICON_SIZE_BUTTON);
01472
01473 * label = gtk_label_new_with_mnemonic (dgettext (domain, widget->label));
01474 gtk_label_set_use_markup(GTK_LABEL(*label), TRUE);
01475
01476 if (widget->data.label.single_line == FALSE)
01477 gtk_label_set_line_wrap(GTK_LABEL(*label), TRUE);
01478
01479 gtk_misc_set_alignment(GTK_MISC(*label), 0, 0.5);
01480 }
01481
01482 static void create_cbox (PreferencesWidget * widget, GtkWidget * * label,
01483 GtkWidget * * combobox, const gchar * domain)
01484 {
01485 *combobox = gtk_combo_box_new_text();
01486
01487 if (widget->label) {
01488 * label = gtk_label_new (dgettext (domain, widget->label));
01489 gtk_misc_set_alignment(GTK_MISC(*label), 1, 0.5);
01490 }
01491
01492 g_signal_connect_after(G_OBJECT(*combobox), "realize",
01493 G_CALLBACK(on_cbox_realize),
01494 widget);
01495 }
01496
01497 static void fill_table (GtkWidget * table, PreferencesWidget * elements, gint
01498 amt, const gchar * domain)
01499 {
01500 gint x;
01501 GtkWidget *widget_left, *widget_middle, *widget_right;
01502 GtkAttachOptions middle_policy = (GtkAttachOptions) (0);
01503
01504 for (x = 0; x < amt; ++x) {
01505 widget_left = widget_middle = widget_right = NULL;
01506 switch (elements[x].type) {
01507 case WIDGET_SPIN_BTN:
01508 create_spin_button (& elements[x], & widget_left,
01509 & widget_middle, & widget_right, domain);
01510 middle_policy = (GtkAttachOptions) (GTK_FILL);
01511 break;
01512 case WIDGET_LABEL:
01513 create_label (& elements[x], & widget_middle, & widget_left,
01514 domain);
01515 middle_policy = (GtkAttachOptions) (GTK_FILL);
01516 break;
01517 case WIDGET_FONT_BTN:
01518 create_font_btn (& elements[x], & widget_left, & widget_middle,
01519 domain);
01520 middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL);
01521 break;
01522 case WIDGET_ENTRY:
01523 create_entry (& elements[x], & widget_left, & widget_middle,
01524 domain);
01525 middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL);
01526 break;
01527 case WIDGET_COMBO_BOX:
01528 create_cbox (& elements[x], & widget_left, & widget_middle,
01529 domain);
01530 middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL);
01531 break;
01532 default:
01533 g_warning("Unsupported widget type %d in table", elements[x].type);
01534 }
01535
01536 if (widget_left)
01537 gtk_table_attach(GTK_TABLE (table), widget_left, 0, 1, x, x+1,
01538 (GtkAttachOptions) (0),
01539 (GtkAttachOptions) (0), 0, 0);
01540
01541 if (widget_middle)
01542 gtk_table_attach(GTK_TABLE(table), widget_middle, 1, widget_right ? 2 : 3, x, x+1,
01543 middle_policy,
01544 (GtkAttachOptions) (0), 4, 0);
01545
01546 if (widget_right)
01547 gtk_table_attach(GTK_TABLE(table), widget_right, 2, 3, x, x+1,
01548 (GtkAttachOptions) (0),
01549 (GtkAttachOptions) (0), 0, 0);
01550 }
01551 }
01552
01553
01554
01555 void create_widgets_with_domain (void * box, PreferencesWidget * widgets, gint
01556 amt, const gchar * domain)
01557 {
01558 gint x;
01559 GtkWidget *alignment = NULL, *widget = NULL;
01560 GtkWidget *child_box = NULL;
01561 GSList *radio_btn_group = NULL;
01562
01563 for (x = 0; x < amt; ++x) {
01564 if (widgets[x].child) {
01565 if (!child_box) {
01566 child_box = gtk_vbox_new(FALSE, 0);
01567 g_object_set_data(G_OBJECT(widget), "child", child_box);
01568 alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
01569 gtk_box_pack_start(box, alignment, FALSE, FALSE, 0);
01570 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 24, 0);
01571 gtk_container_add (GTK_CONTAINER (alignment), child_box);
01572 }
01573 } else
01574 child_box = NULL;
01575
01576 alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
01577 gtk_box_pack_start(child_box ? GTK_BOX(child_box) : box, alignment, FALSE, FALSE, 0);
01578
01579 if (radio_btn_group && widgets[x].type != WIDGET_RADIO_BTN)
01580 radio_btn_group = NULL;
01581
01582 switch(widgets[x].type) {
01583 case WIDGET_CHK_BTN:
01584 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
01585 widget = gtk_check_button_new_with_mnemonic (dgettext (domain,
01586 widgets[x].label));
01587 g_object_set_data ((GObject *) widget, "callback",
01588 (void *) widgets[x].callback);
01589
01590 if (widgets[x].cfg_type == VALUE_CFG_BOOLEAN) {
01591 g_signal_connect(G_OBJECT(widget), "toggled",
01592 G_CALLBACK(on_toggle_button_cfg_toggled),
01593 widgets[x].cfg);
01594 g_signal_connect(G_OBJECT(widget), "realize",
01595 G_CALLBACK(on_toggle_button_cfg_realize),
01596 widgets[x].cfg);
01597 } else {
01598 if (widgets[x].cfg) {
01599 g_signal_connect(G_OBJECT(widget), "toggled",
01600 G_CALLBACK(on_toggle_button_toggled),
01601 widgets[x].cfg);
01602 } else {
01603 gtk_widget_set_sensitive(widget, FALSE);
01604 }
01605 g_signal_connect(G_OBJECT(widget), "realize",
01606 G_CALLBACK(on_toggle_button_realize),
01607 widgets[x].cfg);
01608 }
01609 break;
01610 case WIDGET_LABEL:
01611 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 12, 6, 0, 0);
01612
01613 GtkWidget *label = NULL, *icon = NULL;
01614 create_label (& widgets[x], & label, & icon, domain);
01615
01616 if (icon == NULL)
01617 widget = label;
01618 else {
01619 widget = gtk_hbox_new(FALSE, 6);
01620 gtk_box_pack_start(GTK_BOX(widget), icon, FALSE, FALSE, 0);
01621 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 0);
01622 }
01623 break;
01624 case WIDGET_RADIO_BTN:
01625 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
01626 widget = gtk_radio_button_new_with_mnemonic (radio_btn_group,
01627 dgettext (domain, widgets[x].label));
01628 radio_btn_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
01629 g_signal_connect(G_OBJECT(widget), "toggled",
01630 G_CALLBACK(on_toggle_button_toggled),
01631 widgets[x].cfg);
01632 g_signal_connect(G_OBJECT(widget), "realize",
01633 G_CALLBACK(on_toggle_button_realize),
01634 widgets[x].cfg);
01635 break;
01636 case WIDGET_SPIN_BTN:
01637 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 12, 0);
01638
01639 widget = gtk_hbox_new(FALSE, 6);
01640
01641 GtkWidget *label_pre = NULL, *spin_btn = NULL, *label_past = NULL;
01642 create_spin_button (& widgets[x], & label_pre, & spin_btn,
01643 & label_past, domain);
01644
01645 if (label_pre)
01646 gtk_box_pack_start(GTK_BOX(widget), label_pre, FALSE, FALSE, 0);
01647 if (spin_btn)
01648 gtk_box_pack_start(GTK_BOX(widget), spin_btn, FALSE, FALSE, 0);
01649 if (label_past)
01650 gtk_box_pack_start(GTK_BOX(widget), label_past, FALSE, FALSE, 0);
01651
01652 break;
01653 case WIDGET_CUSTOM:
01654 if (widgets[x].data.populate)
01655 widget = widgets[x].data.populate();
01656 else
01657 widget = NULL;
01658
01659 break;
01660 case WIDGET_FONT_BTN:
01661 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
01662
01663 widget = gtk_hbox_new(FALSE, 6);
01664
01665 GtkWidget *font_btn = NULL;
01666 create_font_btn (& widgets[x], & label, & font_btn, domain);
01667
01668 if (label)
01669 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 0);
01670 if (font_btn)
01671 gtk_box_pack_start(GTK_BOX(widget), font_btn, FALSE, FALSE, 0);
01672 break;
01673 case WIDGET_TABLE:
01674 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
01675
01676 widget = gtk_table_new(widgets[x].data.table.rows, 3, FALSE);
01677 fill_table (widget, widgets[x].data.table.elem,
01678 widgets[x].data.table.rows, domain);
01679 gtk_table_set_row_spacings(GTK_TABLE(widget), 6);
01680 break;
01681 case WIDGET_ENTRY:
01682 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 6, 12);
01683
01684 widget = gtk_hbox_new(FALSE, 6);
01685
01686 GtkWidget *entry = NULL;
01687 create_entry (& widgets[x], & label, & entry, domain);
01688
01689 if (label)
01690 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 0);
01691 if (entry)
01692 gtk_box_pack_start(GTK_BOX(widget), entry, TRUE, TRUE, 0);
01693 break;
01694 case WIDGET_COMBO_BOX:
01695 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
01696
01697 widget = gtk_hbox_new(FALSE, 10);
01698
01699 GtkWidget *combo = NULL;
01700 create_cbox (& widgets[x], & label, & combo, domain);
01701
01702 if (label)
01703 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 0);
01704 if (combo)
01705 gtk_box_pack_start(GTK_BOX(widget), combo, FALSE, FALSE, 0);
01706 break;
01707 case WIDGET_BOX:
01708 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 3, 0);
01709
01710 if (widgets[x].data.box.horizontal) {
01711 widget = gtk_hbox_new(FALSE, 0);
01712 } else {
01713 widget = gtk_vbox_new(FALSE, 0);
01714 }
01715
01716 create_widgets(GTK_BOX(widget), widgets[x].data.box.elem, widgets[x].data.box.n_elem);
01717
01718 if (widgets[x].data.box.frame) {
01719 GtkWidget *tmp;
01720 tmp = widget;
01721
01722 widget = gtk_frame_new (dgettext (domain, widgets[x].label));
01723 gtk_container_add(GTK_CONTAINER(widget), tmp);
01724 }
01725 break;
01726 case WIDGET_NOTEBOOK:
01727 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 3, 0);
01728
01729 widget = gtk_notebook_new();
01730
01731 gint i;
01732 for (i = 0; i<widgets[x].data.notebook.n_tabs; i++) {
01733 GtkWidget *vbox;
01734 vbox = gtk_vbox_new(FALSE, 5);
01735 create_widgets(GTK_BOX(vbox), widgets[x].data.notebook.tabs[i].settings, widgets[x].data.notebook.tabs[i].n_settings);
01736
01737 gtk_notebook_append_page (GTK_NOTEBOOK (widget), vbox,
01738 gtk_label_new (dgettext (domain,
01739 widgets[x].data.notebook.tabs[i].name)));
01740 }
01741 break;
01742 case WIDGET_SEPARATOR:
01743 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 6, 0, 0);
01744
01745 if (widgets[x].data.separator.horizontal == TRUE) {
01746 widget = gtk_hseparator_new();
01747 } else {
01748 widget = gtk_vseparator_new();
01749 }
01750 break;
01751 default:
01752
01753 g_error("This shouldn't ever happen - expect things to break.");
01754 continue;
01755 }
01756
01757 if (widget && !gtk_widget_get_parent(widget))
01758 gtk_container_add(GTK_CONTAINER(alignment), widget);
01759 if (widget && widgets[x].tooltip && widgets[x].type != WIDGET_SPIN_BTN)
01760 gtk_widget_set_tooltip_text (widget, dgettext (domain,
01761 widgets[x].tooltip));
01762 }
01763
01764 }
01765
01766 static GtkWidget *
01767 create_titlestring_tag_menu(void)
01768 {
01769 GtkWidget *titlestring_tag_menu, *menu_item;
01770 guint i;
01771
01772 titlestring_tag_menu = gtk_menu_new();
01773 for(i = 0; i < n_title_field_tags; i++) {
01774 menu_item = gtk_menu_item_new_with_label(_(title_field_tags[i].name));
01775 gtk_menu_shell_append(GTK_MENU_SHELL(titlestring_tag_menu), menu_item);
01776 g_signal_connect(menu_item, "activate",
01777 G_CALLBACK(titlestring_tag_menu_callback),
01778 GINT_TO_POINTER(i));
01779 };
01780 gtk_widget_show_all(titlestring_tag_menu);
01781
01782 return titlestring_tag_menu;
01783 }
01784
01785 static void
01786 create_playback_category(void)
01787 {
01788 GtkWidget *playback_page_vbox;
01789 GtkWidget *widgets_vbox;
01790
01791 playback_page_vbox = gtk_vbox_new (FALSE, 0);
01792 gtk_container_add (GTK_CONTAINER (category_notebook), playback_page_vbox);
01793
01794 widgets_vbox = gtk_vbox_new (FALSE, 0);
01795 create_widgets(GTK_BOX(widgets_vbox), playback_page_widgets, G_N_ELEMENTS(playback_page_widgets));
01796 gtk_box_pack_start (GTK_BOX (playback_page_vbox), widgets_vbox, TRUE, TRUE, 0);
01797 }
01798
01799 static void
01800 create_replay_gain_category(void)
01801 {
01802 GtkWidget *rg_page_vbox;
01803 GtkWidget *widgets_vbox;
01804
01805 rg_page_vbox = gtk_vbox_new (FALSE, 0);
01806 gtk_container_add (GTK_CONTAINER (category_notebook), rg_page_vbox);
01807
01808 widgets_vbox = gtk_vbox_new (FALSE, 0);
01809 create_widgets(GTK_BOX(widgets_vbox), replay_gain_page_widgets, G_N_ELEMENTS(replay_gain_page_widgets));
01810 gtk_box_pack_start (GTK_BOX (rg_page_vbox), widgets_vbox, TRUE, TRUE, 0);
01811 }
01812
01813 static void show_numbers_cb (GtkToggleButton * numbers, void * unused)
01814 {
01815 cfg.show_numbers_in_pl = gtk_toggle_button_get_active (numbers);
01816
01817 hook_call ("playlist update", NULL);
01818 hook_call ("title change", NULL);
01819 }
01820
01821 static void
01822 create_playlist_category(void)
01823 {
01824 GtkWidget *playlist_page_vbox;
01825 GtkWidget *vbox5;
01826 GtkWidget *alignment55;
01827 GtkWidget *label60;
01828 GtkWidget *alignment56;
01829 GtkWidget *table6;
01830 GtkWidget *titlestring_help_button;
01831 GtkWidget *image1;
01832 GtkWidget *titlestring_cbox;
01833 GtkWidget *label62;
01834 GtkWidget *label61;
01835 GtkWidget *alignment85;
01836 GtkWidget *label84;
01837 GtkWidget *alignment86;
01838 GtkWidget *hbox9;
01839 GtkWidget *vbox34;
01840 GtkWidget *checkbutton10;
01841 GtkWidget *image8;
01842 GtkWidget *titlestring_tag_menu = create_titlestring_tag_menu();
01843 GtkWidget * numbers_alignment, * numbers;
01844
01845 playlist_page_vbox = gtk_vbox_new (FALSE, 0);
01846 gtk_container_add (GTK_CONTAINER (category_notebook), playlist_page_vbox);
01847
01848 vbox5 = gtk_vbox_new (FALSE, 0);
01849 gtk_box_pack_start (GTK_BOX (playlist_page_vbox), vbox5, TRUE, TRUE, 0);
01850
01851 create_widgets(GTK_BOX(vbox5), playlist_page_widgets, G_N_ELEMENTS(playlist_page_widgets));
01852
01853 alignment55 = gtk_alignment_new (0.5, 0.5, 1, 1);
01854 gtk_box_pack_start (GTK_BOX (vbox5), alignment55, FALSE, FALSE, 0);
01855 gtk_alignment_set_padding ((GtkAlignment *) alignment55, 12, 3, 0, 0);
01856
01857 label60 = gtk_label_new (_("<b>Song Display</b>"));
01858 gtk_container_add (GTK_CONTAINER (alignment55), label60);
01859 gtk_label_set_use_markup (GTK_LABEL (label60), TRUE);
01860 gtk_misc_set_alignment (GTK_MISC (label60), 0, 0.5);
01861
01862 numbers_alignment = gtk_alignment_new (0, 0, 0, 0);
01863 gtk_alignment_set_padding ((GtkAlignment *) numbers_alignment, 0, 0, 12, 0);
01864 gtk_box_pack_start ((GtkBox *) vbox5, numbers_alignment, 0, 0, 3);
01865
01866 numbers = gtk_check_button_new_with_label (_("Show song numbers"));
01867 gtk_toggle_button_set_active ((GtkToggleButton *) numbers,
01868 cfg.show_numbers_in_pl);
01869 g_signal_connect ((GObject *) numbers, "toggled", (GCallback)
01870 show_numbers_cb, 0);
01871 gtk_container_add ((GtkContainer *) numbers_alignment, numbers);
01872
01873 alignment56 = gtk_alignment_new (0.5, 0.5, 1, 1);
01874 gtk_box_pack_start (GTK_BOX (vbox5), alignment56, FALSE, FALSE, 0);
01875 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment56), 0, 0, 12, 0);
01876
01877 table6 = gtk_table_new (2, 3, FALSE);
01878 gtk_container_add (GTK_CONTAINER (alignment56), table6);
01879 gtk_table_set_row_spacings (GTK_TABLE (table6), 4);
01880 gtk_table_set_col_spacings (GTK_TABLE (table6), 12);
01881
01882 titlestring_help_button = gtk_button_new ();
01883 gtk_table_attach (GTK_TABLE (table6), titlestring_help_button, 2, 3, 1, 2,
01884 (GtkAttachOptions) (0),
01885 (GtkAttachOptions) (0), 0, 0);
01886
01887 gtk_widget_set_can_focus (titlestring_help_button, FALSE);
01888 gtk_widget_set_tooltip_text (titlestring_help_button, _("Show information about titlestring format"));
01889 gtk_button_set_relief (GTK_BUTTON (titlestring_help_button), GTK_RELIEF_HALF);
01890 gtk_button_set_focus_on_click (GTK_BUTTON (titlestring_help_button), FALSE);
01891
01892 image1 = gtk_image_new_from_stock ("gtk-index", GTK_ICON_SIZE_BUTTON);
01893 gtk_container_add (GTK_CONTAINER (titlestring_help_button), image1);
01894
01895 titlestring_cbox = gtk_combo_box_new_text ();
01896 gtk_table_attach (GTK_TABLE (table6), titlestring_cbox, 1, 3, 0, 1,
01897 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
01898 (GtkAttachOptions) (0), 0, 0);
01899 gtk_combo_box_append_text (GTK_COMBO_BOX (titlestring_cbox), _("TITLE"));
01900 gtk_combo_box_append_text (GTK_COMBO_BOX (titlestring_cbox), _("ARTIST - TITLE"));
01901 gtk_combo_box_append_text (GTK_COMBO_BOX (titlestring_cbox), _("ARTIST - ALBUM - TITLE"));
01902 gtk_combo_box_append_text (GTK_COMBO_BOX (titlestring_cbox), _("ARTIST - ALBUM - TRACK. TITLE"));
01903 gtk_combo_box_append_text (GTK_COMBO_BOX (titlestring_cbox), _("ARTIST [ ALBUM ] - TRACK. TITLE"));
01904 gtk_combo_box_append_text (GTK_COMBO_BOX (titlestring_cbox), _("ALBUM - TITLE"));
01905 gtk_combo_box_append_text (GTK_COMBO_BOX (titlestring_cbox), _("Custom"));
01906
01907 titlestring_entry = gtk_entry_new ();
01908 gtk_table_attach (GTK_TABLE (table6), titlestring_entry, 1, 2, 1, 2,
01909 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
01910 (GtkAttachOptions) (0), 0, 0);
01911
01912 label62 = gtk_label_new (_("Custom string:"));
01913 gtk_table_attach (GTK_TABLE (table6), label62, 0, 1, 1, 2,
01914 (GtkAttachOptions) (0),
01915 (GtkAttachOptions) (0), 0, 0);
01916 gtk_label_set_justify (GTK_LABEL (label62), GTK_JUSTIFY_RIGHT);
01917 gtk_misc_set_alignment (GTK_MISC (label62), 1, 0.5);
01918
01919 label61 = gtk_label_new (_("Title format:"));
01920 gtk_table_attach (GTK_TABLE (table6), label61, 0, 1, 0, 1,
01921 (GtkAttachOptions) (0),
01922 (GtkAttachOptions) (0), 0, 0);
01923 gtk_label_set_justify (GTK_LABEL (label61), GTK_JUSTIFY_RIGHT);
01924 gtk_misc_set_alignment (GTK_MISC (label61), 1, 0.5);
01925
01926 alignment85 = gtk_alignment_new (0.5, 0.5, 1, 1);
01927 gtk_box_pack_start (GTK_BOX (vbox5), alignment85, FALSE, FALSE, 0);
01928 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment85), 12, 12, 0, 0);
01929
01930 label84 = gtk_label_new (_("<b>Popup Information</b>"));
01931 gtk_container_add (GTK_CONTAINER (alignment85), label84);
01932 gtk_label_set_use_markup (GTK_LABEL (label84), TRUE);
01933 gtk_misc_set_alignment (GTK_MISC (label84), 0, 0.5);
01934
01935 alignment86 = gtk_alignment_new (0.5, 0.5, 1, 1);
01936 gtk_box_pack_start (GTK_BOX (vbox5), alignment86, FALSE, FALSE, 0);
01937 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment86), 0, 0, 12, 0);
01938
01939 hbox9 = gtk_hbox_new (FALSE, 12);
01940 gtk_container_add (GTK_CONTAINER (alignment86), hbox9);
01941
01942 vbox34 = gtk_vbox_new (FALSE, 0);
01943 gtk_box_pack_start (GTK_BOX (hbox9), vbox34, TRUE, TRUE, 0);
01944
01945 checkbutton10 = gtk_check_button_new_with_mnemonic (_("Show popup information for playlist entries"));
01946 gtk_box_pack_start (GTK_BOX (vbox34), checkbutton10, TRUE, FALSE, 0);
01947 gtk_widget_set_tooltip_text (checkbutton10, _("Toggles popup information window for the pointed entry in the playlist. The window shows title of song, name of album, genre, year of publish, track number, track length, and artwork."));
01948
01949 filepopup_for_tuple_settings_button = gtk_button_new ();
01950 gtk_box_pack_start (GTK_BOX (hbox9), filepopup_for_tuple_settings_button, FALSE, FALSE, 0);
01951
01952 gtk_widget_set_can_focus (filepopup_for_tuple_settings_button, FALSE);
01953 gtk_widget_set_tooltip_text (filepopup_for_tuple_settings_button, _("Edit settings for popup information"));
01954 gtk_button_set_relief (GTK_BUTTON (filepopup_for_tuple_settings_button), GTK_RELIEF_HALF);
01955
01956 image8 = gtk_image_new_from_stock ("gtk-properties", GTK_ICON_SIZE_BUTTON);
01957 gtk_container_add (GTK_CONTAINER (filepopup_for_tuple_settings_button), image8);
01958
01959
01960
01961 g_signal_connect(G_OBJECT(checkbutton10), "toggled",
01962 G_CALLBACK(on_show_filepopup_for_tuple_toggled),
01963 NULL);
01964 g_signal_connect_after(G_OBJECT(checkbutton10), "realize",
01965 G_CALLBACK(on_show_filepopup_for_tuple_realize),
01966 NULL);
01967 g_signal_connect(G_OBJECT(filepopup_for_tuple_settings_button), "clicked",
01968 G_CALLBACK(on_filepopup_for_tuple_settings_clicked),
01969 NULL);
01970
01971 g_signal_connect(titlestring_cbox, "realize",
01972 G_CALLBACK(on_titlestring_cbox_realize),
01973 titlestring_entry);
01974 g_signal_connect(titlestring_cbox, "changed",
01975 G_CALLBACK(on_titlestring_cbox_changed),
01976 titlestring_entry);
01977
01978 g_signal_connect(titlestring_cbox, "changed",
01979 G_CALLBACK(on_titlestring_cbox_changed),
01980 titlestring_help_button);
01981 g_signal_connect(titlestring_help_button, "clicked",
01982 G_CALLBACK(on_titlestring_help_button_clicked),
01983 titlestring_tag_menu);
01984
01985 g_signal_connect(G_OBJECT(titlestring_entry), "changed",
01986 G_CALLBACK(on_titlestring_entry_changed),
01987 NULL);
01988 g_signal_connect_after(G_OBJECT(titlestring_entry), "realize",
01989 G_CALLBACK(on_titlestring_entry_realize),
01990 NULL);
01991
01992
01993
01994
01995 create_filepopup_settings();
01996 }
01997
01998
01999 static void
02000 create_audio_category(void)
02001 {
02002 GtkWidget *audio_page_vbox;
02003 GtkWidget *alignment74;
02004 GtkWidget *label77;
02005 GtkWidget *alignment73;
02006 GtkWidget *vbox33;
02007 GtkWidget *table11;
02008 GtkWidget *label79;
02009 GtkObject *output_plugin_bufsize_adj;
02010 GtkWidget *output_plugin_bufsize;
02011 GtkWidget *output_plugin_cbox;
02012 GtkWidget *label78;
02013 GtkWidget *alignment82;
02014 GtkWidget *output_plugin_button_box;
02015 GtkWidget *output_plugin_prefs;
02016 GtkWidget *alignment76;
02017 GtkWidget *hbox7;
02018 GtkWidget *image5;
02019 GtkWidget *label80;
02020 GtkWidget *output_plugin_info;
02021 GtkWidget *alignment77;
02022 GtkWidget *hbox8;
02023 GtkWidget *image6;
02024 GtkWidget *label81;
02025
02026 audio_page_vbox = gtk_vbox_new (FALSE, 0);
02027 gtk_container_add (GTK_CONTAINER (category_notebook), audio_page_vbox);
02028
02029 alignment74 = gtk_alignment_new (0.5, 0.5, 1, 1);
02030 gtk_box_pack_start (GTK_BOX (audio_page_vbox), alignment74, FALSE, FALSE, 0);
02031 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment74), 0, 12, 0, 0);
02032
02033 label77 = gtk_label_new (_("<b>Audio System</b>"));
02034 gtk_container_add (GTK_CONTAINER (alignment74), label77);
02035 gtk_label_set_use_markup (GTK_LABEL (label77), TRUE);
02036 gtk_misc_set_alignment (GTK_MISC (label77), 0, 0.5);
02037
02038 alignment73 = gtk_alignment_new (0.5, 0.5, 1, 1);
02039 gtk_box_pack_start (GTK_BOX (audio_page_vbox), alignment73, FALSE, FALSE, 0);
02040 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment73), 0, 6, 12, 0);
02041
02042 vbox33 = gtk_vbox_new (FALSE, 0);
02043 gtk_container_add (GTK_CONTAINER (alignment73), vbox33);
02044
02045 table11 = gtk_table_new (3, 2, FALSE);
02046 gtk_box_pack_start (GTK_BOX (vbox33), table11, FALSE, FALSE, 0);
02047 gtk_table_set_row_spacings (GTK_TABLE (table11), 6);
02048 gtk_table_set_col_spacings (GTK_TABLE (table11), 6);
02049
02050 label79 = gtk_label_new (_("Buffer size:"));
02051 gtk_table_attach (GTK_TABLE (table11), label79, 0, 1, 1, 2,
02052 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
02053 (GtkAttachOptions) (0), 0, 0);
02054 gtk_misc_set_alignment (GTK_MISC (label79), 1, 0.5);
02055
02056 output_plugin_bufsize_adj =
02057 gtk_adjustment_new (0, 100, 10000, 100, 1000, 0);
02058 output_plugin_bufsize = gtk_spin_button_new (GTK_ADJUSTMENT (output_plugin_bufsize_adj), 100, 0);
02059 gtk_table_attach (GTK_TABLE (table11), output_plugin_bufsize, 1, 2, 1, 2,
02060 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
02061 (GtkAttachOptions) (0), 0, 0);
02062
02063 output_plugin_cbox = gtk_combo_box_new_text ();
02064 gtk_table_attach (GTK_TABLE (table11), output_plugin_cbox, 1, 2, 0, 1,
02065 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
02066 (GtkAttachOptions) (0), 0, 0);
02067
02068 label78 = gtk_label_new (_("Current output plugin:"));
02069 gtk_table_attach (GTK_TABLE (table11), label78, 0, 1, 0, 1,
02070 (GtkAttachOptions) (0),
02071 (GtkAttachOptions) (0), 0, 0);
02072 gtk_misc_set_alignment (GTK_MISC (label78), 0, 0.5);
02073
02074 alignment82 = gtk_alignment_new (0.5, 0.5, 1, 1);
02075 gtk_box_pack_start (GTK_BOX (audio_page_vbox), alignment82, FALSE, FALSE, 0);
02076 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment82), 0, 0, 12, 0);
02077
02078 output_plugin_button_box = gtk_hbutton_box_new ();
02079 gtk_container_add (GTK_CONTAINER (alignment82), output_plugin_button_box);
02080 gtk_button_box_set_layout (GTK_BUTTON_BOX (output_plugin_button_box), GTK_BUTTONBOX_START);
02081 gtk_box_set_spacing (GTK_BOX (output_plugin_button_box), 8);
02082
02083 output_plugin_prefs = gtk_button_new ();
02084 gtk_container_add (GTK_CONTAINER (output_plugin_button_box), output_plugin_prefs);
02085 gtk_widget_set_sensitive (output_plugin_prefs, FALSE);
02086 gtk_widget_set_can_default(output_plugin_prefs, TRUE);
02087
02088 alignment76 = gtk_alignment_new (0.5, 0.5, 0, 0);
02089 gtk_container_add (GTK_CONTAINER (output_plugin_prefs), alignment76);
02090
02091 hbox7 = gtk_hbox_new (FALSE, 2);
02092 gtk_container_add (GTK_CONTAINER (alignment76), hbox7);
02093
02094 image5 = gtk_image_new_from_stock ("gtk-preferences", GTK_ICON_SIZE_BUTTON);
02095 gtk_box_pack_start (GTK_BOX (hbox7), image5, FALSE, FALSE, 0);
02096
02097 label80 = gtk_label_new_with_mnemonic (_("Output Plugin Preferences"));
02098 gtk_box_pack_start (GTK_BOX (hbox7), label80, FALSE, FALSE, 0);
02099
02100 output_plugin_info = gtk_button_new ();
02101 gtk_container_add (GTK_CONTAINER (output_plugin_button_box), output_plugin_info);
02102 gtk_widget_set_sensitive (output_plugin_info, FALSE);
02103 gtk_widget_set_can_default(output_plugin_info, TRUE);
02104
02105 alignment77 = gtk_alignment_new (0.5, 0.5, 0, 0);
02106 gtk_container_add (GTK_CONTAINER (output_plugin_info), alignment77);
02107
02108 hbox8 = gtk_hbox_new (FALSE, 2);
02109 gtk_container_add (GTK_CONTAINER (alignment77), hbox8);
02110
02111 image6 = gtk_image_new_from_stock ("gtk-about", GTK_ICON_SIZE_BUTTON);
02112 gtk_box_pack_start (GTK_BOX (hbox8), image6, FALSE, FALSE, 0);
02113
02114 label81 = gtk_label_new_with_mnemonic (_("Output Plugin Information"));
02115 gtk_box_pack_start (GTK_BOX (hbox8), label81, FALSE, FALSE, 0);
02116
02117 create_widgets(GTK_BOX(audio_page_vbox), audio_page_widgets, G_N_ELEMENTS(audio_page_widgets));
02118
02119 g_signal_connect(G_OBJECT(output_plugin_bufsize), "value_changed",
02120 G_CALLBACK(on_output_plugin_bufsize_value_changed),
02121 NULL);
02122 g_signal_connect_after(G_OBJECT(output_plugin_bufsize), "realize",
02123 G_CALLBACK(on_output_plugin_bufsize_realize),
02124 NULL);
02125 g_signal_connect_after(G_OBJECT(output_plugin_cbox), "realize",
02126 G_CALLBACK(on_output_plugin_cbox_realize),
02127 NULL);
02128
02129
02130
02131 g_signal_connect(G_OBJECT(output_plugin_cbox), "changed",
02132 G_CALLBACK(output_plugin_enable_prefs),
02133 output_plugin_prefs);
02134 g_signal_connect_swapped(G_OBJECT(output_plugin_prefs), "clicked",
02135 G_CALLBACK(output_plugin_open_prefs),
02136 output_plugin_cbox);
02137
02138 g_signal_connect(G_OBJECT(output_plugin_cbox), "changed",
02139 G_CALLBACK(output_plugin_enable_info),
02140 output_plugin_info);
02141 g_signal_connect_swapped(G_OBJECT(output_plugin_info), "clicked",
02142 G_CALLBACK(output_plugin_open_info),
02143 output_plugin_cbox);
02144
02145 }
02146
02147 static void
02148 create_connectivity_category(void)
02149 {
02150 GtkWidget *connectivity_page_vbox;
02151 GtkWidget *vbox29;
02152
02153 connectivity_page_vbox = gtk_vbox_new (FALSE, 0);
02154 gtk_container_add (GTK_CONTAINER (category_notebook), connectivity_page_vbox);
02155
02156 vbox29 = gtk_vbox_new (FALSE, 0);
02157 gtk_box_pack_start (GTK_BOX (connectivity_page_vbox), vbox29, TRUE, TRUE, 0);
02158
02159 create_widgets(GTK_BOX(vbox29), connectivity_page_widgets, G_N_ELEMENTS(connectivity_page_widgets));
02160 }
02161
02162 static void
02163 create_plugin_category(void)
02164 {
02165 GtkWidget *plugin_page_vbox;
02166 GtkWidget *plugin_notebook;
02167 GtkWidget *plugin_input_vbox;
02168 GtkWidget *alignment43;
02169 GtkWidget *input_plugin_list_label;
02170 GtkWidget *scrolledwindow3;
02171 GtkWidget *input_plugin_view;
02172 GtkWidget *input_plugin_button_box;
02173 GtkWidget *input_plugin_prefs;
02174 GtkWidget *input_plugin_info;
02175 GtkWidget *plugin_input_label;
02176 GtkWidget *plugin_general_vbox;
02177 GtkWidget *alignment45;
02178 GtkWidget *label11;
02179 GtkWidget *scrolledwindow5;
02180 GtkWidget *general_plugin_view;
02181 GtkWidget *general_plugin_button_box;
02182 GtkWidget *general_plugin_prefs;
02183 GtkWidget *general_plugin_info;
02184 GtkWidget *plugin_general_label;
02185 GtkWidget *vbox21;
02186 GtkWidget *alignment46;
02187 GtkWidget *label53;
02188 GtkWidget *scrolledwindow7;
02189 GtkWidget *vis_plugin_view;
02190 GtkWidget *hbuttonbox6;
02191 GtkWidget *vis_plugin_prefs;
02192 GtkWidget *vis_plugin_info;
02193 GtkWidget *vis_label;
02194 GtkWidget *vbox25;
02195 GtkWidget *alignment58;
02196 GtkWidget *label64;
02197 GtkWidget *scrolledwindow9;
02198 GtkWidget *effect_plugin_view;
02199 GtkWidget *hbuttonbox9;
02200 GtkWidget *effect_plugin_prefs;
02201 GtkWidget *effect_plugin_info;
02202 GtkWidget *effects_label;
02203
02204 plugin_page_vbox = gtk_vbox_new (FALSE, 0);
02205 gtk_container_add (GTK_CONTAINER (category_notebook), plugin_page_vbox);
02206
02207 plugin_notebook = gtk_notebook_new ();
02208 gtk_box_pack_start (GTK_BOX (plugin_page_vbox), plugin_notebook, TRUE, TRUE, 0);
02209 gtk_notebook_set_show_border (GTK_NOTEBOOK (plugin_notebook), FALSE);
02210
02211 plugin_input_vbox = gtk_vbox_new (FALSE, 0);
02212 gtk_container_add (GTK_CONTAINER (plugin_notebook), plugin_input_vbox);
02213 gtk_container_set_border_width (GTK_CONTAINER (plugin_input_vbox), 12);
02214
02215 alignment43 = gtk_alignment_new (0.5, 0.5, 1, 1);
02216 gtk_box_pack_start (GTK_BOX (plugin_input_vbox), alignment43, FALSE, FALSE, 4);
02217 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment43), 0, 6, 0, 0);
02218
02219 input_plugin_list_label = gtk_label_new_with_mnemonic (_("_Decoder list:"));
02220 gtk_container_add (GTK_CONTAINER (alignment43), input_plugin_list_label);
02221 gtk_label_set_use_markup (GTK_LABEL (input_plugin_list_label), TRUE);
02222 gtk_misc_set_alignment (GTK_MISC (input_plugin_list_label), 0, 0.5);
02223
02224 scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL);
02225 gtk_box_pack_start (GTK_BOX (plugin_input_vbox), scrolledwindow3, TRUE, TRUE, 0);
02226 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
02227 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow3), GTK_SHADOW_IN);
02228
02229 input_plugin_view = gtk_tree_view_new ();
02230 gtk_container_add (GTK_CONTAINER (scrolledwindow3), input_plugin_view);
02231 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (input_plugin_view), TRUE);
02232 gtk_tree_view_set_reorderable (GTK_TREE_VIEW (input_plugin_view), TRUE);
02233
02234 input_plugin_button_box = gtk_hbutton_box_new ();
02235 gtk_box_pack_start (GTK_BOX (plugin_input_vbox), input_plugin_button_box, FALSE, FALSE, 8);
02236 gtk_button_box_set_layout (GTK_BUTTON_BOX (input_plugin_button_box), GTK_BUTTONBOX_START);
02237 gtk_box_set_spacing (GTK_BOX (input_plugin_button_box), 8);
02238
02239 input_plugin_prefs = gtk_button_new_from_stock ("gtk-preferences");
02240 gtk_container_add (GTK_CONTAINER (input_plugin_button_box), input_plugin_prefs);
02241 gtk_widget_set_sensitive (input_plugin_prefs, FALSE);
02242 gtk_widget_set_can_default(input_plugin_prefs, TRUE);
02243
02244 input_plugin_info = gtk_button_new_from_stock ("gtk-dialog-info");
02245 gtk_container_add (GTK_CONTAINER (input_plugin_button_box), input_plugin_info);
02246 gtk_widget_set_sensitive (input_plugin_info, FALSE);
02247 gtk_widget_set_can_default(input_plugin_info, TRUE);
02248
02249 plugin_input_label = gtk_label_new (_("<span size=\"medium\"><b>Decoders</b></span>"));
02250 gtk_notebook_set_tab_label (GTK_NOTEBOOK (plugin_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (plugin_notebook), 0), plugin_input_label);
02251 gtk_label_set_use_markup (GTK_LABEL (plugin_input_label), TRUE);
02252 gtk_misc_set_alignment (GTK_MISC (plugin_input_label), 0, 0);
02253
02254 plugin_general_vbox = gtk_vbox_new (FALSE, 0);
02255 gtk_container_add (GTK_CONTAINER (plugin_notebook), plugin_general_vbox);
02256 gtk_container_set_border_width (GTK_CONTAINER (plugin_general_vbox), 12);
02257
02258 alignment45 = gtk_alignment_new (0.5, 0.5, 1, 1);
02259 gtk_box_pack_start (GTK_BOX (plugin_general_vbox), alignment45, FALSE, FALSE, 4);
02260 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment45), 0, 6, 0, 0);
02261
02262 label11 = gtk_label_new_with_mnemonic (_("_General plugin list:"));
02263 gtk_container_add (GTK_CONTAINER (alignment45), label11);
02264 gtk_label_set_use_markup (GTK_LABEL (label11), TRUE);
02265 gtk_misc_set_alignment (GTK_MISC (label11), 0, 0.5);
02266
02267 scrolledwindow5 = gtk_scrolled_window_new (NULL, NULL);
02268 gtk_box_pack_start (GTK_BOX (plugin_general_vbox), scrolledwindow5, TRUE, TRUE, 0);
02269 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
02270 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow5), GTK_SHADOW_IN);
02271
02272 general_plugin_view = gtk_tree_view_new ();
02273 gtk_container_add (GTK_CONTAINER (scrolledwindow5), general_plugin_view);
02274 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (general_plugin_view), TRUE);
02275 gtk_tree_view_set_reorderable (GTK_TREE_VIEW (general_plugin_view), TRUE);
02276
02277 general_plugin_button_box = gtk_hbutton_box_new ();
02278 gtk_box_pack_start (GTK_BOX (plugin_general_vbox), general_plugin_button_box, FALSE, FALSE, 8);
02279 gtk_button_box_set_layout (GTK_BUTTON_BOX (general_plugin_button_box), GTK_BUTTONBOX_START);
02280 gtk_box_set_spacing (GTK_BOX (general_plugin_button_box), 8);
02281
02282 general_plugin_prefs = gtk_button_new_from_stock ("gtk-preferences");
02283 gtk_container_add (GTK_CONTAINER (general_plugin_button_box), general_plugin_prefs);
02284 gtk_widget_set_sensitive (general_plugin_prefs, FALSE);
02285 gtk_widget_set_can_default(general_plugin_prefs, TRUE);
02286
02287 general_plugin_info = gtk_button_new_from_stock ("gtk-dialog-info");
02288 gtk_container_add (GTK_CONTAINER (general_plugin_button_box), general_plugin_info);
02289 gtk_widget_set_sensitive (general_plugin_info, FALSE);
02290 gtk_widget_set_can_default(general_plugin_info, TRUE);
02291
02292 plugin_general_label = gtk_label_new (_("<span size=\"medium\"><b>General</b></span>"));
02293 gtk_notebook_set_tab_label (GTK_NOTEBOOK (plugin_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (plugin_notebook), 1), plugin_general_label);
02294 gtk_label_set_use_markup (GTK_LABEL (plugin_general_label), TRUE);
02295
02296 vbox21 = gtk_vbox_new (FALSE, 0);
02297 gtk_container_add (GTK_CONTAINER (plugin_notebook), vbox21);
02298 gtk_container_set_border_width (GTK_CONTAINER (vbox21), 12);
02299
02300 alignment46 = gtk_alignment_new (0.5, 0.5, 1, 1);
02301 gtk_box_pack_start (GTK_BOX (vbox21), alignment46, FALSE, FALSE, 4);
02302 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment46), 0, 6, 0, 0);
02303
02304 label53 = gtk_label_new_with_mnemonic (_("_Visualization plugin list:"));
02305 gtk_container_add (GTK_CONTAINER (alignment46), label53);
02306 gtk_label_set_use_markup (GTK_LABEL (label53), TRUE);
02307 gtk_misc_set_alignment (GTK_MISC (label53), 0, 0.5);
02308
02309 scrolledwindow7 = gtk_scrolled_window_new (NULL, NULL);
02310 gtk_box_pack_start (GTK_BOX (vbox21), scrolledwindow7, TRUE, TRUE, 0);
02311 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
02312 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_SHADOW_IN);
02313
02314 vis_plugin_view = gtk_tree_view_new ();
02315 gtk_container_add (GTK_CONTAINER (scrolledwindow7), vis_plugin_view);
02316 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (vis_plugin_view), TRUE);
02317 gtk_tree_view_set_reorderable (GTK_TREE_VIEW (vis_plugin_view), TRUE);
02318
02319 hbuttonbox6 = gtk_hbutton_box_new ();
02320 gtk_box_pack_start (GTK_BOX (vbox21), hbuttonbox6, FALSE, FALSE, 8);
02321 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox6), GTK_BUTTONBOX_START);
02322 gtk_box_set_spacing (GTK_BOX (hbuttonbox6), 8);
02323
02324 vis_plugin_prefs = gtk_button_new_from_stock ("gtk-preferences");
02325 gtk_container_add (GTK_CONTAINER (hbuttonbox6), vis_plugin_prefs);
02326 gtk_widget_set_sensitive (vis_plugin_prefs, FALSE);
02327 gtk_widget_set_can_default(vis_plugin_prefs, TRUE);
02328
02329 vis_plugin_info = gtk_button_new_from_stock ("gtk-dialog-info");
02330 gtk_container_add (GTK_CONTAINER (hbuttonbox6), vis_plugin_info);
02331 gtk_widget_set_sensitive (vis_plugin_info, FALSE);
02332 gtk_widget_set_can_default(vis_plugin_info, TRUE);
02333
02334 vis_label = gtk_label_new (_("<b>Visualization</b>"));
02335 gtk_notebook_set_tab_label (GTK_NOTEBOOK (plugin_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (plugin_notebook), 2), vis_label);
02336 gtk_label_set_use_markup (GTK_LABEL (vis_label), TRUE);
02337
02338 vbox25 = gtk_vbox_new (FALSE, 0);
02339 gtk_container_add (GTK_CONTAINER (plugin_notebook), vbox25);
02340 gtk_container_set_border_width (GTK_CONTAINER (vbox25), 12);
02341
02342 alignment58 = gtk_alignment_new (0.5, 0.5, 1, 1);
02343 gtk_box_pack_start (GTK_BOX (vbox25), alignment58, FALSE, FALSE, 4);
02344 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment58), 0, 6, 0, 0);
02345
02346 label64 = gtk_label_new (_("Effect plugins:"));
02347 gtk_container_add (GTK_CONTAINER (alignment58), label64);
02348 gtk_misc_set_alignment (GTK_MISC (label64), 0, 0.5);
02349
02350 scrolledwindow9 = gtk_scrolled_window_new (NULL, NULL);
02351 gtk_box_pack_start (GTK_BOX (vbox25), scrolledwindow9, TRUE, TRUE, 0);
02352 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
02353 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_SHADOW_IN);
02354
02355 effect_plugin_view = gtk_tree_view_new ();
02356 gtk_container_add (GTK_CONTAINER (scrolledwindow9), effect_plugin_view);
02357 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (effect_plugin_view), TRUE);
02358 gtk_tree_view_set_reorderable (GTK_TREE_VIEW (effect_plugin_view), TRUE);
02359
02360 hbuttonbox9 = gtk_hbutton_box_new ();
02361 gtk_box_pack_start (GTK_BOX (vbox25), hbuttonbox9, FALSE, FALSE, 8);
02362 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox9), GTK_BUTTONBOX_START);
02363 gtk_box_set_spacing (GTK_BOX (hbuttonbox9), 8);
02364
02365 effect_plugin_prefs = gtk_button_new_from_stock ("gtk-preferences");
02366 gtk_container_add (GTK_CONTAINER (hbuttonbox9), effect_plugin_prefs);
02367 gtk_widget_set_sensitive (effect_plugin_prefs, FALSE);
02368 gtk_widget_set_can_default(effect_plugin_prefs, TRUE);
02369
02370 effect_plugin_info = gtk_button_new_from_stock ("gtk-dialog-info");
02371 gtk_container_add (GTK_CONTAINER (hbuttonbox9), effect_plugin_info);
02372 gtk_widget_set_sensitive (effect_plugin_info, FALSE);
02373 gtk_widget_set_can_default(effect_plugin_info, TRUE);
02374
02375 effects_label = gtk_label_new (_("<b>Effects</b>"));
02376 gtk_notebook_set_tab_label (GTK_NOTEBOOK (plugin_notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (plugin_notebook), 3), effects_label);
02377 gtk_label_set_use_markup (GTK_LABEL (effects_label), TRUE);
02378
02379
02380
02381 gtk_label_set_mnemonic_widget (GTK_LABEL (input_plugin_list_label), category_notebook);
02382 gtk_label_set_mnemonic_widget (GTK_LABEL (label11), category_notebook);
02383 gtk_label_set_mnemonic_widget (GTK_LABEL (label53), category_notebook);
02384 gtk_label_set_mnemonic_widget (GTK_LABEL (label64), category_notebook);
02385
02386
02387
02388 g_signal_connect_after(G_OBJECT(input_plugin_view), "realize",
02389 G_CALLBACK(on_input_plugin_view_realize),
02390 NULL);
02391 g_signal_connect_after(G_OBJECT(general_plugin_view), "realize",
02392 G_CALLBACK(on_general_plugin_view_realize),
02393 NULL);
02394 g_signal_connect_after(G_OBJECT(vis_plugin_view), "realize",
02395 G_CALLBACK(on_vis_plugin_view_realize),
02396 NULL);
02397 g_signal_connect_after(G_OBJECT(effect_plugin_view), "realize",
02398 G_CALLBACK(on_effect_plugin_view_realize),
02399 NULL);
02400
02401
02402
02403
02404 g_object_set_data(G_OBJECT(input_plugin_view), "plugin_type" , GINT_TO_POINTER(PLUGIN_VIEW_TYPE_INPUT));
02405 g_signal_connect(G_OBJECT(input_plugin_view), "row-activated",
02406 G_CALLBACK(plugin_treeview_open_prefs),
02407 NULL);
02408 g_signal_connect(G_OBJECT(input_plugin_view), "cursor-changed",
02409 G_CALLBACK(plugin_treeview_enable_prefs),
02410 input_plugin_prefs);
02411
02412 g_signal_connect_swapped(G_OBJECT(input_plugin_prefs), "clicked",
02413 G_CALLBACK(plugin_treeview_open_prefs),
02414 input_plugin_view);
02415
02416 g_signal_connect(G_OBJECT(input_plugin_view), "cursor-changed",
02417 G_CALLBACK(plugin_treeview_enable_info),
02418 input_plugin_info);
02419 g_signal_connect_swapped(G_OBJECT(input_plugin_info), "clicked",
02420 G_CALLBACK(plugin_treeview_open_info),
02421 input_plugin_view);
02422
02423
02424
02425
02426 g_object_set_data(G_OBJECT(general_plugin_view), "plugin_type" , GINT_TO_POINTER(PLUGIN_VIEW_TYPE_GENERAL));
02427 g_signal_connect(G_OBJECT(general_plugin_view), "row-activated",
02428 G_CALLBACK(plugin_treeview_open_prefs),
02429 NULL);
02430
02431 g_signal_connect(G_OBJECT(general_plugin_view), "cursor-changed",
02432 G_CALLBACK(plugin_treeview_enable_prefs),
02433 general_plugin_prefs);
02434
02435 g_signal_connect_swapped(G_OBJECT(general_plugin_prefs), "clicked",
02436 G_CALLBACK(plugin_treeview_open_prefs),
02437 general_plugin_view);
02438
02439 g_signal_connect(G_OBJECT(general_plugin_view), "cursor-changed",
02440 G_CALLBACK(plugin_treeview_enable_info),
02441 general_plugin_info);
02442 g_signal_connect_swapped(G_OBJECT(general_plugin_info), "clicked",
02443 G_CALLBACK(plugin_treeview_open_info),
02444 general_plugin_view);
02445
02446
02447
02448
02449 g_object_set_data(G_OBJECT(vis_plugin_view), "plugin_type" , GINT_TO_POINTER(PLUGIN_VIEW_TYPE_VIS));
02450 g_signal_connect(G_OBJECT(vis_plugin_view), "row-activated",
02451 G_CALLBACK(plugin_treeview_open_prefs),
02452 NULL);
02453 g_signal_connect_swapped(G_OBJECT(vis_plugin_prefs), "clicked",
02454 G_CALLBACK(plugin_treeview_open_prefs),
02455 vis_plugin_view);
02456 g_signal_connect(G_OBJECT(vis_plugin_view), "cursor-changed",
02457 G_CALLBACK(plugin_treeview_enable_prefs), vis_plugin_prefs);
02458
02459 g_signal_connect(G_OBJECT(vis_plugin_view), "cursor-changed",
02460 G_CALLBACK(plugin_treeview_enable_info), vis_plugin_info);
02461 g_signal_connect_swapped(G_OBJECT(vis_plugin_info), "clicked",
02462 G_CALLBACK(plugin_treeview_open_info),
02463 vis_plugin_view);
02464
02465
02466
02467
02468 g_object_set_data(G_OBJECT(effect_plugin_view), "plugin_type" , GINT_TO_POINTER(PLUGIN_VIEW_TYPE_EFFECT));
02469 g_signal_connect(G_OBJECT(effect_plugin_view), "row-activated",
02470 G_CALLBACK(plugin_treeview_open_prefs),
02471 NULL);
02472 g_signal_connect_swapped(G_OBJECT(effect_plugin_prefs), "clicked",
02473 G_CALLBACK(plugin_treeview_open_prefs),
02474 effect_plugin_view);
02475 g_signal_connect(G_OBJECT(effect_plugin_view), "cursor-changed",
02476 G_CALLBACK(plugin_treeview_enable_prefs), effect_plugin_prefs);
02477
02478 g_signal_connect(G_OBJECT(effect_plugin_view), "cursor-changed",
02479 G_CALLBACK(plugin_treeview_enable_info), effect_plugin_info);
02480 g_signal_connect_swapped(G_OBJECT(effect_plugin_info), "clicked",
02481 G_CALLBACK(plugin_treeview_open_info),
02482 effect_plugin_view);
02483
02484 }
02485
02486 static void
02487 destroy_plugin_page(GList *list)
02488 {
02489 GList *iter;
02490
02491 MOWGLI_ITER_FOREACH(iter, list)
02492 {
02493 Plugin *plugin = PLUGIN(iter->data);
02494 if (plugin->settings && plugin->settings->data) {
02495 plugin->settings->data = NULL;
02496 if (plugin->settings->apply)
02497 plugin->settings->apply();
02498 if (plugin->settings->cleanup)
02499 plugin->settings->cleanup();
02500 }
02501 }
02502 }
02503
02504 static void
02505 destroy_plugin_pages(void)
02506 {
02507 destroy_plugin_page(plugin_get_list(PLUGIN_TYPE_INPUT));
02508 destroy_plugin_page(plugin_get_list(PLUGIN_TYPE_GENERAL));
02509 destroy_plugin_page(plugin_get_list(PLUGIN_TYPE_VIS));
02510 destroy_plugin_page(plugin_get_list(PLUGIN_TYPE_EFFECT));
02511 }
02512
02513 static gboolean
02514 prefswin_destroy(GtkWidget *window, GdkEvent *event, gpointer data)
02515 {
02516 destroy_plugin_pages();
02517 prefswin = NULL;
02518 category_notebook = NULL;
02519 gtk_widget_destroy(filepopup_settings);
02520 filepopup_settings = NULL;
02521 gtk_widget_destroy(window);
02522 return TRUE;
02523 }
02524
02525 static void
02526 create_plugin_page(GList *list)
02527 {
02528 GList *iter;
02529
02530 MOWGLI_ITER_FOREACH(iter, list)
02531 {
02532 Plugin *plugin = PLUGIN(iter->data);
02533 if (plugin->settings && plugin->settings->type == PREFERENCES_PAGE) {
02534 create_plugin_preferences_page(plugin->settings);
02535 }
02536 }
02537 }
02538
02539 static void
02540 create_plugin_pages(void)
02541 {
02542 create_plugin_page(plugin_get_list(PLUGIN_TYPE_INPUT));
02543 create_plugin_page(plugin_get_list(PLUGIN_TYPE_GENERAL));
02544 create_plugin_page(plugin_get_list(PLUGIN_TYPE_VIS));
02545 create_plugin_page(plugin_get_list(PLUGIN_TYPE_EFFECT));
02546 }
02547
02548
02549 void * * create_prefs_window (void)
02550 {
02551 gchar *aud_version_string;
02552
02553 GtkWidget *vbox;
02554 GtkWidget *hbox1;
02555 GtkWidget *scrolledwindow6;
02556 GtkWidget *hseparator1;
02557 GtkWidget *hbox4;
02558 GtkWidget *audversionlabel;
02559 GtkWidget *prefswin_button_box;
02560 GtkWidget *hbox11;
02561 GtkWidget *image10;
02562 GtkWidget *close;
02563 GtkAccelGroup *accel_group;
02564
02565 accel_group = gtk_accel_group_new ();
02566
02567 prefswin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
02568 gtk_window_set_type_hint (GTK_WINDOW (prefswin), GDK_WINDOW_TYPE_HINT_DIALOG);
02569 gtk_container_set_border_width (GTK_CONTAINER (prefswin), 12);
02570 gtk_window_set_title (GTK_WINDOW (prefswin), _("Audacious Preferences"));
02571 gtk_window_set_position (GTK_WINDOW (prefswin), GTK_WIN_POS_CENTER);
02572 gtk_window_set_default_size (GTK_WINDOW (prefswin), 680, 400);
02573
02574 vbox = gtk_vbox_new (FALSE, 0);
02575 gtk_container_add (GTK_CONTAINER (prefswin), vbox);
02576
02577 hbox1 = gtk_hbox_new (FALSE, 8);
02578 gtk_box_pack_start (GTK_BOX (vbox), hbox1, TRUE, TRUE, 0);
02579
02580 scrolledwindow6 = gtk_scrolled_window_new (NULL, NULL);
02581 gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow6, TRUE, TRUE, 0);
02582 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow6), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
02583 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow6), GTK_SHADOW_IN);
02584
02585 category_treeview = gtk_tree_view_new ();
02586 gtk_container_add (GTK_CONTAINER (scrolledwindow6), category_treeview);
02587 gtk_widget_set_size_request (category_treeview, 172, -1);
02588 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (category_treeview), FALSE);
02589
02590 category_notebook = gtk_notebook_new ();
02591 gtk_box_pack_start (GTK_BOX (hbox1), category_notebook, TRUE, TRUE, 0);
02592
02593 gtk_widget_set_can_focus (category_notebook, FALSE);
02594 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (category_notebook), FALSE);
02595 gtk_notebook_set_show_border (GTK_NOTEBOOK (category_notebook), FALSE);
02596 gtk_notebook_set_scrollable (GTK_NOTEBOOK (category_notebook), TRUE);
02597
02598
02599
02600 create_audio_category();
02601 create_replay_gain_category();
02602 create_connectivity_category();
02603 create_playback_category();
02604 create_playlist_category();
02605 create_plugin_category();
02606 create_plugin_pages();
02607
02608 hseparator1 = gtk_hseparator_new ();
02609 gtk_box_pack_start (GTK_BOX (vbox), hseparator1, FALSE, FALSE, 6);
02610
02611 hbox4 = gtk_hbox_new (FALSE, 0);
02612 gtk_box_pack_start (GTK_BOX (vbox), hbox4, FALSE, FALSE, 0);
02613
02614 audversionlabel = gtk_label_new ("");
02615 gtk_box_pack_start (GTK_BOX (hbox4), audversionlabel, FALSE, FALSE, 0);
02616 gtk_label_set_use_markup (GTK_LABEL (audversionlabel), TRUE);
02617
02618 prefswin_button_box = gtk_hbutton_box_new ();
02619 gtk_box_pack_start (GTK_BOX (hbox4), prefswin_button_box, TRUE, TRUE, 0);
02620 gtk_button_box_set_layout (GTK_BUTTON_BOX (prefswin_button_box), GTK_BUTTONBOX_END);
02621 gtk_box_set_spacing (GTK_BOX (prefswin_button_box), 6);
02622
02623 hbox11 = gtk_hbox_new (FALSE, 2);
02624
02625 image10 = gtk_image_new_from_stock ("gtk-refresh", GTK_ICON_SIZE_BUTTON);
02626 gtk_box_pack_start (GTK_BOX (hbox11), image10, FALSE, FALSE, 0);
02627
02628 close = gtk_button_new_from_stock ("gtk-close");
02629 gtk_container_add (GTK_CONTAINER (prefswin_button_box), close);
02630 gtk_widget_set_can_default(close, TRUE);
02631 gtk_widget_add_accelerator (close, "clicked", accel_group,
02632 GDK_Escape, (GdkModifierType) 0,
02633 GTK_ACCEL_VISIBLE);
02634
02635
02636 gtk_window_add_accel_group (GTK_WINDOW (prefswin), accel_group);
02637
02638
02639 g_signal_connect(G_OBJECT(prefswin), "delete_event",
02640 G_CALLBACK(prefswin_destroy),
02641 NULL);
02642 g_signal_connect_swapped(G_OBJECT(close), "clicked",
02643 G_CALLBACK(prefswin_destroy),
02644 GTK_OBJECT (prefswin));
02645
02646
02647 on_category_treeview_realize ((GtkTreeView *) category_treeview,
02648 (GtkNotebook *) category_notebook);
02649
02650
02651
02652 aud_version_string = g_strdup_printf
02653 ("<span size='small'>%s (%s)</span>", "Audacious " PACKAGE_VERSION,
02654 BUILDSTAMP);
02655
02656 gtk_label_set_markup( GTK_LABEL(audversionlabel) , aud_version_string );
02657 g_free(aud_version_string);
02658 gtk_widget_show_all(vbox);
02659
02660 return & prefswin;
02661 }
02662
02663 void
02664 destroy_prefs_window(void)
02665 {
02666 prefswin_destroy(prefswin, NULL, NULL);
02667 }
02668
02669 void
02670 create_plugin_preferences_page(PluginPreferences *settings)
02671 {
02672 g_return_if_fail(settings->type == PREFERENCES_PAGE);
02673
02674 if (settings->data != NULL)
02675 return;
02676
02677 if (settings->init)
02678 settings->init();
02679
02680 GtkWidget *vbox;
02681 vbox = gtk_vbox_new(FALSE, 5);
02682
02683 create_widgets(GTK_BOX(vbox), settings->prefs, settings->n_prefs);
02684 gtk_widget_show_all(vbox);
02685 prefswin_page_new(vbox, settings->title, settings->imgurl);
02686
02687 settings->data = (gpointer) vbox;
02688 }
02689
02690 void
02691 destroy_plugin_preferences_page(PluginPreferences *settings)
02692 {
02693 if (settings->data) {
02694 if (settings->apply)
02695 settings->apply();
02696
02697 prefswin_page_destroy(GTK_WIDGET(settings->data));
02698 settings->data = NULL;
02699
02700 if (settings->cleanup)
02701 settings->cleanup();
02702 }
02703 }
02704
02705 void
02706 show_prefs_window(void)
02707 {
02708 gtk_window_present(GTK_WINDOW(prefswin));
02709 }
02710
02711 void
02712 hide_prefs_window(void)
02713 {
02714 g_return_if_fail(prefswin);
02715 gtk_widget_hide(GTK_WIDGET(prefswin));
02716 }
02717
02718 static void prefswin_page_queue_new (GtkWidget * container, const gchar * name,
02719 const gchar * imgurl)
02720 {
02721 CategoryQueueEntry *ent = g_new0(CategoryQueueEntry, 1);
02722
02723 ent->container = container;
02724 ent->pg_name = name;
02725 ent->img_url = imgurl;
02726
02727 if (category_queue)
02728 ent->next = category_queue;
02729
02730 category_queue = ent;
02731 }
02732
02733 static void
02734 prefswin_page_queue_destroy(CategoryQueueEntry *ent)
02735 {
02736 category_queue = ent->next;
02737 g_free(ent);
02738 }
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753 gint prefswin_page_new (void * container, const gchar * name, const gchar *
02754 imgurl)
02755 {
02756 GtkTreeModel *model;
02757 GtkTreeIter iter;
02758 GdkPixbuf *img = NULL;
02759 GtkTreeView *treeview = GTK_TREE_VIEW(category_treeview);
02760 gint id;
02761
02762 if (treeview == NULL || category_notebook == NULL)
02763 {
02764 prefswin_page_queue_new(container, name, imgurl);
02765 return -1;
02766 }
02767
02768 model = gtk_tree_view_get_model(treeview);
02769
02770 if (model == NULL)
02771 {
02772 prefswin_page_queue_new(container, name, imgurl);
02773 return -1;
02774 }
02775
02776
02777 gtk_widget_show(container);
02778 id = gtk_notebook_append_page(GTK_NOTEBOOK(category_notebook), container, NULL);
02779
02780 if (id == -1)
02781 return -1;
02782
02783 if (imgurl != NULL)
02784 img = gdk_pixbuf_new_from_file(imgurl, NULL);
02785
02786 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
02787 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
02788 CATEGORY_VIEW_COL_ICON, img,
02789 CATEGORY_VIEW_COL_NAME,
02790 name, CATEGORY_VIEW_COL_ID, id, -1);
02791
02792 if (img != NULL)
02793 g_object_unref(img);
02794
02795 return id;
02796 }
02797
02798 void
02799 prefswin_page_destroy(GtkWidget *container)
02800 {
02801 GtkTreeModel *model;
02802 GtkTreeIter iter;
02803 GtkTreeView *treeview = GTK_TREE_VIEW(category_treeview);
02804 gboolean ret;
02805 gint id;
02806 gint index = -1;
02807
02808 if (category_notebook == NULL || treeview == NULL || container == NULL)
02809 return;
02810
02811 id = gtk_notebook_page_num(GTK_NOTEBOOK(category_notebook), container);
02812
02813 if (id == -1)
02814 return;
02815
02816 gtk_notebook_remove_page(GTK_NOTEBOOK(category_notebook), id);
02817
02818 model = gtk_tree_view_get_model(treeview);
02819
02820 if (model == NULL)
02821 return;
02822
02823 ret = gtk_tree_model_get_iter_first(model, &iter);
02824
02825 while (ret == TRUE)
02826 {
02827 gtk_tree_model_get(model, &iter, CATEGORY_VIEW_COL_ID, &index, -1);
02828
02829 if (index == id)
02830 {
02831 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
02832 ret = gtk_tree_model_get_iter_first(model, &iter);
02833 continue;
02834 }
02835
02836 if (index > id)
02837 {
02838 index--;
02839 gtk_list_store_set(GTK_LIST_STORE(model), &iter, CATEGORY_VIEW_COL_ID, index, -1);
02840 }
02841
02842 ret = gtk_tree_model_iter_next(model, &iter);
02843 }
02844 }
02845
02846 static void sw_volume_toggled (void)
02847 {
02848 gint vol[2];
02849
02850 if (cfg.software_volume_control)
02851 {
02852 vol[0] = cfg.sw_volume_left;
02853 vol[1] = cfg.sw_volume_right;
02854 }
02855 else
02856 input_get_volume (& vol[0], & vol[1]);
02857
02858 hook_call ("volume set", vol);
02859 }