diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index e91a4e23..95befdf3 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -1113,6 +1113,24 @@ dvr_entry_class_start_set(void *o, const void *v) return dvr_entry_class_time_set(de, &de->de_start, *(time_t *)v); } +static uint32_t +dvr_entry_class_start_opts(void *o) +{ + dvr_entry_t *de = (dvr_entry_t *)o; + if (de && !dvr_entry_is_editable(de)) + return PO_RDONLY; + return 0; +} + +static uint32_t +dvr_entry_class_start_extra_opts(void *o) +{ + dvr_entry_t *de = (dvr_entry_t *)o; + if (de && !dvr_entry_is_editable(de)) + return PO_RDONLY | PO_DURATION; + return PO_DURATION; +} + static int dvr_entry_class_start_extra_set(void *o, const void *v) { @@ -1191,6 +1209,8 @@ dvr_entry_class_channel_set(void *o, const void *v) if (ch == NULL) { if (de->de_channel) { LIST_REMOVE(de, de_channel_link); + free(de->de_channel_name); + de->de_channel_name = NULL; de->de_channel = NULL; return 1; } @@ -1643,6 +1663,7 @@ const idclass_t dvr_entry_class = { .name = "Start Time", .set = dvr_entry_class_start_set, .off = offsetof(dvr_entry_t, de_start), + .get_opts = dvr_entry_class_start_opts, }, { .type = PT_TIME, @@ -1651,6 +1672,7 @@ const idclass_t dvr_entry_class = { .off = offsetof(dvr_entry_t, de_start_extra), .set = dvr_entry_class_start_extra_set, .list = dvr_entry_class_extra_list, + .get_opts = dvr_entry_class_start_extra_opts, .opts = PO_DURATION, }, { @@ -1696,6 +1718,7 @@ const idclass_t dvr_entry_class = { .set = dvr_entry_class_channel_set, .get = dvr_entry_class_channel_get, .list = dvr_entry_class_channel_list, + .get_opts = dvr_entry_class_start_opts, }, { .type = PT_STR, @@ -1766,6 +1789,7 @@ const idclass_t dvr_entry_class = { .set = dvr_entry_class_config_name_set, .get = dvr_entry_class_config_name_get, .list = dvr_entry_class_config_name_list, + .get_opts = dvr_entry_class_start_opts, }, { .type = PT_STR, @@ -2146,6 +2170,30 @@ dvr_config_class_enabled_set(void *o, const void *v) return 0; } +static uint32_t +dvr_config_class_enabled_opts(void *o) +{ + dvr_config_t *cfg = (dvr_config_t *)o; + if (cfg && dvr_config_is_default(cfg) && dvr_config_is_valid(cfg)) + return PO_RDONLY; + return 0; +} + +static int +dvr_config_class_name_set(void *o, const void *v) +{ + dvr_config_t *cfg = (dvr_config_t *)o; + if (dvr_config_is_default(cfg) && dvr_config_is_valid(cfg)) + return 0; + if (strcmp(cfg->dvr_config_name ?: "", v ?: "")) { + if (dvr_config_is_valid(cfg) && (v == NULL || *(char *)v == '\0')) + return 0; + free(cfg->dvr_config_name); + cfg->dvr_config_name = strdup(v); + return 1; + } + return 0; +} static const char * dvr_config_class_get_title (idnode_t *self) @@ -2228,14 +2276,17 @@ const idclass_t dvr_config_class = { .off = offsetof(dvr_config_t, dvr_enabled), .def.i = 1, .group = 1, + .get_opts = dvr_config_class_enabled_opts, }, { .type = PT_STR, .id = "name", .name = "Config Name", + .set = dvr_config_class_name_set, .off = offsetof(dvr_config_t, dvr_config_name), .def.s = "! New config", .group = 1, + .get_opts = dvr_config_class_enabled_opts, }, { .type = PT_INT, diff --git a/src/prop.c b/src/prop.c index 05066adf..bb748c30 100644 --- a/src/prop.c +++ b/src/prop.c @@ -94,7 +94,8 @@ prop_write_values if (!f) continue; /* Ignore */ - if(p->opts & optmask) continue; + u32 = p->get_opts ? p->get_opts(obj) : p->opts; + if(u32 & optmask) continue; /* Sanity check */ assert(p->set || p->off); @@ -228,10 +229,12 @@ prop_read_value { const char *s; const void *val = obj + p->off; + uint32_t u32; char buf[16]; /* Ignore */ - if (p->opts & optmask) return; + u32 = p->get_opts ? p->get_opts(obj) : p->opts; + if (u32 & optmask) return; if (p->type == PT_NONE) return; /* Sanity check */ @@ -323,6 +326,7 @@ prop_serialize_value { htsmsg_field_t *f; char buf[16]; + uint32_t opts; /* Remove parent */ // TODO: this is really horrible and inefficient! @@ -393,19 +397,20 @@ prop_serialize_value } /* Options */ - if (pl->opts & PO_RDONLY) + opts = pl->get_opts ? pl->get_opts(obj) : pl->opts; + if (opts & PO_RDONLY) htsmsg_add_bool(m, "rdonly", 1); - if (pl->opts & PO_NOSAVE) + if (opts & PO_NOSAVE) htsmsg_add_bool(m, "nosave", 1); - if (pl->opts & PO_WRONCE) + if (opts & PO_WRONCE) htsmsg_add_bool(m, "wronce", 1); - if (pl->opts & PO_ADVANCED) + if (opts & PO_ADVANCED) htsmsg_add_bool(m, "advanced", 1); - if (pl->opts & PO_HIDDEN) + if (opts & PO_HIDDEN) htsmsg_add_bool(m, "hidden", 1); - if (pl->opts & PO_PASSWORD) + if (opts & PO_PASSWORD) htsmsg_add_bool(m, "password", 1); - if (pl->opts & PO_DURATION) + if (opts & PO_DURATION) htsmsg_add_bool(m, "duration", 1); /* Enum list */ diff --git a/src/prop.h b/src/prop.h index 803543a9..babcb54f 100644 --- a/src/prop.h +++ b/src/prop.h @@ -86,6 +86,9 @@ typedef struct property { time_t tm; // PT_TIME } def; + /* Extended options */ + uint32_t (*get_opts) (void *ptr); + /* Notification callback */ void (*notify) (void *ptr);