Audacious
$Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* Audacious - Cross-platform multimedia player 00002 * Copyright (C) 2005-2007 Audacious development team. 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; under version 3 of the License. 00007 * 00008 * This program is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 * GNU General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * along with this program. If not, see <http://www.gnu.org/licenses>. 00015 * 00016 * The Audacious team does not consider modular code linking to 00017 * Audacious or using our public API to be a derived work. 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 /* GtkWidget * */ 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 /* filepopup settings widgets */ 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 /* prefswin widgets */ 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 /* get toggled iter */ 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 /* clean up */ 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 /* insert separator as needed */ 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 /* mark the treeview widget as available to third party plugins */ 00940 category_treeview = GTK_WIDGET(treeview); 00941 00942 /* prefswin_page_queue_destroy already pops the queue forward for us. */ 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 /* void create_widgets_with_domain (GtkBox * box, PreferencesWidget * widgets, 01554 gint amt, const gchar * domain) */ 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) { /* perhaps this logic can be better */ 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: /* custom widget. --nenolod */ 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 /* shouldn't ever happen - expect things to break */ 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 /* Create window for filepopup settings */ 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 /* plugin->output page */ 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 /* plugin->input page */ 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 /* plugin->general page */ 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 /* plugin->vis page */ 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 /* plugin->effects page */ 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 /* GtkWidget * * create_prefs_window (void) */ 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 /* connect signals */ 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 /* create category view */ 02647 on_category_treeview_realize ((GtkTreeView *) category_treeview, 02648 (GtkNotebook *) category_notebook); 02649 02650 /* audacious version label */ 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)); /* show or raise prefs window */ 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 * Public APIs for adding new pages to the prefs window. 02742 * 02743 * Basically, the concept here is that third party components can register themselves in the root 02744 * preferences window. 02745 * 02746 * From a usability standpoint this makes the application look more "united", instead of cluttered 02747 * and malorganised. Hopefully this option will be used further in the future. 02748 * 02749 * - nenolod 02750 */ 02751 /* gint prefswin_page_new (GtkWidget * container, const gchar * name, 02752 const gchar * imgurl) */ 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 /* Make sure the widgets are visible. */ 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 }