commit c8c0a86f492c9423a6330f9deaa86a718ef08c54
parent f1996f51ba1744260bba4d7c3aa5d9a84c97236e
Author: Louis Burda <quent.burda@gmail.com>
Date: Thu, 16 Mar 2023 19:21:26 +0100
Allow saving reordered tracks in tag
Diffstat:
4 files changed, 96 insertions(+), 90 deletions(-)
diff --git a/src/cmd.c b/src/cmd.c
@@ -51,7 +51,15 @@ cmd_status_from_errno(int err)
bool
cmd_save(const char *args)
{
- data_save();
+ struct link *link;
+ struct tag *tag;
+
+ for (LIST_ITER(&tags, link)) {
+ tag = UPCAST(link, struct tag, link);
+ if (tag->index_dirty || tag->reordered)
+ tag_save_tracks(tag);
+ }
+
return true;
}
@@ -191,7 +199,7 @@ cmd_reindex(const char *name)
/* update each tag specified */
for (LIST_ITER(&matches, link)) {
ref = UPCAST(link, struct ref, link);
- if (!tracks_update(ref->data))
+ if (!tag_reindex_tracks(ref->data))
goto cleanup;
}
diff --git a/src/data.c b/src/data.c
@@ -30,8 +30,7 @@ static void tag_free(struct tag *tag);
static struct track *track_alloc(const char *path, const char *fname);
static void track_free(struct track *t);
-static void tracks_load(struct tag *tag);
-static void tracks_save(struct tag *tag);
+static bool tag_name_cmp(struct link *l1, struct link *l2);
struct tag *
tag_alloc(const char *path, const char *fname)
@@ -44,6 +43,7 @@ tag_alloc(const char *path, const char *fname)
tag->fpath = aprintf("%s/%s", path, fname);
tag->name = astrdup(fname);
tag->index_dirty = false;
+ tag->reordered = false;
tag->link = LINK_EMPTY;
tag->link_sel = LINK_EMPTY;
list_init(&tag->tracks);
@@ -88,62 +88,15 @@ track_free(struct track *t)
free(t);
}
-void
-tracks_load(struct tag *tag)
+bool
+tag_name_cmp(struct link *l1, struct link *l2)
{
- char linebuf[1024];
- char *index_path;
- FILE *file;
-
- index_path = aprintf("%s/index", tag->fpath);
- file = fopen(index_path, "r");
- if (file == NULL) {
- index_update(tag); /* create index */
- file = fopen(index_path, "r");
- if (!file) ERROR(SYSTEM, "fopen %s", tag->name);
- }
+ struct tag *t1, *t2;
- while (fgets(linebuf, sizeof(linebuf), file)) {
- if (!*linebuf) continue;
- if (linebuf[strlen(linebuf) - 1] == '\n')
- linebuf[strlen(linebuf) - 1] = '\0';
- track_add(tag, linebuf);
- }
+ t1 = LINK_UPCAST(l1, struct tag, link);
+ t2 = LINK_UPCAST(l2, struct tag, link);
- tag->index_dirty = false;
-
- fclose(file);
- free(index_path);
-}
-
-void
-tracks_save(struct tag *tag)
-{
- struct track *track;
- struct link *link;
- char *index_path;
- FILE *file;
-
- /* write playlist back to index file */
-
- index_path = aprintf("%s/index", tag->fpath);
- file = fopen(index_path, "w+");
- if (!file) {
- WARNX(SYSTEM, "Failed to write to index file: %s",
- index_path);
- free(index_path);
- return;
- }
-
- for (LIST_ITER(&tag->tracks, link)) {
- track = UPCAST(link, struct track, link_tt);
- fprintf(file, "%s\n", track->name);
- }
-
- tag->index_dirty = false;
-
- fclose(file);
- free(index_path);
+ return strcmp(t1->name, t2->name) <= 0;
}
bool
@@ -259,55 +212,85 @@ move_file(const char *src, const char *dst)
}
void
-index_update(struct tag *tag)
+tag_clear_tracks(struct tag *tag)
{
- struct dirent *ent;
+ struct link *link;
+ struct track *track;
+
+ while (!list_empty(&tag->tracks)) {
+ link = list_pop_front(&tag->tracks);
+ track = UPCAST(link, struct track, link_tt);
+ track_rm(track, false);
+ }
+}
+
+void
+tag_load_tracks(struct tag *tag)
+{
+ char linebuf[1024];
char *index_path;
FILE *file;
- DIR *dir;
-
- dir = opendir(tag->fpath);
- if (!dir) ERROR(SYSTEM, "opendir %s", tag->fpath);
index_path = aprintf("%s/index", tag->fpath);
+ file = fopen(index_path, "r");
+ if (file == NULL) {
+ tag_reindex_tracks(tag);
+ return;
+ }
- file = fopen(index_path, "w+");
- if (!file) ERROR(SYSTEM, "fopen %s/index", tag->name);
+ while (fgets(linebuf, sizeof(linebuf), file)) {
+ if (!*linebuf) continue;
+ if (linebuf[strlen(linebuf) - 1] == '\n')
+ linebuf[strlen(linebuf) - 1] = '\0';
+ track_add(tag, linebuf);
+ }
+
+ tag->index_dirty = false;
+
+ fclose(file);
free(index_path);
+}
- while ((ent = readdir(dir))) {
- if (!strcmp(ent->d_name, "."))
- continue;
- if (!strcmp(ent->d_name, ".."))
- continue;
+void
+tag_save_tracks(struct tag *tag)
+{
+ struct track *track;
+ struct link *link;
+ char *index_path;
+ FILE *file;
- /* skip files without extension */
- if (!strchr(ent->d_name + 1, '.'))
- continue;
+ /* write playlist back to index file */
- fprintf(file, "%s\n", ent->d_name);
+ index_path = aprintf("%s/index", tag->fpath);
+ file = fopen(index_path, "w+");
+ if (!file) {
+ WARNX(SYSTEM, "Failed to write to index file: %s",
+ index_path);
+ free(index_path);
+ return;
}
- closedir(dir);
+ for (LIST_ITER(&tag->tracks, link)) {
+ track = UPCAST(link, struct track, link_tt);
+ fprintf(file, "%s\n", track->name);
+ }
+
+ tag->index_dirty = false;
+
fclose(file);
+ free(index_path);
}
bool
-tracks_update(struct tag *tag)
+tag_reindex_tracks(struct tag *tag)
{
- struct link *link;
- struct track *track;
struct dirent *ent;
DIR *dir;
dir = opendir(tag->fpath);
if (!dir) return false;
- while (!list_empty(&tag->tracks)) {
- link = list_pop_front(&tag->tracks);
- track = UPCAST(link, struct track, link_tt);
- track_rm(track, false);
- }
+ tag_clear_tracks(tag);
while ((ent = readdir(dir))) {
if (!strcmp(ent->d_name, "."))
@@ -690,11 +673,13 @@ data_load(void)
tag = tag_add(ent->d_name);
if (!strcmp(tag->name, "trash"))
trash_tag = tag;
- tracks_load(tag);
+ tag_load_tracks(tag);
}
free(path);
}
+ list_sort(&tags, false, tag_name_cmp);
+
playlist_outdated = true;
closedir(dir);
@@ -709,7 +694,7 @@ data_save(void)
for (LIST_ITER(&tags, link)) {
tag = UPCAST(link, struct tag, link);
if (tag->index_dirty)
- tracks_save(tag);
+ tag_save_tracks(tag);
}
release_lock(datadir);
diff --git a/src/data.h b/src/data.h
@@ -8,6 +8,7 @@ struct tag {
char *name, *fpath;
struct list tracks;
bool index_dirty;
+ bool reordered;
struct link link; /* tags list */
struct link link_sel; /* selected tags list */
@@ -33,9 +34,6 @@ bool copy_file(const char *dst, const char *src);
bool dup_file(const char *dst, const char *src);
bool move_file(const char *dst, const char *src);
-void index_update(struct tag *tag);
-bool tracks_update(struct tag *tag);
-
struct track *tracks_vis_track(struct link *link);
void playlist_clear(void);
@@ -47,6 +45,11 @@ struct tag *tag_find(const char *name);
bool tag_rm(struct tag *tag, bool sync_fs);
bool tag_rename(struct tag *tag, const char *name);
+void tag_clear_tracks(struct tag *tag);
+void tag_load_tracks(struct tag *tag);
+void tag_save_tracks(struct tag *tag);
+bool tag_reindex_tracks(struct tag *tag);
+
struct track *track_add(struct tag *tag, const char *fname);
bool track_rm(struct track *track, bool sync_fs);
bool track_rename(struct track *track, const char *name);
diff --git a/src/tui.c b/src/tui.c
@@ -660,7 +660,17 @@ track_vis_name_cmp(struct link *l1, struct link *l2)
void
sort_visible_tracks(void)
{
+ struct link *link;
+ struct tag *tag;
+
list_sort(tracks_vis, false, track_vis_name_cmp);
+
+ if (!track_show_playlist) {
+ link = list_at(&tags, tag_nav.sel);
+ if (!link) return;
+ tag = LINK_UPCAST(link, struct tag, link);
+ tag->reordered = true;
+ }
}
bool
@@ -1160,13 +1170,13 @@ reindex_selected_tags(void)
if (track_show_playlist) {
for (LIST_ITER(&tags_sel, link)) {
tag = UPCAST(link, struct tag, link_sel);
- tracks_update(tag);
+ tag_reindex_tracks(tag);
}
} else {
link = list_at(&tags, tag_nav.sel);
if (!link) return;
tag = UPCAST(link, struct tag, link);
- tracks_update(tag);
+ tag_reindex_tracks(tag);
}
if (playing_tag) {