summaryrefslogtreecommitdiff
path: root/src/libaudgui
diff options
context:
space:
mode:
Diffstat (limited to 'src/libaudgui')
-rw-r--r--src/libaudgui/Makefile4
-rw-r--r--src/libaudgui/eq-preset.cc7
-rw-r--r--src/libaudgui/file-opener.cc1
-rw-r--r--src/libaudgui/infopopup.cc2
-rw-r--r--src/libaudgui/infowin.cc51
-rw-r--r--src/libaudgui/init.cc1
-rw-r--r--src/libaudgui/internal.h3
-rw-r--r--src/libaudgui/jump-to-track-cache.cc2
-rw-r--r--src/libaudgui/jump-to-track.cc2
-rw-r--r--src/libaudgui/libaudgui-gtk.h4
-rw-r--r--src/libaudgui/list.cc42
-rw-r--r--src/libaudgui/menu.cc2
-rw-r--r--src/libaudgui/playlists.cc3
-rw-r--r--src/libaudgui/prefs-widget.cc76
-rw-r--r--src/libaudgui/prefs-window.cc39
-rw-r--r--src/libaudgui/preset-browser.cc2
-rw-r--r--src/libaudgui/queue-manager.cc2
-rw-r--r--src/libaudgui/status.cc11
-rw-r--r--src/libaudgui/urilist.cc37
-rw-r--r--src/libaudgui/util.cc80
20 files changed, 260 insertions, 111 deletions
diff --git a/src/libaudgui/Makefile b/src/libaudgui/Makefile
index 55ba07f..dde93e1 100644
--- a/src/libaudgui/Makefile
+++ b/src/libaudgui/Makefile
@@ -1,6 +1,6 @@
SHARED_LIB = ${LIB_PREFIX}audgui${LIB_SUFFIX}
-LIB_MAJOR = 3
-LIB_MINOR = 1
+LIB_MAJOR = 4
+LIB_MINOR = 0
SRCS = about.cc \
confirm.cc \
diff --git a/src/libaudgui/eq-preset.cc b/src/libaudgui/eq-preset.cc
index 2aa37b0..a2f1c9d 100644
--- a/src/libaudgui/eq-preset.cc
+++ b/src/libaudgui/eq-preset.cc
@@ -103,14 +103,13 @@ static void populate_list ()
static void save_list ()
{
- auto sort_cb = [] (const EqualizerPreset & a, const EqualizerPreset & b, void *)
- { return strcmp (a.name, b.name); };
-
Index<EqualizerPreset> presets;
for (const PresetItem & item : preset_list)
presets.append (item.preset);
- presets.sort (sort_cb, nullptr);
+ presets.sort ([] (const EqualizerPreset & a, const EqualizerPreset & b)
+ { return strcmp (a.name, b.name); });
+
aud_eq_write_presets (presets, "eq.preset");
}
diff --git a/src/libaudgui/file-opener.cc b/src/libaudgui/file-opener.cc
index a51abb8..efe339c 100644
--- a/src/libaudgui/file-opener.cc
+++ b/src/libaudgui/file-opener.cc
@@ -104,6 +104,7 @@ static GtkWidget * create_filebrowser (gboolean open)
gtk_container_add ((GtkContainer *) window, vbox);
GtkWidget * chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN);
+ gtk_file_chooser_set_local_only ((GtkFileChooser *) chooser, false);
gtk_file_chooser_set_select_multiple ((GtkFileChooser *) chooser, true);
String path = aud_get_str ("audgui", "filesel_path");
diff --git a/src/libaudgui/infopopup.cc b/src/libaudgui/infopopup.cc
index a117b2b..bc2edfd 100644
--- a/src/libaudgui/infopopup.cc
+++ b/src/libaudgui/infopopup.cc
@@ -318,7 +318,7 @@ EXPORT void audgui_infopopup_show (int playlist, int entry)
String filename = aud_playlist_entry_get_filename (playlist, entry);
Tuple tuple = aud_playlist_entry_get_tuple (playlist, entry);
- if (filename && tuple)
+ if (filename && tuple.valid ())
infopopup_show (filename, tuple);
}
diff --git a/src/libaudgui/infowin.cc b/src/libaudgui/infowin.cc
index 353c9c3..5002dfc 100644
--- a/src/libaudgui/infowin.cc
+++ b/src/libaudgui/infowin.cc
@@ -72,6 +72,7 @@ static struct {
static GtkWidget * infowin;
static int current_playlist_id, current_entry;
static String current_file;
+static Tuple current_tuple;
static PluginHandle * current_decoder = nullptr;
static bool can_write = false;
static QueuedFunc ministatus_timer;
@@ -200,20 +201,17 @@ static void ministatus_display_message (const char * text)
static void infowin_update_tuple ()
{
- Tuple tuple;
- tuple.set_filename (current_file);
-
- set_field_str_from_entry (tuple, Tuple::Title, widgets.title);
- set_field_str_from_entry (tuple, Tuple::Artist, widgets.artist);
- set_field_str_from_entry (tuple, Tuple::Album, widgets.album);
- set_field_str_from_entry (tuple, Tuple::AlbumArtist, widgets.album_artist);
- set_field_str_from_entry (tuple, Tuple::Comment, widgets.comment);
- set_field_str_from_entry (tuple, Tuple::Genre, gtk_bin_get_child ((GtkBin *)
- widgets.genre));
- set_field_int_from_entry (tuple, Tuple::Year, widgets.year);
- set_field_int_from_entry (tuple, Tuple::Track, widgets.track);
-
- if (aud_file_write_tuple (current_file, current_decoder, tuple))
+ set_field_str_from_entry (current_tuple, Tuple::Title, widgets.title);
+ set_field_str_from_entry (current_tuple, Tuple::Artist, widgets.artist);
+ set_field_str_from_entry (current_tuple, Tuple::Album, widgets.album);
+ set_field_str_from_entry (current_tuple, Tuple::AlbumArtist, widgets.album_artist);
+ set_field_str_from_entry (current_tuple, Tuple::Comment, widgets.comment);
+ set_field_str_from_entry (current_tuple, Tuple::Genre,
+ gtk_bin_get_child ((GtkBin *) widgets.genre));
+ set_field_int_from_entry (current_tuple, Tuple::Year, widgets.year);
+ set_field_int_from_entry (current_tuple, Tuple::Track, widgets.track);
+
+ if (aud_file_write_tuple (current_file, current_decoder, current_tuple))
{
ministatus_display_message (_("Save successful"));
gtk_widget_set_sensitive (widgets.apply, false);
@@ -279,6 +277,7 @@ static void infowin_destroyed ()
infowin = nullptr;
current_file = String ();
+ current_tuple = Tuple ();
current_decoder = nullptr;
}
@@ -408,7 +407,7 @@ static void create_infowin ()
hook_associate ("art ready", (HookFunction) infowin_display_image, nullptr);
}
-static void infowin_show (int list, int entry, const char * filename,
+static void infowin_show (int list, int entry, const String & filename,
const Tuple & tuple, PluginHandle * decoder, bool writable)
{
if (! infowin)
@@ -416,7 +415,8 @@ static void infowin_show (int list, int entry, const char * filename,
current_playlist_id = aud_playlist_get_unique_id (list);
current_entry = entry;
- current_file = String (filename);
+ current_file = filename;
+ current_tuple = tuple.ref ();
current_decoder = decoder;
can_write = writable;
@@ -469,17 +469,20 @@ EXPORT void audgui_infowin_show (int playlist, int entry)
String error;
PluginHandle * decoder = aud_playlist_entry_get_decoder (playlist, entry,
Playlist::Wait, & error);
+ Tuple tuple = decoder ? aud_playlist_entry_get_tuple (playlist, entry,
+ Playlist::Wait, & error) : Tuple ();
- if (decoder && ! aud_custom_infowin (filename, decoder))
+ if (decoder && tuple.valid () && ! aud_custom_infowin (filename, decoder))
{
- Tuple tuple = aud_playlist_entry_get_tuple (playlist, entry, Playlist::Wait, & error);
- if (tuple)
- {
- tuple.delete_fallbacks ();
- infowin_show (playlist, entry, filename, tuple, decoder,
- aud_file_can_write_tuple (filename, decoder));
- }
+ /* cuesheet entries cannot be updated */
+ bool can_write = aud_file_can_write_tuple (filename, decoder) &&
+ ! tuple.is_set (Tuple::StartTime);
+
+ tuple.delete_fallbacks ();
+ infowin_show (playlist, entry, filename, tuple, decoder, can_write);
}
+ else
+ audgui_infowin_hide ();
if (error)
aud_ui_show_error (str_printf (_("Error opening %s:\n%s"),
diff --git a/src/libaudgui/init.cc b/src/libaudgui/init.cc
index d560bc3..ede7414 100644
--- a/src/libaudgui/init.cc
+++ b/src/libaudgui/init.cc
@@ -170,5 +170,4 @@ EXPORT void audgui_cleanup ()
plugin_menu_cleanup ();
plugin_prefs_cleanup ();
- urilist_cleanup ();
}
diff --git a/src/libaudgui/internal.h b/src/libaudgui/internal.h
index d54204d..b43c97c 100644
--- a/src/libaudgui/internal.h
+++ b/src/libaudgui/internal.h
@@ -61,7 +61,4 @@ GtkWidget * plugin_view_new (PluginType type);
void status_init ();
void status_cleanup ();
-/* urilist.c */
-void urilist_cleanup ();
-
#endif /* AUDGUI_INTERNAL_H */
diff --git a/src/libaudgui/jump-to-track-cache.cc b/src/libaudgui/jump-to-track-cache.cc
index db07995..7dcf242 100644
--- a/src/libaudgui/jump-to-track-cache.cc
+++ b/src/libaudgui/jump-to-track-cache.cc
@@ -132,7 +132,7 @@ void JumpToTrackCache::init ()
item.entry = entry;
item.path = String (uri_to_display (aud_playlist_entry_get_filename (playlist, entry)));
- Tuple tuple = aud_playlist_entry_get_tuple (playlist, entry, Playlist::Guess);
+ Tuple tuple = aud_playlist_entry_get_tuple (playlist, entry, Playlist::NoWait);
item.title = tuple.get_str (Tuple::Title);
item.artist = tuple.get_str (Tuple::Artist);
item.album = tuple.get_str (Tuple::Album);
diff --git a/src/libaudgui/jump-to-track.cc b/src/libaudgui/jump-to-track.cc
index b903912..a681163 100644
--- a/src/libaudgui/jump-to-track.cc
+++ b/src/libaudgui/jump-to-track.cc
@@ -220,7 +220,7 @@ static void list_get_value (void * user, int row, int column, GValue * value)
g_value_set_int (value, 1 + entry);
break;
case 1:
- Tuple tuple = aud_playlist_entry_get_tuple (playlist, entry, Playlist::Guess);
+ Tuple tuple = aud_playlist_entry_get_tuple (playlist, entry, Playlist::NoWait);
g_value_set_string (value, tuple.get_str (Tuple::FormattedTitle));
break;
}
diff --git a/src/libaudgui/libaudgui-gtk.h b/src/libaudgui/libaudgui-gtk.h
index fc144a5..8bd8c08 100644
--- a/src/libaudgui/libaudgui-gtk.h
+++ b/src/libaudgui/libaudgui-gtk.h
@@ -63,6 +63,10 @@ void audgui_simple_message (GtkWidget * * widget, GtkMessageType type,
GtkWidget * audgui_button_new (const char * text, const char * icon,
AudguiCallback callback, void * data);
+GtkWidget * audgui_file_entry_new (GtkFileChooserAction action, const char * title);
+String audgui_file_entry_get_uri (GtkWidget * entry);
+void audgui_file_entry_set_uri (GtkWidget * entry, const char * uri);
+
GtkWidget * audgui_dialog_new (GtkMessageType type, const char * title,
const char * text, GtkWidget * button1, GtkWidget * button2);
void audgui_dialog_add_widget (GtkWidget * dialog, GtkWidget * widget);
diff --git a/src/libaudgui/list.cc b/src/libaudgui/list.cc
index a0b6ce6..906922b 100644
--- a/src/libaudgui/list.cc
+++ b/src/libaudgui/list.cc
@@ -343,6 +343,10 @@ static void drag_begin (GtkWidget * widget, GdkDragContext * context,
g_signal_stop_emission_by_name (widget, "drag-begin");
model->dragging = true;
+
+ /* If button_press_cb preserved a multiple selection, tell button_release_cb
+ * not to clear it. */
+ model->frozen = false;
}
static void drag_end (GtkWidget * widget, GdkDragContext * context,
@@ -426,14 +430,10 @@ static gboolean drag_motion (GtkWidget * widget, GdkDragContext * context,
{
g_signal_stop_emission_by_name (widget, "drag-motion");
- /* If button_press_cb preserved a multiple selection, tell button_release_cb
- * not to clear it. */
- model->frozen = false;
-
- if (model->dragging && MODEL_HAS_CB (model, shift_rows)) /* dragging within same list */
- gdk_drag_status (context, GDK_ACTION_MOVE, time);
- else if (MODEL_HAS_CB (model, data_type)) /* cross-widget dragging */
- gdk_drag_status (context, GDK_ACTION_COPY, time);
+ if (model->dragging && MODEL_HAS_CB (model, shift_rows))
+ gdk_drag_status (context, GDK_ACTION_MOVE, time); /* dragging within same list */
+ else if (MODEL_HAS_CB (model, data_type) && MODEL_HAS_CB (model, receive_data))
+ gdk_drag_status (context, GDK_ACTION_COPY, time); /* cross-widget dragging */
else
return false;
@@ -489,15 +489,17 @@ static gboolean drag_drop (GtkWidget * widget, GdkDragContext * context, int x,
gboolean success = true;
int row = audgui_list_row_at_point_rounded (widget, x, y);
- if (model->dragging && MODEL_HAS_CB (model, shift_rows)) /* dragging within same list */
+ if (model->dragging && MODEL_HAS_CB (model, shift_rows))
{
+ /* dragging within same list */
if (model->clicked_row >= 0 && model->clicked_row < model->rows)
model->cbs->shift_rows (model->user, model->clicked_row, row);
else
success = false;
}
- else if (MODEL_HAS_CB (model, data_type)) /* cross-widget dragging */
+ else if (MODEL_HAS_CB (model, data_type) && MODEL_HAS_CB (model, receive_data))
{
+ /* cross-widget dragging */
model->receive_row = row;
gtk_drag_get_data (widget, context, gdk_atom_intern
(model->cbs->data_type, false), time);
@@ -608,18 +610,22 @@ EXPORT GtkWidget * audgui_list_new_real (const AudguiListCallbacks * cbs, int cb
gboolean supports_drag = false;
- if (MODEL_HAS_CB (model, data_type) && MODEL_HAS_CB (model, get_data) &&
- MODEL_HAS_CB (model, receive_data))
+ if (MODEL_HAS_CB (model, data_type) &&
+ (MODEL_HAS_CB (model, get_data) || MODEL_HAS_CB (model, receive_data)))
{
const GtkTargetEntry target = {(char *) cbs->data_type, 0, 0};
- gtk_drag_source_set (list, GDK_BUTTON1_MASK, & target, 1,
- GDK_ACTION_COPY);
- gtk_drag_dest_set (list, (GtkDestDefaults) 0, & target, 1, GDK_ACTION_COPY);
+ if (MODEL_HAS_CB (model, get_data))
+ {
+ gtk_drag_source_set (list, GDK_BUTTON1_MASK, & target, 1, GDK_ACTION_COPY);
+ g_signal_connect (list, "drag-data-get", (GCallback) drag_data_get, model);
+ }
- g_signal_connect (list, "drag-data-get", (GCallback) drag_data_get, model);
- g_signal_connect (list, "drag-data-received", (GCallback)
- drag_data_received, model);
+ if (MODEL_HAS_CB (model, receive_data))
+ {
+ gtk_drag_dest_set (list, (GtkDestDefaults) 0, & target, 1, GDK_ACTION_COPY);
+ g_signal_connect (list, "drag-data-received", (GCallback) drag_data_received, model);
+ }
supports_drag = true;
}
diff --git a/src/libaudgui/menu.cc b/src/libaudgui/menu.cc
index 3069d8b..ef5ac34 100644
--- a/src/libaudgui/menu.cc
+++ b/src/libaudgui/menu.cc
@@ -65,7 +65,7 @@ static void unhook_cb (GtkCheckMenuItem * check, const AudguiMenuItem * item)
EXPORT GtkWidget * audgui_menu_item_new_with_domain
(const AudguiMenuItem * item, GtkAccelGroup * accel, const char * domain)
{
- const char * name = domain ? dgettext (domain, item->name) : item->name;
+ const char * name = (domain && item->name) ? dgettext (domain, item->name) : item->name;
GtkWidget * widget = nullptr;
if (name && item->func && ! item->cname) /* normal widget */
diff --git a/src/libaudgui/playlists.cc b/src/libaudgui/playlists.cc
index d106292..4922fba 100644
--- a/src/libaudgui/playlists.cc
+++ b/src/libaudgui/playlists.cc
@@ -68,7 +68,7 @@ static void finish_job (void * data)
Playlist::GetMode mode = Playlist::Wait;
if (aud_get_bool (nullptr, "metadata_on_play"))
- mode = Playlist::Nothing;
+ mode = Playlist::NoWait;
if (list >= 0)
{
@@ -184,6 +184,7 @@ static void create_selector (ImportExportJob * job, const char * filename, const
}
job->selector = gtk_file_chooser_dialog_new (title, nullptr, action, nullptr, nullptr);
+ gtk_file_chooser_set_local_only ((GtkFileChooser *) job->selector, false);
if (filename)
gtk_file_chooser_set_uri ((GtkFileChooser *) job->selector, filename);
diff --git a/src/libaudgui/prefs-widget.cc b/src/libaudgui/prefs-widget.cc
index df6b68b..c240ece 100644
--- a/src/libaudgui/prefs-widget.cc
+++ b/src/libaudgui/prefs-widget.cc
@@ -34,7 +34,7 @@ static void widget_changed (GtkWidget * widget, const PreferencesWidget * w)
{
case PreferencesWidget::CheckButton:
{
- gboolean set = gtk_toggle_button_get_active ((GtkToggleButton *) widget);
+ bool set = gtk_toggle_button_get_active ((GtkToggleButton *) widget);
w->cfg.set_bool (set);
auto child = (GtkWidget *) g_object_get_data ((GObject *) widget, "child");
@@ -45,10 +45,17 @@ static void widget_changed (GtkWidget * widget, const PreferencesWidget * w)
}
case PreferencesWidget::RadioButton:
- if (gtk_toggle_button_get_active ((GtkToggleButton *) widget))
+ {
+ bool set = gtk_toggle_button_get_active ((GtkToggleButton *) widget);
+ if (set)
w->cfg.set_int (w->data.radio_btn.value);
+ auto child = (GtkWidget *) g_object_get_data ((GObject *) widget, "child");
+ if (child)
+ gtk_widget_set_sensitive (child, set);
+
break;
+ }
case PreferencesWidget::SpinButton:
if (w->cfg.type == WidgetConfig::Int)
@@ -66,6 +73,13 @@ static void widget_changed (GtkWidget * widget, const PreferencesWidget * w)
w->cfg.set_string (gtk_entry_get_text ((GtkEntry *) widget));
break;
+ case PreferencesWidget::FileEntry:
+ {
+ String uri = audgui_file_entry_get_uri (widget);
+ w->cfg.set_string (uri ? uri : "");
+ break;
+ }
+
case PreferencesWidget::ComboBox:
{
auto items = (const ComboItem *) g_object_get_data ((GObject *) widget, "comboitems");
@@ -120,6 +134,10 @@ static void widget_update (void *, void * widget)
gtk_entry_set_text ((GtkEntry *) widget, w->cfg.get_string ());
break;
+ case PreferencesWidget::FileEntry:
+ audgui_file_entry_set_uri ((GtkWidget *) widget, w->cfg.get_string ());
+ break;
+
case PreferencesWidget::ComboBox:
combobox_update ((GtkWidget *) widget, w);
break;
@@ -158,6 +176,7 @@ static void widget_init (GtkWidget * widget, const PreferencesWidget * w)
break;
case PreferencesWidget::Entry:
+ case PreferencesWidget::FileEntry:
case PreferencesWidget::ComboBox:
g_signal_connect (widget, "changed", (GCallback) widget_changed, (void *) w);
break;
@@ -247,6 +266,31 @@ static void create_entry (const PreferencesWidget * widget, GtkWidget * * label,
widget_init (* entry, widget);
}
+/* WIDGET_FILE_ENTRY */
+
+static void create_file_entry (const PreferencesWidget * widget,
+ GtkWidget * * label, GtkWidget * * entry, const char * domain)
+{
+ switch (widget->data.file_entry.mode)
+ {
+ case FileSelectMode::File:
+ * entry = audgui_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN, _("Choose File"));
+ break;
+
+ case FileSelectMode::Folder:
+ * entry = audgui_file_entry_new (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, _("Choose Folder"));
+ break;
+ }
+
+ if (widget->label)
+ {
+ * label = gtk_label_new (dgettext (domain, widget->label));
+ gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5);
+ }
+
+ widget_init (* entry, widget);
+}
+
/* WIDGET_COMBO_BOX */
static void combobox_update (GtkWidget * combobox, const PreferencesWidget * widget)
@@ -339,6 +383,11 @@ static void fill_table (GtkWidget * table,
middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL);
break;
+ case PreferencesWidget::FileEntry:
+ create_file_entry (& w, & widget_left, & widget_middle, domain);
+ middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL);
+ break;
+
case PreferencesWidget::ComboBox:
create_cbox (& w, & widget_left, & widget_middle, domain);
break;
@@ -371,7 +420,7 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
{
GtkWidget * widget = nullptr, * child_box = nullptr;
bool disable_child = false;
- GSList * radio_btn_group = nullptr;
+ GSList * radio_btn_group[2] = {};
int indent = 0;
int spacing = 0;
@@ -406,8 +455,11 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
widget = nullptr;
disable_child = false;
- if (radio_btn_group && w.type != PreferencesWidget::RadioButton)
- radio_btn_group = nullptr;
+ if (w.type != PreferencesWidget::RadioButton)
+ radio_btn_group[w.child] = nullptr;
+
+ if (! w.child)
+ radio_btn_group[true] = nullptr;
switch (w.type)
{
@@ -449,9 +501,10 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
}
case PreferencesWidget::RadioButton:
- widget = gtk_radio_button_new_with_mnemonic (radio_btn_group,
- dgettext (domain, w.label));
- radio_btn_group = gtk_radio_button_get_group ((GtkRadioButton *) widget);
+ widget = gtk_radio_button_new_with_mnemonic
+ (radio_btn_group[w.child], dgettext (domain, w.label));
+ radio_btn_group[w.child] = gtk_radio_button_get_group ((GtkRadioButton *) widget);
+ disable_child = (w.cfg.get_int () != w.data.radio_btn.value);
widget_init (widget, & w);
break;
@@ -503,11 +556,16 @@ void audgui_create_widgets_with_domain (GtkWidget * box,
break;
case PreferencesWidget::Entry:
+ case PreferencesWidget::FileEntry:
{
widget = gtk_hbox_new (false, 6);
GtkWidget * entry = nullptr;
- create_entry (& w, & label, & entry, domain);
+
+ if (w.type == PreferencesWidget::FileEntry)
+ create_file_entry (& w, & label, & entry, domain);
+ else
+ create_entry (& w, & label, & entry, domain);
if (label)
gtk_box_pack_start ((GtkBox *) widget, label, false, false, 0);
diff --git a/src/libaudgui/prefs-window.cc b/src/libaudgui/prefs-window.cc
index 948119c..5ba9a09 100644
--- a/src/libaudgui/prefs-window.cc
+++ b/src/libaudgui/prefs-window.cc
@@ -125,12 +125,20 @@ static const ComboItem chardet_detector_presets[] = {
};
static const ComboItem bitdepth_elements[] = {
+ ComboItem (N_("Automatic"), -1),
ComboItem ("16", 16),
ComboItem ("24", 24),
ComboItem ("32", 32),
ComboItem (N_("Floating point"), 0)
};
+static const ComboItem record_elements[] = {
+ ComboItem (N_("As decoded"), (int) OutputStream::AsDecoded),
+ ComboItem (N_("After applying ReplayGain"), (int) OutputStream::AfterReplayGain),
+ ComboItem (N_("After applying effects"), (int) OutputStream::AfterEffects),
+ ComboItem (N_("After applying equalization"), (int) OutputStream::AfterEqualizer)
+};
+
static Index<ComboItem> iface_combo_elements;
static int iface_combo_selected;
static GtkWidget * iface_prefs_box;
@@ -160,7 +168,7 @@ static void output_bit_depth_changed ();
static const PreferencesWidget output_combo_widgets[] = {
WidgetCombo (N_("Output plugin:"),
- WidgetInt (output_combo_selected, output_combo_changed),
+ WidgetInt (output_combo_selected, output_combo_changed, "audgui update output combo"),
{0, output_combo_fill}),
WidgetCustomGTK (output_create_config_button),
WidgetCustomGTK (output_create_about_button)
@@ -199,15 +207,19 @@ static const PreferencesWidget audio_page_widgets[] = {
WidgetSpin (N_("Buffer size:"),
WidgetInt (0, "output_buffer_size"),
{100, 10000, 1000, N_("ms")}),
- WidgetCustomGTK (record_create_checkbox),
- WidgetBox ({{record_buttons}, true},
- WIDGET_CHILD),
WidgetCheck (N_("Soft clipping"),
WidgetBool (0, "soft_clipping")),
WidgetCheck (N_("Use software volume control (not recommended)"),
WidgetBool (0, "software_volume_control")),
- WidgetLabel (N_("<b>Replay Gain</b>")),
- WidgetCheck (N_("Enable Replay Gain"),
+ WidgetLabel (N_("<b>Recording Settings</b>")),
+ WidgetCustomGTK (record_create_checkbox),
+ WidgetBox ({{record_buttons}, true},
+ WIDGET_CHILD),
+ WidgetCombo (N_("Record stream:"),
+ WidgetInt (0, "record_stream"),
+ {{record_elements}}),
+ WidgetLabel (N_("<b>ReplayGain</b>")),
+ WidgetCheck (N_("Enable ReplayGain"),
WidgetBool (0, "enable_replay_gain")),
WidgetCheck (N_("Album mode"),
WidgetBool (0, "replay_gain_album"),
@@ -215,8 +227,6 @@ static const PreferencesWidget audio_page_widgets[] = {
WidgetCheck (N_("Prevent clipping (recommended)"),
WidgetBool (0, "enable_clipping_prevention"),
WIDGET_CHILD),
- WidgetLabel (N_("<b>Adjust Levels</b>"),
- WIDGET_CHILD),
WidgetTable ({{gain_table}},
WIDGET_CHILD)
};
@@ -279,8 +289,10 @@ static const PreferencesWidget playlist_page_widgets[] = {
WidgetLabel (N_("<b>Song Display</b>")),
WidgetCheck (N_("Show song numbers"),
WidgetBool (0, "show_numbers_in_pl", send_title_change)),
- WidgetCheck (N_("Show leading zeroes (02:00 instead of 2:00)"),
+ WidgetCheck (N_("Show leading zeroes (02:00 vs. 2:00)"),
WidgetBool (0, "leading_zero", send_title_change)),
+ WidgetCheck (N_("Show hours separately (1:30:00 vs. 90:00)"),
+ WidgetBool (0, "show_hours", send_title_change)),
WidgetCustomGTK (create_titlestring_table),
WidgetLabel (N_("<b>Compatibility</b>")),
WidgetCheck (N_("Interpret \\ (backward slash) as a folder delimiter"),
@@ -617,13 +629,20 @@ static void create_appearance_category ()
static void output_combo_changed ()
{
- PluginHandle * plugin = aud_plugin_list (PluginType::Output)[output_combo_selected];
+ auto & list = aud_plugin_list (PluginType::Output);
+ PluginHandle * plugin = list[output_combo_selected];
if (aud_plugin_enable (plugin, true))
{
gtk_widget_set_sensitive (output_config_button, aud_plugin_has_configure (plugin));
gtk_widget_set_sensitive (output_about_button, aud_plugin_has_about (plugin));
}
+ else
+ {
+ /* set combo box back to current output */
+ output_combo_selected = list.find (aud_plugin_get_current (PluginType::Output));
+ hook_call ("audgui update output combo", nullptr);
+ }
}
static ArrayRef<ComboItem> output_combo_fill ()
diff --git a/src/libaudgui/preset-browser.cc b/src/libaudgui/preset-browser.cc
index fa7ccb5..9144086 100644
--- a/src/libaudgui/preset-browser.cc
+++ b/src/libaudgui/preset-browser.cc
@@ -51,6 +51,8 @@ static void show_preset_browser (const char * title, gboolean save,
GTK_RESPONSE_CANCEL, save ? _("Save") : _("Load"), GTK_RESPONSE_ACCEPT,
nullptr);
+ gtk_file_chooser_set_local_only ((GtkFileChooser *) browser, false);
+
if (default_filename)
gtk_file_chooser_set_current_name ((GtkFileChooser *) browser, default_filename);
diff --git a/src/libaudgui/queue-manager.cc b/src/libaudgui/queue-manager.cc
index 195a6ba..2b5e6d0 100644
--- a/src/libaudgui/queue-manager.cc
+++ b/src/libaudgui/queue-manager.cc
@@ -45,7 +45,7 @@ static void get_value (void * user, int row, int column, GValue * value)
g_value_set_int (value, 1 + entry);
break;
case COLUMN_TITLE:
- Tuple tuple = aud_playlist_entry_get_tuple (list, entry, Playlist::Guess);
+ Tuple tuple = aud_playlist_entry_get_tuple (list, entry, Playlist::NoWait);
g_value_set_string (value, tuple.get_str (Tuple::FormattedTitle));
break;
}
diff --git a/src/libaudgui/status.cc b/src/libaudgui/status.cc
index fa04fd3..6ba9b3c 100644
--- a/src/libaudgui/status.cc
+++ b/src/libaudgui/status.cc
@@ -27,7 +27,7 @@
static GtkWidget * progress_window;
static GtkWidget * progress_label, * progress_label_2;
-static GtkWidget * error_window;
+static GtkWidget * error_window, * info_window;
static void create_progress_window ()
{
@@ -85,12 +85,18 @@ static void show_error (void * data, void * user)
audgui_simple_message (& error_window, GTK_MESSAGE_ERROR, _("Error"), (const char *) data);
}
+static void show_info (void * data, void * user)
+{
+ audgui_simple_message (& info_window, GTK_MESSAGE_INFO, _("Information"), (const char *) data);
+}
+
void status_init ()
{
hook_associate ("ui show progress", show_progress, nullptr);
hook_associate ("ui show progress 2", show_progress_2, nullptr);
hook_associate ("ui hide progress", hide_progress, nullptr);
hook_associate ("ui show error", show_error, nullptr);
+ hook_associate ("ui show info", show_info, nullptr);
}
void status_cleanup ()
@@ -99,9 +105,12 @@ void status_cleanup ()
hook_dissociate ("ui show progress 2", show_progress_2);
hook_dissociate ("ui hide progress", hide_progress);
hook_dissociate ("ui show error", show_error);
+ hook_dissociate ("ui show info", show_info);
if (progress_window)
gtk_widget_destroy (progress_window);
if (error_window)
gtk_widget_destroy (error_window);
+ if (info_window)
+ gtk_widget_destroy (info_window);
}
diff --git a/src/libaudgui/urilist.cc b/src/libaudgui/urilist.cc
index 1dc04e4..a0809f4 100644
--- a/src/libaudgui/urilist.cc
+++ b/src/libaudgui/urilist.cc
@@ -21,33 +21,13 @@
#include <libaudcore/audstrings.h>
#include <libaudcore/drct.h>
-#include <libaudcore/mainloop.h>
-#include <libaudcore/multihash.h>
#include <libaudcore/playlist.h>
-#include <libaudcore/tuple.h>
-#include <libaudcore/vfs.h>
#include "libaudgui.h"
-static SimpleHash<String, Tuple> tuple_cache;
-static QueuedFunc cleanup_timer;
-
-void urilist_cleanup ()
-{
- tuple_cache.clear ();
- cleanup_timer.stop ();
-}
-
static String check_uri (const char * name)
{
- if (! strstr (name, "://"))
- {
- StringBuf uri = filename_to_uri (name);
- if (uri)
- return String (uri);
- }
-
- return String (name);
+ return strstr (name, "://") ? String (name) : String (filename_to_uri (name));
}
static Index<PlaylistAddItem> urilist_to_index (const char * list)
@@ -67,12 +47,7 @@ static Index<PlaylistAddItem> urilist_to_index (const char * list)
next = end = strchr (list, 0);
if (end > list)
- {
- String filename = check_uri (str_copy (list, end - list));
- const Tuple * tuple = tuple_cache.lookup (filename);
-
- index.append (filename, tuple ? tuple->ref () : Tuple ());
- }
+ index.append (check_uri (str_copy (list, end - list)));
list = next;
}
@@ -92,6 +67,8 @@ EXPORT void audgui_urilist_insert (int playlist, int at, const char * list)
EXPORT Index<char> audgui_urilist_create_from_selected (int playlist)
{
+ aud_playlist_cache_selected (playlist);
+
Index<char> buf;
int entries = aud_playlist_entry_count (playlist);
@@ -103,15 +80,9 @@ EXPORT Index<char> audgui_urilist_create_from_selected (int playlist)
buf.append ('\n');
String filename = aud_playlist_entry_get_filename (playlist, count);
- Tuple tuple = aud_playlist_entry_get_tuple (playlist, count, Playlist::Nothing);
-
buf.insert (filename, -1, strlen (filename));
- if (tuple)
- tuple_cache.add (filename, std::move (tuple));
}
}
- cleanup_timer.queue (30000, [] (void *) { urilist_cleanup (); }, nullptr);
-
return buf;
}
diff --git a/src/libaudgui/util.cc b/src/libaudgui/util.cc
index 54e1c74..98307e5 100644
--- a/src/libaudgui/util.cc
+++ b/src/libaudgui/util.cc
@@ -125,6 +125,86 @@ EXPORT GtkWidget * audgui_button_new (const char * text, const char * icon,
return button;
}
+struct FileEntryData {
+ GtkFileChooserAction action;
+ String title;
+};
+
+static void entry_response_cb (GtkWidget * dialog, int response, GtkWidget * entry)
+{
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ char * uri = gtk_file_chooser_get_uri ((GtkFileChooser *) dialog);
+ if (uri)
+ {
+ audgui_file_entry_set_uri (entry, uri);
+ g_free (uri);
+ }
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void entry_browse_cb (GtkWidget * entry, GtkEntryIconPosition pos,
+ GdkEvent * event, const FileEntryData * data)
+{
+ GtkWidget * dialog = gtk_file_chooser_dialog_new (data->title, nullptr,
+ data->action, _("Open"), GTK_RESPONSE_ACCEPT, _("Cancel"),
+ GTK_RESPONSE_REJECT, nullptr);
+
+ gtk_file_chooser_set_local_only ((GtkFileChooser *) dialog, false);
+
+ String uri = audgui_file_entry_get_uri (entry);
+ if (uri)
+ gtk_file_chooser_set_uri ((GtkFileChooser *) dialog, uri);
+
+ g_signal_connect (dialog, "response", (GCallback) entry_response_cb, entry);
+ g_signal_connect_object (entry, "destroy", (GCallback) gtk_widget_destroy,
+ dialog, G_CONNECT_SWAPPED);
+
+ gtk_widget_show (dialog);
+}
+
+EXPORT GtkWidget * audgui_file_entry_new (GtkFileChooserAction action, const char * title)
+{
+ GtkWidget * entry = gtk_entry_new ();
+
+ auto data = new FileEntryData {action, String (title)};
+ auto destroy_cb = [] (void * data) { delete (FileEntryData *) data; };
+ g_object_set_data_full ((GObject *) entry, "file-entry-data", data, destroy_cb);
+
+ gtk_entry_set_icon_from_icon_name ((GtkEntry *) entry,
+ GTK_ENTRY_ICON_SECONDARY, "document-open");
+ g_signal_connect (entry, "icon-press", (GCallback) entry_browse_cb, data);
+
+ return entry;
+}
+
+EXPORT String audgui_file_entry_get_uri (GtkWidget * entry)
+{
+ const char * text = gtk_entry_get_text ((GtkEntry *) entry);
+
+ if (! text[0])
+ return String ();
+ else if (strstr (text, "://"))
+ return String (text);
+ else
+ return String (filename_to_uri (filename_normalize (filename_expand (str_copy (text)))));
+}
+
+EXPORT void audgui_file_entry_set_uri (GtkWidget * entry, const char * uri)
+{
+ if (! uri || ! uri[0])
+ {
+ gtk_entry_set_text ((GtkEntry *) entry, "");
+ return;
+ }
+
+ StringBuf path = uri_to_filename (uri, false);
+ gtk_entry_set_text ((GtkEntry *) entry, path ? filename_contract (std::move (path)) : uri);
+ gtk_editable_set_position ((GtkEditable *) entry, -1);
+}
+
EXPORT GtkWidget * audgui_dialog_new (GtkMessageType type, const char * title,
const char * text, GtkWidget * button1, GtkWidget * button2)
{