summaryrefslogtreecommitdiff
path: root/plugins/converter
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/converter')
-rw-r--r--plugins/converter/converter.c154
-rw-r--r--plugins/converter/converter.glade16
-rw-r--r--plugins/converter/converter.h3
-rw-r--r--plugins/converter/convgui.c189
-rw-r--r--plugins/converter/interface.c6
5 files changed, 269 insertions, 99 deletions
diff --git a/plugins/converter/converter.c b/plugins/converter/converter.c
index 41e896dd..a0e7a218 100644
--- a/plugins/converter/converter.c
+++ b/plugins/converter/converter.c
@@ -167,7 +167,7 @@ encoder_preset_save (ddb_encoder_preset_t *p, int overwrite) {
return -1;
}
const char *confdir = deadbeef->get_config_dir ();
- char path[1024];
+ char path[PATH_MAX];
if (snprintf (path, sizeof (path), "%s/presets", confdir) < 0) {
return -1;
}
@@ -371,7 +371,7 @@ dsp_preset_save (ddb_dsp_preset_t *p, int overwrite) {
return -1;
}
const char *confdir = deadbeef->get_config_dir ();
- char path[1024];
+ char path[PATH_MAX];
if (snprintf (path, sizeof (path), "%s/presets", confdir) < 0) {
return -1;
}
@@ -458,77 +458,69 @@ copy_file (const char *in, const char *out) {
int
load_encoder_presets (void) {
// check if we need to install presets
- char ppath[1024];
- char epath[1024];
- char fpath[1024];
+ char ppath[PATH_MAX];
+ char epath[PATH_MAX];
snprintf (ppath, sizeof (ppath), "%s/presets", deadbeef->get_config_dir ());
snprintf (epath, sizeof (epath), "%s/encoders", ppath);
- snprintf (fpath, sizeof (fpath), "%s/.installed", epath);
- struct stat stat_buf;
- if (0 != stat (fpath, &stat_buf)) {
- // file not found, install all presets from plugin_dir/convpresets/
- mkdir (ppath, 0755);
- mkdir (epath, 0755);
- char preset_src_dir[1024];
- snprintf (preset_src_dir, sizeof (preset_src_dir), "%s/convpresets", deadbeef->get_plugin_dir ());
- struct dirent **namelist = NULL;
- int n = scandir (preset_src_dir, &namelist, NULL, dirent_alphasort);
- for (int i = 0; i < n; i++) {
- // replace _ with spaces
- char new_name[1024];
- char *o = new_name;
- char *in = namelist[i]->d_name;
- while (*in) {
- if (*in == '_') {
- *o++ = ' ';
- in++;
- }
- else {
- *o++ = *in++;
- }
- }
- *o = 0;
- char in_name[1024];
- char out_name[1024];
- snprintf (in_name, sizeof (in_name), "%s/%s", preset_src_dir, namelist[i]->d_name);
- snprintf (out_name, sizeof (out_name), "%s/%s", epath, new_name);
- copy_file (in_name, out_name);
- free (namelist[i]);
- }
- if (namelist) {
- free (namelist);
- }
- FILE *fp = fopen (fpath, "w+b");
- if (fp) {
- fclose (fp);
- }
- }
- ddb_encoder_preset_t *tail = NULL;
- char path[1024];
+ char path[PATH_MAX];
if (snprintf (path, sizeof (path), "%s/presets/encoders", deadbeef->get_config_dir ()) < 0) {
return -1;
}
- struct dirent **namelist = NULL;
- int n = scandir (path, &namelist, scandir_preset_filter, dirent_alphasort);
- int i;
- for (i = 0; i < n; i++) {
- char s[1024];
- if (snprintf (s, sizeof (s), "%s/%s", path, namelist[i]->d_name) > 0){
- ddb_encoder_preset_t *p = encoder_preset_load (s);
- if (p) {
- if (tail) {
- tail->next = p;
- tail = p;
- }
- else {
- encoder_presets = tail = p;
+
+ char syspath[PATH_MAX];
+ if (snprintf (syspath, sizeof (syspath), "%s/convpresets", deadbeef->get_plugin_dir ()) < 0) {
+ return -1;
+ }
+
+ const char *preset_dirs[] = {
+ syspath, path, NULL
+ };
+
+ ddb_encoder_preset_t *tail = NULL;
+
+ for (int di = 0; preset_dirs[di]; di++) {
+ const char *path = preset_dirs[di];
+ struct dirent **namelist = NULL;
+ int n = scandir (path, &namelist, scandir_preset_filter, dirent_alphasort);
+ int i;
+ for (i = 0; i < n; i++) {
+ char s[PATH_MAX];
+ if (snprintf (s, sizeof (s), "%s/%s", path, namelist[i]->d_name) > 0){
+ ddb_encoder_preset_t *p = encoder_preset_load (s);
+ if (p) {
+ if (path == syspath) {
+ // don't allow editing stock presets
+ p->readonly = 1;
+ }
+ else {
+ // check if the same RO preset exists
+ for (ddb_encoder_preset_t *pr = encoder_presets; pr; pr = pr->next) {
+ if (pr->readonly && !strcmp (pr->title, p->title)) {
+ encoder_preset_free (p);
+ p = NULL;
+ break;
+ }
+ }
+ if (!p) {
+ // NOTE: we don't delete duplicate presets in $HOME
+ // for compat with <=0.6.1
+ continue;
+ }
+ }
+ if (tail) {
+ tail->next = p;
+ tail = p;
+ }
+ else {
+ encoder_presets = tail = p;
+ }
}
}
+ free (namelist[i]);
}
- free (namelist[i]);
+ free (namelist);
}
- free (namelist);
return 0;
}
@@ -555,7 +547,7 @@ free_encoder_presets (void) {
int
load_dsp_presets (void) {
ddb_dsp_preset_t *tail = NULL;
- char path[1024];
+ char path[PATH_MAX];
if (snprintf (path, sizeof (path), "%s/presets/dsp", deadbeef->get_config_dir ()) < 0) {
return -1;
}
@@ -563,7 +555,7 @@ load_dsp_presets (void) {
int n = scandir (path, &namelist, scandir_preset_filter, dirent_alphasort);
int i;
for (i = 0; i < n; i++) {
- char s[1024];
+ char s[PATH_MAX];
if (snprintf (s, sizeof (s), "%s/%s", path, namelist[i]->d_name) > 0){
ddb_dsp_preset_t *p = dsp_preset_load (s);
if (p) {
@@ -929,10 +921,10 @@ convert (DB_playItem_t *it, const char *out, int output_bps, int output_is_float
// write wave header
char wavehdr_int[] = {
- 0x52, 0x49, 0x46, 0x46, 0x24, 0x70, 0x0d, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61
+ 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61
};
char wavehdr_float[] = {
- 0x52, 0x49, 0x46, 0x46, 0x2a, 0xdf, 0x02, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x28, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x02, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x16, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0xc5, 0x5b, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61
+ 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x28, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x02, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x16, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0xc5, 0x5b, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61
};
char *wavehdr = output_is_float ? wavehdr_float : wavehdr_int;
int wavehdr_size = output_is_float ? sizeof (wavehdr_float) : sizeof (wavehdr_int);
@@ -1013,9 +1005,9 @@ convert (DB_playItem_t *it, const char *out, int output_bps, int output_is_float
outsize += sz;
if (!header_written) {
- uint32_t size = (it->endsample-it->startsample) * outch * output_bps / 8;
+ uint64_t size = (int64_t)(it->endsample-it->startsample) * outch * output_bps / 8;
if (!size) {
- size = deadbeef->pl_get_item_duration (it) * fileinfo->fmt.samplerate * outch * output_bps / 8;
+ size = (double)deadbeef->pl_get_item_duration (it) * fileinfo->fmt.samplerate * outch * output_bps / 8;
}
@@ -1026,20 +1018,38 @@ convert (DB_playItem_t *it, const char *out, int output_bps, int output_is_float
size = temp;
}
+ uint64_t chunksize;
+ chunksize = size + 36;
+
+ // for float, add 36 more
+ if (output_is_float) {
+ chunksize += 36;
+ }
+
+ uint32_t size32 = 0xffffffff;
+ if (chunksize <= 0xffffffff) {
+ size32 = chunksize;
+ }
+ memcpy (&wavehdr[4], &size32, 4);
memcpy (&wavehdr[22], &outch, 2);
memcpy (&wavehdr[24], &outsr, 4);
uint16_t blockalign = outch * output_bps / 8;
memcpy (&wavehdr[32], &blockalign, 2);
memcpy (&wavehdr[34], &output_bps, 2);
+ size32 = 0xffffffff;
+ if (size <= 0xffffffff) {
+ size32 = size;
+ }
+
if (wavehdr_size != write (temp_file, wavehdr, wavehdr_size)) {
fprintf (stderr, "converter: wave header write error\n");
goto error;
}
if (encoder_preset->method == DDB_ENCODER_METHOD_PIPE) {
- size = 0;
+ size32 = 0;
}
- if (write (temp_file, &size, sizeof (size)) != sizeof (size)) {
+ if (write (temp_file, &size32, sizeof (size32)) != sizeof (size32)) {
fprintf (stderr, "converter: wave header size write error\n");
goto error;
}
@@ -1220,7 +1230,7 @@ static ddb_converter_t plugin = {
.misc.plugin.api_vmajor = 1,
.misc.plugin.api_vminor = 0,
.misc.plugin.version_major = 1,
- .misc.plugin.version_minor = 2,
+ .misc.plugin.version_minor = 3,
.misc.plugin.type = DB_PLUGIN_MISC,
.misc.plugin.name = "Converter",
.misc.plugin.id = "converter",
diff --git a/plugins/converter/converter.glade b/plugins/converter/converter.glade
index af771399..a5f44643 100644
--- a/plugins/converter/converter.glade
+++ b/plugins/converter/converter.glade
@@ -1730,6 +1730,22 @@ Temporary file</property>
</child>
<child>
+ <widget class="GtkButton" id="copy">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-copy</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
<widget class="GtkButton" id="remove">
<property name="visible">True</property>
<property name="can_focus">True</property>
diff --git a/plugins/converter/converter.h b/plugins/converter/converter.h
index 0adc5833..63aeb349 100644
--- a/plugins/converter/converter.h
+++ b/plugins/converter/converter.h
@@ -53,6 +53,9 @@ typedef struct ddb_encoder_preset_s {
int tag_oggvorbis;
int tag_mp3xing;
int id3v2_version;
+
+ // added in converter-1.3
+ int readonly; // this means the preset cannot be edited
} ddb_encoder_preset_t;
typedef struct ddb_dsp_preset_s {
diff --git a/plugins/converter/convgui.c b/plugins/converter/convgui.c
index b461dcb7..e1ebdfb1 100644
--- a/plugins/converter/convgui.c
+++ b/plugins/converter/convgui.c
@@ -67,13 +67,24 @@ typedef struct {
converter_ctx_t *current_ctx;
-void
-fill_presets (GtkListStore *mdl, ddb_preset_t *head) {
+enum {
+ PRESET_TYPE_ENCODER,
+ PRESET_TYPE_DSP
+};
+
+static void
+fill_presets (GtkListStore *mdl, ddb_preset_t *head, int type) {
ddb_preset_t *p = head;
while (p) {
GtkTreeIter iter;
gtk_list_store_append (mdl, &iter);
- gtk_list_store_set (mdl, &iter, 0, p->title, -1);
+ const char *s = p->title;
+ if (type == PRESET_TYPE_ENCODER && ((ddb_encoder_preset_t *)p)->readonly) {
+ char stock[1000];
+ snprintf (stock, sizeof (stock), _("[Built-in] %s"), p->title);
+ s = stock;
+ }
+ gtk_list_store_set (mdl, &iter, 0, s, -1);
p = p->next;
}
}
@@ -432,7 +443,7 @@ converter_show_cb (void *data) {
// fill encoder presets
combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "encoder"));
GtkListStore *mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
- fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list ());
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list (), PRESET_TYPE_ENCODER);
gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("converter.encoder_preset", 0));
// fill dsp presets
@@ -441,7 +452,7 @@ converter_show_cb (void *data) {
GtkTreeIter iter;
gtk_list_store_append (mdl, &iter);
gtk_list_store_set (mdl, &iter, 0, "Pass through", -1);
- fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ());
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list (), PRESET_TYPE_DSP);
gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("converter.dsp_preset", -1) + 1);
@@ -693,13 +704,12 @@ init_encoder_preset_from_dlg (GtkWidget *dlg, ddb_encoder_preset_t *p) {
}
int
-edit_encoder_preset (char *title, GtkWidget *toplevel, int overwrite) {
+edit_encoder_preset (char *title, GtkWidget *toplevel) {
GtkWidget *dlg = create_convpreset_editor ();
gtk_window_set_title (GTK_WINDOW (dlg), title);
gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (toplevel));
-
ddb_encoder_preset_t *p = current_ctx->current_encoder_preset;
if (p->title) {
@@ -728,7 +738,19 @@ edit_encoder_preset (char *title, GtkWidget *toplevel, int overwrite) {
ddb_encoder_preset_t *p = converter_plugin->encoder_preset_alloc ();
if (p) {
init_encoder_preset_from_dlg (dlg, p);
- int err = converter_plugin->encoder_preset_save (p, overwrite);
+ int err = 0;
+
+ ddb_encoder_preset_t *pp = converter_plugin->encoder_preset_get_list ();
+ for (; pp; pp = pp->next) {
+ if (pp != old && !strcmp (pp->title, p->title)) {
+ err = -2;
+ break;
+ }
+ }
+
+ if (!err) {
+ err = converter_plugin->encoder_preset_save (p, 1);
+ }
if (!err) {
if (old->title && strcmp (p->title, old->title)) {
char path[1024];
@@ -778,7 +800,7 @@ refresh_encoder_lists (GtkComboBox *combo, GtkTreeView *list) {
}
gtk_list_store_clear (mdl);
- fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list ());
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list (), PRESET_TYPE_ENCODER);
if (idx != -1) {
path = gtk_tree_path_new_from_indices (idx, -1);
gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
@@ -789,7 +811,7 @@ refresh_encoder_lists (GtkComboBox *combo, GtkTreeView *list) {
int act = gtk_combo_box_get_active (combo);
mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo));
gtk_list_store_clear (mdl);
- fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list ());
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list (), PRESET_TYPE_ENCODER);
gtk_combo_box_set_active (combo, act);
}
@@ -801,7 +823,7 @@ on_encoder_preset_add (GtkButton *button,
current_ctx->current_encoder_preset = converter_plugin->encoder_preset_alloc ();
- if (GTK_RESPONSE_OK == edit_encoder_preset (_("Add new encoder"), toplevel, 0)) {
+ if (GTK_RESPONSE_OK == edit_encoder_preset (_("Add new encoder"), toplevel)) {
converter_plugin->encoder_preset_append (current_ctx->current_encoder_preset);
GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "encoder"));
GtkWidget *list = lookup_widget (toplevel, "presets");
@@ -831,7 +853,7 @@ on_encoder_preset_edit (GtkButton *button,
ddb_encoder_preset_t *p = converter_plugin->encoder_preset_get_for_idx (idx);
current_ctx->current_encoder_preset = p;
- int r = edit_encoder_preset (_("Edit encoder"), toplevel, 1);
+ int r = edit_encoder_preset (_("Edit encoder"), toplevel);
if (r == GTK_RESPONSE_OK) {
GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "encoder"));
refresh_encoder_lists (combo, GTK_TREE_VIEW (list));
@@ -884,6 +906,63 @@ on_encoder_preset_remove (GtkButton *button,
}
}
+static void
+on_encoder_preset_cursor_changed (GtkTreeView *treeview,
+ gpointer user_data) {
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (treeview));
+ GtkWidget *edit = lookup_widget (toplevel, "edit");
+
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (treeview, &path, &col);
+ if (!path || !col) {
+ // nothing selected
+ gtk_widget_set_sensitive (edit, FALSE);
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+
+ ddb_encoder_preset_t *p = converter_plugin->encoder_preset_get_for_idx (idx);
+ gtk_widget_set_sensitive (edit, !p->readonly);
+}
+
+
+void
+on_encoder_preset_copy (GtkButton *button, gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+ GtkTreeView *treeview = GTK_TREE_VIEW (lookup_widget (toplevel, "presets"));
+
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (treeview, &path, &col);
+ if (!path || !col) {
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+
+ ddb_encoder_preset_t *p = converter_plugin->encoder_preset_get_for_idx (idx);
+
+ current_ctx->current_encoder_preset = converter_plugin->encoder_preset_alloc ();
+ if (!current_ctx->current_encoder_preset) {
+ return;
+ }
+ converter_plugin->encoder_preset_copy (current_ctx->current_encoder_preset, p);
+
+ if (GTK_RESPONSE_OK == edit_encoder_preset (_("Add new encoder"), toplevel)) {
+ converter_plugin->encoder_preset_append (current_ctx->current_encoder_preset);
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "encoder"));
+ refresh_encoder_lists (combo, treeview);
+ }
+
+ current_ctx->current_encoder_preset = NULL;
+}
+
void
on_edit_encoder_presets_clicked (GtkButton *button,
gpointer user_data)
@@ -894,14 +973,16 @@ on_edit_encoder_presets_clicked (GtkButton *button,
g_signal_connect ((gpointer)lookup_widget (dlg, "add"), "clicked", G_CALLBACK (on_encoder_preset_add), NULL);
g_signal_connect ((gpointer)lookup_widget (dlg, "remove"), "clicked", G_CALLBACK (on_encoder_preset_remove), NULL);
g_signal_connect ((gpointer)lookup_widget (dlg, "edit"), "clicked", G_CALLBACK (on_encoder_preset_edit), NULL);
+ g_signal_connect ((gpointer)lookup_widget (dlg, "copy"), "clicked", G_CALLBACK (on_encoder_preset_copy), NULL);
GtkWidget *list = lookup_widget (dlg, "presets");
+ g_signal_connect ((gpointer)list, "cursor-changed", G_CALLBACK (on_encoder_preset_cursor_changed), NULL);
GtkCellRenderer *title_cell = gtk_cell_renderer_text_new ();
GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (_("Title"), title_cell, "text", 0, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (list), GTK_TREE_VIEW_COLUMN (col));
GtkListStore *mdl = gtk_list_store_new (1, G_TYPE_STRING);
gtk_tree_view_set_model (GTK_TREE_VIEW (list), GTK_TREE_MODEL (mdl));
- fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list ());
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->encoder_preset_get_list (), PRESET_TYPE_ENCODER);
int curr = deadbeef->conf_get_int ("converter.encoder_preset", -1);
if (curr != -1) {
GtkTreePath *path = gtk_tree_path_new_from_indices (curr, -1);
@@ -1181,7 +1262,7 @@ on_dsp_preset_plugin_down_clicked (GtkButton *button,
int
-edit_dsp_preset (const char *title, GtkWidget *toplevel, int overwrite) {
+edit_dsp_preset (const char *title, GtkWidget *toplevel, ddb_dsp_preset_t *orig) {
int r = GTK_RESPONSE_CANCEL;
GtkWidget *dlg = create_dsppreset_editor ();
@@ -1189,10 +1270,11 @@ edit_dsp_preset (const char *title, GtkWidget *toplevel, int overwrite) {
gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (toplevel));
gtk_window_set_title (GTK_WINDOW (dlg), title);
+ ddb_dsp_preset_t *p = current_ctx->current_dsp_preset;
// title
- if (current_ctx->current_dsp_preset->title) {
- gtk_entry_set_text (GTK_ENTRY (lookup_widget (dlg, "title")), current_ctx->current_dsp_preset->title);
+ if (p->title) {
+ gtk_entry_set_text (GTK_ENTRY (lookup_widget (dlg, "title")), p->title);
}
{
@@ -1213,11 +1295,26 @@ edit_dsp_preset (const char *title, GtkWidget *toplevel, int overwrite) {
r = gtk_dialog_run (GTK_DIALOG (dlg));
if (r == GTK_RESPONSE_OK) {
- if (current_ctx->current_dsp_preset->title) {
- free (current_ctx->current_dsp_preset->title);
+ const char *title = gtk_entry_get_text (GTK_ENTRY (lookup_widget (dlg, "title")));
+ int err = 0;
+
+ // don't allow duplicate title with existing presets
+ ddb_dsp_preset_t *pp = converter_plugin->dsp_preset_get_list ();
+ for (; pp; pp = pp->next) {
+ if (pp != orig && !strcmp (pp->title, title)) {
+ err = -2;
+ break;
+ }
}
- current_ctx->current_dsp_preset->title = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (dlg, "title"))));
- int err = converter_plugin->dsp_preset_save (current_ctx->current_dsp_preset, overwrite);
+
+ if (!err) {
+ if (current_ctx->current_dsp_preset->title) {
+ free (current_ctx->current_dsp_preset->title);
+ }
+ current_ctx->current_dsp_preset->title = strdup (title);
+ err = converter_plugin->dsp_preset_save (current_ctx->current_dsp_preset, 1);
+ }
+
if (err < 0) {
GtkWidget *warndlg = gtk_message_dialog_new (GTK_WINDOW (gtkui_plugin->get_mainwin ()), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Failed to save DSP preset"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (warndlg), err == -1 ? _("Check preset folder permissions, try to pick different title, or free up some disk space") : _("Preset with the same name already exists. Try to pick another title."));
@@ -1255,7 +1352,7 @@ refresh_dsp_lists (GtkComboBox *combo, GtkTreeView *list) {
}
gtk_list_store_clear (mdl);
- fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ());
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list (), PRESET_TYPE_DSP);
if (idx != -1) {
path = gtk_tree_path_new_from_indices (idx, -1);
gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, col, FALSE);
@@ -1269,7 +1366,7 @@ refresh_dsp_lists (GtkComboBox *combo, GtkTreeView *list) {
GtkTreeIter iter;
gtk_list_store_append (mdl, &iter);
gtk_list_store_set (mdl, &iter, 0, "Pass through", -1);
- fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ());
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list (), PRESET_TYPE_DSP);
gtk_combo_box_set_active (combo, act);
}
@@ -1283,7 +1380,7 @@ on_dsp_preset_add (GtkButton *button,
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
- if (GTK_RESPONSE_OK == edit_dsp_preset (_("New DSP Preset"), toplevel, 0)) {
+ if (GTK_RESPONSE_OK == edit_dsp_preset (_("New DSP Preset"), toplevel, NULL)) {
converter_plugin->dsp_preset_append (current_ctx->current_dsp_preset);
GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "dsp_preset"));
GtkWidget *list = lookup_widget (toplevel, "presets");
@@ -1297,6 +1394,43 @@ on_dsp_preset_add (GtkButton *button,
}
void
+on_dsp_preset_copy (GtkButton *button, gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+ GtkTreeView *treeview = GTK_TREE_VIEW (lookup_widget (toplevel, "presets"));
+
+ GtkTreePath *path;
+ GtkTreeViewColumn *col;
+ gtk_tree_view_get_cursor (treeview, &path, &col);
+ if (!path || !col) {
+ return;
+ }
+ int *indices = gtk_tree_path_get_indices (path);
+ int idx = *indices;
+ g_free (indices);
+
+ ddb_dsp_preset_t *p = converter_plugin->dsp_preset_get_for_idx (idx);
+
+ current_ctx->current_dsp_preset = converter_plugin->dsp_preset_alloc ();
+ if (!current_ctx->current_dsp_preset) {
+ return;
+ }
+ converter_plugin->dsp_preset_copy (current_ctx->current_dsp_preset, p);
+
+ if (GTK_RESPONSE_OK == edit_dsp_preset (_("New DSP Preset"), toplevel, NULL)) {
+ converter_plugin->dsp_preset_append (current_ctx->current_dsp_preset);
+ GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (current_ctx->converter, "dsp_preset"));
+ refresh_dsp_lists (combo, treeview);
+ }
+ else {
+ converter_plugin->dsp_preset_free (current_ctx->current_dsp_preset);
+ }
+
+ current_ctx->current_dsp_preset = NULL;
+}
+
+void
on_dsp_preset_remove (GtkButton *button,
gpointer user_data)
{
@@ -1368,7 +1502,7 @@ on_dsp_preset_edit (GtkButton *button,
current_ctx->current_dsp_preset = converter_plugin->dsp_preset_alloc ();
converter_plugin->dsp_preset_copy (current_ctx->current_dsp_preset, p);
- int r = edit_dsp_preset (_("Edit DSP Preset"), toplevel, 1);
+ int r = edit_dsp_preset (_("Edit DSP Preset"), toplevel, p);
if (r == GTK_RESPONSE_OK) {
// replace preset
converter_plugin->dsp_preset_replace (p, current_ctx->current_dsp_preset);
@@ -1393,6 +1527,7 @@ on_edit_dsp_presets_clicked (GtkButton *button,
g_signal_connect ((gpointer)lookup_widget (dlg, "add"), "clicked", G_CALLBACK (on_dsp_preset_add), NULL);
g_signal_connect ((gpointer)lookup_widget (dlg, "remove"), "clicked", G_CALLBACK (on_dsp_preset_remove), NULL);
g_signal_connect ((gpointer)lookup_widget (dlg, "edit"), "clicked", G_CALLBACK (on_dsp_preset_edit), NULL);
+ g_signal_connect ((gpointer)lookup_widget (dlg, "copy"), "clicked", G_CALLBACK (on_dsp_preset_copy), NULL);
GtkWidget *list = lookup_widget (dlg, "presets");
GtkCellRenderer *title_cell = gtk_cell_renderer_text_new ();
@@ -1400,7 +1535,7 @@ on_edit_dsp_presets_clicked (GtkButton *button,
gtk_tree_view_append_column (GTK_TREE_VIEW (list), GTK_TREE_VIEW_COLUMN (col));
GtkListStore *mdl = gtk_list_store_new (1, G_TYPE_STRING);
gtk_tree_view_set_model (GTK_TREE_VIEW (list), GTK_TREE_MODEL (mdl));
- fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ());
+ fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list (), PRESET_TYPE_DSP);
int curr = deadbeef->conf_get_int ("converter.dsp_preset", -1);
if (curr >= 0) {
GtkTreePath *path = gtk_tree_path_new_from_indices (curr, -1);
@@ -1463,8 +1598,8 @@ convgui_connect (void) {
fprintf (stderr, "convgui: converter plugin not found\n");
return -1;
}
- if (!PLUG_TEST_COMPAT(&converter_plugin->misc.plugin, 1, 2)) {
- fprintf (stderr, "convgui: need converter>=1.2, but found %d.%d\n", converter_plugin->misc.plugin.version_major, converter_plugin->misc.plugin.version_minor);
+ if (!PLUG_TEST_COMPAT(&converter_plugin->misc.plugin, 1, 3)) {
+ fprintf (stderr, "convgui: need converter>=1.3, but found %d.%d\n", converter_plugin->misc.plugin.version_major, converter_plugin->misc.plugin.version_minor);
return -1;
}
return 0;
diff --git a/plugins/converter/interface.c b/plugins/converter/interface.c
index 4e693e3b..56b5bdcd 100644
--- a/plugins/converter/interface.c
+++ b/plugins/converter/interface.c
@@ -792,6 +792,7 @@ create_preset_list (void)
GtkWidget *vbox33;
GtkWidget *hbox94;
GtkWidget *add;
+ GtkWidget *copy;
GtkWidget *remove;
GtkWidget *edit;
GtkWidget *scrolledwindow8;
@@ -821,6 +822,10 @@ create_preset_list (void)
gtk_widget_show (add);
gtk_box_pack_start (GTK_BOX (hbox94), add, FALSE, TRUE, 0);
+ copy = gtk_button_new_from_stock ("gtk-copy");
+ gtk_widget_show (copy);
+ gtk_box_pack_start (GTK_BOX (hbox94), copy, FALSE, TRUE, 0);
+
remove = gtk_button_new_from_stock ("gtk-remove");
gtk_widget_show (remove);
gtk_box_pack_start (GTK_BOX (hbox94), remove, FALSE, TRUE, 0);
@@ -856,6 +861,7 @@ create_preset_list (void)
GLADE_HOOKUP_OBJECT (preset_list, vbox33, "vbox33");
GLADE_HOOKUP_OBJECT (preset_list, hbox94, "hbox94");
GLADE_HOOKUP_OBJECT (preset_list, add, "add");
+ GLADE_HOOKUP_OBJECT (preset_list, copy, "copy");
GLADE_HOOKUP_OBJECT (preset_list, remove, "remove");
GLADE_HOOKUP_OBJECT (preset_list, edit, "edit");
GLADE_HOOKUP_OBJECT (preset_list, scrolledwindow8, "scrolledwindow8");