]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - aft.c
Implement afs events.
[paraslash.git] / aft.c
diff --git a/aft.c b/aft.c
index c63ab47106866dd5caa9e99062377c742b999a68..46d6729280cf8b90ce47c5d9194c2cace22c2f81 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -647,8 +647,11 @@ int open_and_update_audio_file(struct osl_row *aft_row, struct audio_file_data *
        save_afsi(&new_afsi, &afsi_obj); /* in-place update */
        if (afd->current_play_mode == PLAY_MODE_PLAYLIST)
                ret = playlist_update_audio_file(aft_row);
-       else
-               ret = mood_update_audio_file(aft_row, &afd->afsi);
+       else {
+               struct afsi_change_event_data aced = {.aft_row = aft_row,
+                       .old_afsi = &afd->afsi};
+               afs_event(AFSI_CHANGE, NULL, &aced);
+       }
        return ret;
 err:
        free(afd->afhi.chunk_table);
@@ -774,7 +777,6 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts,
                        sprintf(score_buf, "%li ", d->score);
        }
 
-       PARA_NOTICE_LOG("id: %s, %d\n", d->path, afsi->audio_format_id);
        if (opts->mode == LS_MODE_LONG) {
                para_printf(b,
                        "%s"    /* score */
@@ -1096,13 +1098,11 @@ static int com_ls_callback(const struct osl_object *query,
        time_t current_time;
 
 
-       PARA_NOTICE_LOG("%d patterns\n", opts->num_patterns);
        if (opts->num_patterns) {
                opts->patterns = para_malloc(opts->num_patterns * sizeof(char *));
                for (i = 0, p = pattern_start; i < opts->num_patterns; i++) {
                        opts->patterns[i] = p;
                        p += strlen(p) + 1;
-                       PARA_NOTICE_LOG("pattern %d: %s\n", i, opts->patterns[i]);
                }
        } else
                opts->patterns = NULL;
@@ -1114,10 +1114,8 @@ static int com_ls_callback(const struct osl_object *query,
        if (ret < 0)
                goto out;
        ret = opts->num_patterns? -E_NO_MATCH : 0;
-       if (!opts->num_matching_paths) {
-               PARA_NOTICE_LOG("no match, ret: %d\n", ret);
+       if (!opts->num_matching_paths)
                goto out;
-       }
        ret = sort_matching_paths(opts);
        if (ret < 0)
                goto out;
@@ -1137,7 +1135,6 @@ static int com_ls_callback(const struct osl_object *query,
        ret = 1;
 out:
        ls_output->data = b.buf;
-       PARA_NOTICE_LOG("ls_outoute.data: %p\n", ls_output->data);
        ls_output->size = b.size;
        free(opts->data);
        free(opts->data_ptr);
@@ -1388,7 +1385,7 @@ static int com_add_callback(const struct osl_object *query,
 {
        char *buf = query->data, *path;
        struct osl_row *pb, *aft_row;
-       const struct osl_row *hs;
+       struct osl_row *hs;
        struct osl_object objs[NUM_AFT_COLUMNS];
        HASH_TYPE *hash;
        char asc[2 * HASH_SIZE + 1];
@@ -1429,13 +1426,18 @@ static int com_add_callback(const struct osl_object *query,
                        pb = NULL;
                }
                /* file rename, update hs' path */
-               ret = osl_get_object(audio_file_table, hs, AFTCOL_PATH, &obj);
-               if (flags & ADD_FLAG_VERBOSE)
+               if (flags & ADD_FLAG_VERBOSE) {
+                       ret = osl_get_object(audio_file_table, hs,
+                               AFTCOL_PATH, &obj);
+                       if (ret < 0)
+                               goto out;
                        para_printf(&msg, "renamed from %s\n", (char *)obj.data);
+               }
                ret = osl_update_object(audio_file_table, hs, AFTCOL_PATH,
                        &objs[AFTCOL_PATH]);
                if (ret < 0)
                        goto out;
+               afs_event(AUDIO_FILE_RENAME, &msg, hs);
                if (!(flags & ADD_FLAG_FORCE))
                        goto out;
        }
@@ -1466,7 +1468,7 @@ static int com_add_callback(const struct osl_object *query,
                        goto out;
        }
        if (hs || pb) { /* (hs != NULL and pb != NULL) implies hs == pb */
-               const struct osl_row *row = pb? pb : hs;
+               struct osl_row *row = pb? pb : hs;
                /* update afhi and chunk_table */
                if (flags & ADD_FLAG_VERBOSE)
                        para_printf(&msg, "updating afhi and chunk table\n");
@@ -1476,6 +1478,9 @@ static int com_add_callback(const struct osl_object *query,
                        goto out;
                ret = osl_update_object(audio_file_table, row, AFTCOL_CHUNKS,
                        &objs[AFTCOL_CHUNKS]);
+               if (ret < 0)
+                       goto out;
+               afs_event(AFHI_CHANGE, &msg, row);
                goto out;
        }
        /* new entry, use default afsi */
@@ -1728,6 +1733,7 @@ static int touch_audio_file(__a_unused struct osl_table *table,
        struct afs_info old_afsi, new_afsi;
        int ret, no_options = tad->cto->num_played < 0 && tad->cto->last_played < 0 &&
                tad->cto->lyrics_id < 0 && tad->cto->image_id < 0;
+       struct afsi_change_event_data aced;
 
        ret = get_afsi_object_of_row(row, &obj);
        if (ret < 0) {
@@ -1760,9 +1766,9 @@ static int touch_audio_file(__a_unused struct osl_table *table,
                        new_afsi.last_played = tad->cto->last_played;
        }
        save_afsi(&new_afsi, &obj); /* in-place update */
-       ret = mood_update_audio_file(row, &old_afsi);
-       if (ret < 0)
-               para_printf(&tad->pb, "%s: %s\n", name, PARA_STRERROR(-ret));
+       aced.aft_row = row;
+       aced.old_afsi = &old_afsi;
+       afs_event(AFSI_CHANGE, &tad->pb, &aced);
        return 1;
 }
 
@@ -1880,9 +1886,7 @@ static int remove_audio_file(__a_unused struct osl_table *table,
 
        if (crd->flags & RM_FLAG_VERBOSE)
                para_printf(&crd->pb, "removing %s\n", name);
-       ret = mood_delete_audio_file(row);
-       if (ret < 0)
-               para_printf(&crd->pb, "%s: %s\n", name, PARA_STRERROR(-ret));
+       afs_event(AUDIO_FILE_REMOVE, &crd->pb, row);
        ret = osl_del_row(audio_file_table, row);
        if (ret < 0)
                para_printf(&crd->pb, "%s: %s\n", name, PARA_STRERROR(-ret));
@@ -1999,12 +2003,14 @@ static int copy_selector_info(__a_unused struct osl_table *table,
        struct cpsi_action_data *cad = data;
        struct osl_object target_afsi_obj;
        int ret;
-       struct afs_info target_afsi;
+       struct afs_info old_afsi, target_afsi;
+       struct afsi_change_event_data aced;
 
        ret = get_afsi_object_of_row(row, &target_afsi_obj);
        if (ret < 0)
                return ret;
        load_afsi(&target_afsi, &target_afsi_obj);
+       old_afsi = target_afsi;
        if (cad->flags & CPSI_FLAG_COPY_LYRICS_ID)
                target_afsi.lyrics_id = cad->source_afsi.lyrics_id;
        if (cad->flags & CPSI_FLAG_COPY_IMAGE_ID)
@@ -2019,6 +2025,9 @@ static int copy_selector_info(__a_unused struct osl_table *table,
        cad->num_copied++;
        if (cad->flags & CPSI_FLAG_VERBOSE)
                para_printf(&cad->pb, "copied afsi to %s\n", name);
+       aced.aft_row = row;
+       aced.old_afsi = &old_afsi;
+       afs_event(AFSI_CHANGE, &cad->pb, &aced);
        return 1;
 }
 
@@ -2222,10 +2231,45 @@ static int aft_create(const char *dir)
        return osl_create_table(&audio_file_table_desc);
 }
 
+static int clear_attribute(struct osl_row *row, void *data)
+{
+       struct rmatt_event_data *red = data;
+       struct afs_info afsi;
+       struct osl_object obj;
+       int ret = get_afsi_object_of_row(row, &obj);
+       uint64_t mask = ~(1ULL << red->bitnum);
+
+       if (ret < 0)
+               return ret;
+       ret = load_afsi(&afsi, &obj);
+       if (ret < 0)
+               return ret;
+       afsi.attributes &= mask;
+       save_afsi(&afsi, &obj);
+       return 1;
+}
+
+static int aft_event_handler(enum afs_events event, struct para_buffer *pb,
+               void *data)
+{
+       switch(event) {
+       case ATTRIBUTE_REMOVE: {
+               const struct rmatt_event_data *red = data;
+               para_printf(pb, "clearing attribute %s (bit %u) from all "
+                       "entries in the audio file table\n", red->name,
+                       red->bitnum);
+               return audio_file_loop(data, clear_attribute);
+               }
+       default:
+               return 1;
+       }
+}
+
 void aft_init(struct afs_table *t)
 {
        t->name = audio_file_table_desc.name;
        t->open = aft_open;
        t->close = aft_close;
        t->create = aft_create;
+       t->event_handler = aft_event_handler;
 }