summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Lithopsian <deadbeef@nartowicz.co.uk>2014-06-22 22:39:47 +0100
committerGravatar Lithopsian <deadbeef@nartowicz.co.uk>2014-06-22 22:39:47 +0100
commit6cd87a40c3a3da1ff8ecdc0f8b980cec38de84aa (patch)
tree7d87af9dae15d6227edc3f0efebe16c49593a973 /plugins
parent579a1e72d3c96c2b04f127cc273f3641a56702fe (diff)
parentd43b7c86b8fe7e5ef47a78becbca46b121d33d40 (diff)
Merge pull request #7 from Alexey-Yakovenko/master
Resync
Diffstat (limited to 'plugins')
-rw-r--r--plugins/artwork/Makefile.am2
-rw-r--r--plugins/artwork/escape.h34
-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
-rw-r--r--plugins/flac/flac.c106
-rw-r--r--plugins/gtkui/actionhandlers.c13
-rw-r--r--plugins/gtkui/deadbeef.glade1
-rw-r--r--plugins/gtkui/interface.c1
-rw-r--r--plugins/gtkui/plcommon.c11
-rw-r--r--plugins/m3u/m3u.c31
13 files changed, 345 insertions, 222 deletions
diff --git a/plugins/artwork/Makefile.am b/plugins/artwork/Makefile.am
index 9fb8bea8..11f98e24 100644
--- a/plugins/artwork/Makefile.am
+++ b/plugins/artwork/Makefile.am
@@ -21,7 +21,7 @@ endif
if HAVE_FLAC
FLAC_DEPS=$(FLAC_LIBS)
-flac_clags=-DUSE_METAFLAC $(FLAC_CFLAGS)
+flac_cflags=-DUSE_METAFLAC $(FLAC_CFLAGS)
endif
AM_CFLAGS = $(CFLAGS) $(ARTWORK_CFLAGS) $(flac_cflags) $(artwork_net_cflags) -std=c99
diff --git a/plugins/artwork/escape.h b/plugins/artwork/escape.h
index a8086a89..bd76f4d4 100644
--- a/plugins/artwork/escape.h
+++ b/plugins/artwork/escape.h
@@ -1,20 +1,24 @@
/*
- DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009-2013 Alexey Yakovenko <waker@users.sourceforge.net>
+ DeaDBeeF -- the music player
+ Copyright (C) 2009-2014 Alexey Yakovenko and other contributors
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef __ESCAPE_H
#define __ESCAPE_H
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");
diff --git a/plugins/flac/flac.c b/plugins/flac/flac.c
index 5deab23e..977298b0 100644
--- a/plugins/flac/flac.c
+++ b/plugins/flac/flac.c
@@ -988,6 +988,9 @@ cflac_write_metadata (DB_playItem_t *it) {
if (data && data->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
break;
}
+ else {
+ data = NULL;
+ }
} while (FLAC__metadata_iterator_next (iter));
if (data) {
@@ -1062,108 +1065,13 @@ cflac_write_metadata (DB_playItem_t *it) {
deadbeef->pl_unlock ();
-#if 0 // fetching covers is broken, disabling for 0.5.2
- // check if we have embedded cover
- data = NULL;
- while (FLAC__metadata_iterator_prev (iter));
- do {
- data = FLAC__metadata_iterator_get_block (iter);
- if (data && data->type == FLAC__METADATA_TYPE_PICTURE) {
- break;
- }
- } while (FLAC__metadata_iterator_next (iter));
-
- if (!coverart_plugin) {
- DB_plugin_t **plugins = deadbeef->plug_get_list ();
- for (int i = 0; plugins[i]; i++) {
- DB_plugin_t *p = plugins[i];
- if (p->id && !strcmp (p->id, "artwork") && p->version_major == 1 && p->version_minor >= 1) {
- coverart_plugin = (DB_artwork_plugin_t *)p;
- break;
- }
- }
- }
-
- // add coverart if the file doesn't have it
- // FIXME: should have an option to overwrite it
- if ((!data || data->type != FLAC__METADATA_TYPE_PICTURE) && coverart_plugin) {
- deadbeef->pl_lock ();
- const char *alb = deadbeef->pl_find_meta (it, "album");
- const char *art = deadbeef->pl_find_meta (it, "artist");
- if (!alb || !*alb) {
- alb = deadbeef->pl_find_meta (it, "title");
- }
- const char *fn = deadbeef->pl_find_meta (it, ":URI");
-
- char *album = alb ? strdupa (alb) : NULL;
- char *artist = art ? strdupa (art) : NULL;
- char *fname = fn ? strdupa (fn) : NULL;
- deadbeef->pl_unlock ();
-
- char *image_fname = coverart_plugin->get_album_art_sync (fname, artist, album, -1);
-
- if (image_fname && strcmp (image_fname, coverart_plugin->get_default_cover())) {
- DB_FILE *fp = deadbeef->fopen (image_fname);
- FLAC__byte *coverart_data = NULL;
- FLAC__StreamMetadata *metadata = NULL;
- if (!fp) {
- fprintf (stderr, "flac: cannot open coverart %s\n", image_fname);
- goto error2;
- }
-
- int64_t len = deadbeef->fgetlength (fp);
- if (len < 4) {
- fprintf (stderr, "flac: cover image file %s is too small\n", image_fname);
- goto error2;
- }
- coverart_data = malloc (len);
- if (!coverart_data) {
- fprintf (stderr, "flac: cannot allocate memory\n");
- goto error2;
- }
- if (!deadbeef->fread (coverart_data, len, 1, fp)) {
- fprintf (stderr, "flac: cannot read from %s\n",image_fname);
- goto error2;
- }
-
- metadata = FLAC__metadata_object_new (FLAC__METADATA_TYPE_PICTURE);
- if (!metadata) {
- fprintf (stderr, "flac: failed to allocate new picture block\n");
- goto error2;
- }
-
- FLAC__metadata_object_picture_set_description (metadata, "Cover", true);
- FLAC__metadata_object_picture_set_data (metadata, coverart_data,len, true);
- metadata->data.picture.type = FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
-
- if (*(uint32_t *)coverart_data == 0x474e5089) { // png header
- metadata->data.picture.mime_type = strdup ("image/png");
- } else {
- metadata->data.picture.mime_type = strdup ("image/jpeg");
- }
-
- while (FLAC__metadata_iterator_next (iter));
- if (!FLAC__metadata_iterator_insert_block_after (iter, metadata)) {
- fprintf (stderr, "flac: failed to append picture block to chain\n");
- goto error2;
- }
-
-error2:
- if (fp) {
- deadbeef->fclose (fp);
- }
- if (coverart_data) {
- free (coverart_data);
- }
- }
- }
-#endif
-
- if (!isogg)
+ if (!isogg) {
res = FLAC__metadata_chain_write (chain, 1, 0);
+ }
#if USE_OGGEDIT
- else
+ else {
res = cflac_write_metadata_ogg(it, &data->data.vorbis_comment);
+ }
#endif
if (res) {
trace ("cflac_write_metadata: failed to write tags: code %d\n", res);
diff --git a/plugins/gtkui/actionhandlers.c b/plugins/gtkui/actionhandlers.c
index ad4bf04c..99a658bb 100644
--- a/plugins/gtkui/actionhandlers.c
+++ b/plugins/gtkui/actionhandlers.c
@@ -40,6 +40,9 @@
#include "callbacks.h"
#include <sys/stat.h>
+// disable custom title function, until we have new title formatting (0.7)
+#define DISABLE_CUSTOM_TITLE
+
extern GtkWidget *mainwin;
extern DB_functions_t *deadbeef;
@@ -401,7 +404,6 @@ on_toggle_set_custom_title (GtkToggleButton *togglebutton, gpointer user_data) {
deadbeef->conf_save ();
}
-
gboolean
action_add_location_handler_cb (void *user_data) {
GtkWidget *dlg = create_addlocationdlg ();
@@ -409,18 +411,23 @@ action_add_location_handler_cb (void *user_data) {
GtkWidget *sct = lookup_widget (dlg, "set_custom_title");
GtkWidget *ct = lookup_widget (dlg, "custom_title");
+#ifndef DISABLE_CUSTOM_TITLE
if (deadbeef->conf_get_int ("gtkui.location_set_custom_title", 0)) {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sct), TRUE);
gtk_widget_set_sensitive (ct, TRUE);
}
- else {
+ else
+#endif
+ {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sct), FALSE);
gtk_widget_set_sensitive (ct, FALSE);
}
+#ifndef DISABLE_CUSTOM_TITLE
g_signal_connect ((gpointer) sct, "toggled",
G_CALLBACK (on_toggle_set_custom_title),
dlg);
+#endif
gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
int res = gtk_dialog_run (GTK_DIALOG (dlg));
@@ -433,9 +440,11 @@ action_add_location_handler_cb (void *user_data) {
if (!deadbeef->plt_add_files_begin (plt, 0)) {
DB_playItem_t *tail = deadbeef->plt_get_last (plt, PL_MAIN);
DB_playItem_t *it = deadbeef->plt_insert_file2 (0, plt, tail, text, NULL, NULL, NULL);
+#ifndef DISABLE_CUSTOM_TITLE
if (it && deadbeef->conf_get_int ("gtkui.location_set_custom_title", 0)) {
deadbeef->pl_replace_meta (it, ":CUSTOM_TITLE", gtk_entry_get_text (GTK_ENTRY (ct)));
}
+#endif
if (tail) {
deadbeef->pl_item_unref (tail);
}
diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade
index 7828a9bf..57dd0cbe 100644
--- a/plugins/gtkui/deadbeef.glade
+++ b/plugins/gtkui/deadbeef.glade
@@ -6342,7 +6342,6 @@ if you don't press Apply.</property>
<child>
<widget class="GtkHBox" id="hbox122">
- <property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">8</property>
diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c
index 5cd3ce7e..c4c02b73 100644
--- a/plugins/gtkui/interface.c
+++ b/plugins/gtkui/interface.c
@@ -3223,7 +3223,6 @@ create_addlocationdlg (void)
gtk_entry_set_activates_default (GTK_ENTRY (addlocation_entry), TRUE);
hbox122 = gtk_hbox_new (FALSE, 8);
- gtk_widget_show (hbox122);
gtk_box_pack_start (GTK_BOX (vbox45), hbox122, TRUE, TRUE, 0);
set_custom_title = gtk_check_button_new_with_mnemonic (_("Set custom title"));
diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c
index a6077929..d7df4f62 100644
--- a/plugins/gtkui/plcommon.c
+++ b/plugins/gtkui/plcommon.c
@@ -38,6 +38,9 @@
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
+// disable custom title function, until we have new title formatting (0.7)
+#define DISABLE_CUSTOM_TITLE
+
char group_by_str[MAX_GROUP_BY_STR];
extern GtkWidget *theme_treeview;
@@ -478,6 +481,7 @@ on_toggle_set_custom_title (GtkToggleButton *togglebutton, gpointer user_data) {
deadbeef->conf_save ();
}
+#ifndef DISABLE_CUSTOM_TITLE
void
on_set_custom_title_activate (GtkMenuItem *menuitem, gpointer user_data)
{
@@ -530,6 +534,7 @@ on_set_custom_title_activate (GtkMenuItem *menuitem, gpointer user_data)
gtk_widget_destroy (dlg);
lv->binding->unref (it);
}
+#endif
void
on_remove_from_disk_activate (GtkMenuItem *menuitem,
@@ -624,7 +629,9 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
GtkWidget *separator8;
GtkWidget *properties1;
GtkWidget *reload_metadata;
+#ifndef DISABLE_CUSTOM_TITLE
GtkWidget *set_custom_title;
+#endif
playlist_menu = gtk_menu_new ();
add_to_playback_queue1 = gtk_menu_item_new_with_mnemonic (_("Add To Playback Queue"));
@@ -795,6 +802,7 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
gtk_widget_set_sensitive (separator8, FALSE);
}
+#ifndef DISABLE_CUSTOM_TITLE
set_custom_title = gtk_menu_item_new_with_mnemonic (_("Set Custom Title"));
gtk_widget_show (set_custom_title);
gtk_container_add (GTK_CONTAINER (playlist_menu), set_custom_title);
@@ -806,6 +814,7 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
gtk_widget_show (separator);
gtk_container_add (GTK_CONTAINER (playlist_menu), separator);
gtk_widget_set_sensitive (separator, FALSE);
+#endif
properties1 = gtk_menu_item_new_with_mnemonic (_("Track Properties"));
gtk_widget_show (properties1);
@@ -829,9 +838,11 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) {
G_CALLBACK (on_remove_from_disk_activate),
NULL);
}
+#ifndef DISABLE_CUSTOM_TITLE
g_signal_connect ((gpointer) set_custom_title, "activate",
G_CALLBACK (on_set_custom_title_activate),
listview);
+#endif
g_signal_connect ((gpointer) properties1, "activate",
G_CALLBACK (main_properties_activate),
NULL);
diff --git a/plugins/m3u/m3u.c b/plugins/m3u/m3u.c
index ea5a5fba..56602c4c 100644
--- a/plugins/m3u/m3u.c
+++ b/plugins/m3u/m3u.c
@@ -21,9 +21,16 @@
3. This notice may not be removed or altered from any source distribution.
*/
+#ifdef HAVE_CONFIG_H
+# include "../../config.h"
+#endif
#include <string.h>
#include <stdlib.h>
#include <math.h> // for ceil
+#if HAVE_SYS_SYSLIMITS_H
+#include <sys/syslimits.h>
+#endif
+
#include "../../deadbeef.h"
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
@@ -235,18 +242,24 @@ load_m3u (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pab
static DB_playItem_t *
pls_insert_file (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, const char *uri, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data, const char *title, const char *length) {
trace ("pls_insert_file uri: %s\n", uri);
+ trace ("pls_insert_file fname: %s\n", fname);
DB_playItem_t *it = NULL;
const char *slash = NULL;
if (strrchr (uri, '/')) {
+ trace ("pls: inserting from uri: %s\n", uri);
it = deadbeef->plt_insert_file2 (0, plt, after, uri, pabort, cb, user_data);
}
- else if (slash = strrchr (fname, '/')) {
+
+ if (!it) {
+ slash = strrchr (fname, '/');
+ }
+ if (slash) {
int l = strlen (uri);
char fullpath[slash - fname + l + 2];
memcpy (fullpath, fname, slash - fname + 1);
strcpy (fullpath + (slash - fname + 1), uri);
- trace ("pls_insert_file: adding file %s\n", fullpath);
+ trace ("pls: inserting from calculated relative path: %s\n", fullpath);
it = deadbeef->plt_insert_file2 (0, plt, after, fullpath, pabort, cb, user_data);
}
if (it) {
@@ -262,6 +275,7 @@ pls_insert_file (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, c
static DB_playItem_t *
load_pls (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) {
+ trace ("load_pls %s\n", fname);
const char *slash = strrchr (fname, '/');
DB_FILE *fp = deadbeef->fopen (fname);
if (!fp) {
@@ -423,8 +437,11 @@ load_pls (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pab
trace ("length%d=%s\n", idx, length);
}
else {
- trace ("invalid entry in pls file: %s\n", p);
- break;
+ trace ("pls: skipping unrecognized entry in pls file: %s\n", p);
+ e = p;
+ while (e < end && *e >= 0x20) {
+ e++;
+ }
}
while (e < end && *e < 0x20) {
e++;
@@ -443,6 +460,12 @@ load_pls (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pab
static DB_playItem_t *
m3uplug_load (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname, int *pabort, int (*cb)(DB_playItem_t *it, void *data), void *user_data) {
+ char resolved_fname[PATH_MAX];
+ char *res = realpath (fname, resolved_fname);
+ if (res) {
+ fname = resolved_fname;
+ }
+
const char *ext = strrchr (fname, '.');
if (ext) {
ext++;