Skip to content

Commit 2859931

Browse files
medialib: fix numeric sorting by track number (fixes #3287)
1 parent 04e20e7 commit 2859931

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

include/deadbeef/deadbeef.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,9 @@ typedef enum {
754754
// Allow faster metadata lookups, but without "override" support.
755755
// This is mostly suitable for medialib tree formatting.
756756
DDB_TF_CONTEXT_FAST_LOOKUP = 64,
757+
758+
// Force track numbers to have more zero padding, to make sense when sorting
759+
DDB_TF_FORCE_SORTABLE_TRACK_NUMBER = 128,
757760
#endif
758761
} ddb_tf_flags_t;
759762

plugins/medialib/medialibtree.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ _create_tf_tree(medialib_source_t *source, ml_tree_item_t *root, int selected, c
241241
if (needs_sort) {
242242
ddb_tf_context_t ctx = {
243243
._size = sizeof (ddb_tf_context_t),
244-
.flags = DDB_TF_CONTEXT_NO_DYNAMIC | DDB_TF_CONTEXT_NO_MUTEX_LOCK | DDB_TF_CONTEXT_FAST_LOOKUP,
244+
.flags = DDB_TF_CONTEXT_NO_DYNAMIC | DDB_TF_CONTEXT_NO_MUTEX_LOCK | DDB_TF_CONTEXT_FAST_LOOKUP | DDB_TF_FORCE_SORTABLE_TRACK_NUMBER,
245245
.plt = source->ml_playlist,
246246
.idx = -1,
247247
};
@@ -468,8 +468,19 @@ _create_sorted_folder_tree(ddb_playlist_t *plt, ml_tree_item_t *parent, int sele
468468
static void
469469
_create_folder_tree(medialib_source_t *source, ml_tree_item_t *root, const char *track_tf, int selected, int needs_sort) {
470470
if (needs_sort) {
471-
const char *sort_tf = "$directory_path(%path%)/[%album artist% - ]%album%/[%tracknumber%. ]%title%";
472-
deadbeef->plt_sort_v2(source->ml_playlist, PL_MAIN, -1, sort_tf, DDB_SORT_ASCENDING);
471+
ddb_tf_context_t ctx = {
472+
._size = sizeof (ddb_tf_context_t),
473+
.flags = DDB_TF_CONTEXT_NO_DYNAMIC | DDB_TF_CONTEXT_NO_MUTEX_LOCK | DDB_TF_CONTEXT_FAST_LOOKUP | DDB_TF_FORCE_SORTABLE_TRACK_NUMBER,
474+
.plt = source->ml_playlist,
475+
.idx = -1,
476+
};
477+
478+
const char *tf_sort = "$directory_path(%path%)/[%album artist% - ]%album%/[%tracknumber%. ]%title%";
479+
char *tf_bytecode = deadbeef->tf_compile(tf_sort);
480+
481+
deadbeef->plt_sort_v3(&ctx, tf_bytecode, PL_MAIN, -1, DDB_SORT_ASCENDING);
482+
483+
deadbeef->tf_free(tf_bytecode);
473484
}
474485

475486
char *track_tf_bc = deadbeef->tf_compile(track_tf);

src/tf.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,20 +2972,27 @@ _get_title_from_path(const char *path, const char **end) {
29722972
}
29732973

29742974
static int
2975-
_get_tracknumber_from_string(const char *v, char *out, int outlen) {
2975+
_get_tracknumber_from_string(const char *v, char *out, int outlen, int force_sortable) {
29762976
const char *p = v;
2977+
29772978
while (*p) {
29782979
if (!isdigit (*p)) {
29792980
break;
29802981
}
29812982
p++;
29822983
}
2983-
if (p > v && *p == 0 && p-v == 1) {
2984-
return snprintf_clip (out, outlen, "%02d", atoi(v));
2985-
}
2986-
else {
2987-
return -1;
2984+
2985+
if (p > v && *p == 0 ) {
2986+
if (force_sortable) {
2987+
return snprintf_clip (out, outlen, "%05d", atoi(v));
2988+
}
2989+
2990+
if (p - v == 1) {
2991+
return snprintf_clip (out, outlen, "%02d", atoi(v));
2992+
}
29882993
}
2994+
2995+
return -1;
29892996
}
29902997

29912998
/*
@@ -3122,7 +3129,7 @@ tf_eval_int (ddb_tf_context_t *ctx, const char *code, int size, char *out, int o
31223129
else if (!strcmp (name, "tracknumber")) {
31233130
const char *v = pl_find_meta_raw (it, "track");
31243131
if (v) {
3125-
int l = _get_tracknumber_from_string(v, out, outlen);
3132+
int l = _get_tracknumber_from_string(v, out, outlen, (ctx->flags & DDB_TF_FORCE_SORTABLE_TRACK_NUMBER) != 0);
31263133
if (l >= 0) {
31273134
out += l;
31283135
outlen -= l;
@@ -3824,7 +3831,7 @@ tf_eval_int (ddb_tf_context_t *ctx, const char *code, int size, char *out, int o
38243831
v = meta->value;
38253832
}
38263833
if (v) {
3827-
int l = _get_tracknumber_from_string(v, out, outlen);
3834+
int l = _get_tracknumber_from_string(v, out, outlen, (ctx->flags & DDB_TF_FORCE_SORTABLE_TRACK_NUMBER) != 0);
38283835
if (l >= 0) {
38293836
out += l;
38303837
outlen -= l;

0 commit comments

Comments
 (0)