From 15350decd4777a2d9a9e21175b7d62307f235434 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Sun, 27 Dec 2009 00:41:46 +0200 Subject: [PATCH] studio "save as". Fixes #13 --- daemon/cmd.h | 2 +- daemon/cmd_save_studio.c | 70 +++++++++++++++++++++++++++++++++++++----------- daemon/studio.c | 37 ++++++++++++++++++++++--- gui/gui.glade | 16 +++++++++++ gui/main.c | 23 ++++++++++++++++ proxies/studio_proxy.c | 5 ++++ proxies/studio_proxy.h | 1 + 7 files changed, 134 insertions(+), 20 deletions(-) diff --git a/daemon/cmd.h b/daemon/cmd.h index a4c847a5..02e2784a 100644 --- a/daemon/cmd.h +++ b/daemon/cmd.h @@ -64,7 +64,7 @@ void * ladish_command_new(size_t size); bool ladish_command_new_studio(void * call_ptr, struct ladish_cqueue * queue_ptr, const char * studio_name); bool ladish_command_load_studio(void * call_ptr, struct ladish_cqueue * queue_ptr, const char * studio_name); bool ladish_command_rename_studio(void * call_ptr, struct ladish_cqueue * queue_ptr, const char * studio_name); -bool ladish_command_save_studio(void * call_ptr, struct ladish_cqueue * queue_ptr); +bool ladish_command_save_studio(void * call_ptr, struct ladish_cqueue * queue_ptr, const char * new_studio_name); bool ladish_command_start_studio(void * call_ptr, struct ladish_cqueue * queue_ptr); bool ladish_command_stop_studio(void * call_ptr, struct ladish_cqueue * queue_ptr); bool ladish_command_unload_studio(void * call_ptr, struct ladish_cqueue * queue_ptr); diff --git a/daemon/cmd_save_studio.c b/daemon/cmd_save_studio.c index 77bf2011..c02700d8 100644 --- a/daemon/cmd_save_studio.c +++ b/daemon/cmd_save_studio.c @@ -655,7 +655,13 @@ exit: #undef indent #undef fd -#define cmd_ptr ((struct ladish_command *)command_context) +struct ladish_command_save_studio +{ + struct ladish_command command; + char * studio_name; +}; + +#define cmd_ptr ((struct ladish_command_save_studio *)command_context) static bool run(void * command_context) { @@ -671,7 +677,7 @@ static bool run(void * command_context) struct stat st; struct save_context save_context; - ASSERT(cmd_ptr->state == LADISH_COMMAND_STATE_PENDING); + ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING); time(×tamp); ctime_r(×tamp, timestamp_str); @@ -685,7 +691,7 @@ static bool run(void * command_context) goto exit; } - if (!studio_compose_filename(g_studio.name, &filename, &bak_filename)) + if (!studio_compose_filename(cmd_ptr->studio_name, &filename, &bak_filename)) { log_error("failed to compose studio filename"); goto exit; @@ -704,16 +710,21 @@ static bool run(void * command_context) /* saving already persisted studio that was not renamed */ old_filename = filename; } - else + else if (strcmp(cmd_ptr->studio_name, g_studio.name) == 0) { /* saving renamed studio */ old_filename = g_studio.filename; g_studio.filename = filename; } + else + { + /* saving studio copy (save as) */ + old_filename = filename; + g_studio.filename = filename; + } filename = NULL; ASSERT(g_studio.filename != NULL); - ASSERT(g_studio.filename != old_filename); ASSERT(g_studio.filename != bak_filename); if (bak_filename != NULL) @@ -894,10 +905,18 @@ static bool run(void * command_context) g_studio.persisted = true; g_studio.automatic = false; /* even if it was automatic, it is not anymore because it is saved */ - cmd_ptr->state = LADISH_COMMAND_STATE_DONE; + cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE; ret = true; + if (old_filename == g_studio.filename && strcmp(g_studio.name, cmd_ptr->studio_name) != 0) + { + free(g_studio.name); + g_studio.name = cmd_ptr->studio_name; + cmd_ptr->studio_name = NULL; + emit_studio_renamed(); + } + close: close(fd); @@ -905,7 +924,8 @@ rename_back: if (!ret && bak_filename != NULL) { /* save failed - try to rename the backup file back */ - if (rename(bak_filename, g_studio.filename) != 0) + ASSERT(old_filename != NULL); + if (rename(bak_filename, old_filename) != 0) { log_error("rename(%s, %s) failed: %d (%s)", bak_filename, g_studio.filename, errno, strerror(errno)); } @@ -917,7 +937,7 @@ free_filenames: free(bak_filename); } - if (old_filename != NULL) + if (old_filename != NULL && old_filename != g_studio.filename) { free(old_filename); } @@ -929,22 +949,41 @@ exit: return ret; } +static void destructor(void * command_context) +{ + log_info("save studio command destructor"); + if (cmd_ptr->studio_name != NULL) + { + free(cmd_ptr->studio_name); + } +} + #undef cmd_ptr -bool ladish_command_save_studio(void * call_ptr, struct ladish_cqueue * queue_ptr) +bool ladish_command_save_studio(void * call_ptr, struct ladish_cqueue * queue_ptr, const char * new_studio_name) { - struct ladish_command * cmd_ptr; + struct ladish_command_save_studio * cmd_ptr; + char * studio_name_dup; - cmd_ptr = ladish_command_new(sizeof(struct ladish_command)); + studio_name_dup = strdup(new_studio_name); + if (studio_name_dup == NULL) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "strdup('%s') failed.", new_studio_name); + goto fail; + } + + cmd_ptr = ladish_command_new(sizeof(struct ladish_command_save_studio)); if (cmd_ptr == NULL) { log_error("ladish_command_new() failed."); - goto fail; + goto fail_free_name; } - cmd_ptr->run = run; + cmd_ptr->command.run = run; + cmd_ptr->command.destructor = destructor; + cmd_ptr->studio_name = studio_name_dup; - if (!ladish_cqueue_add_command(queue_ptr, cmd_ptr)) + if (!ladish_cqueue_add_command(queue_ptr, &cmd_ptr->command)) { lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "ladish_cqueue_add_command() failed."); goto fail_destroy_command; @@ -954,7 +993,8 @@ bool ladish_command_save_studio(void * call_ptr, struct ladish_cqueue * queue_pt fail_destroy_command: free(cmd_ptr); - +fail_free_name: + free(studio_name_dup); fail: return false; } diff --git a/daemon/studio.c b/daemon/studio.c index 0fe240d5..3ecc2b1c 100644 --- a/daemon/studio.c +++ b/daemon/studio.c @@ -603,10 +603,8 @@ static void ladish_rename_studio(struct dbus_method_call * call_ptr) emit_studio_renamed(); } -static void ladish_save_studio(struct dbus_method_call * call_ptr) +static bool ladish_save_studio_internal(struct dbus_method_call * call_ptr, const char * new_studio_name) { - log_info("Save studio request"); - /* FIXME: this is wrong place to do such check because state before command execution needs to be checked and not state before command is submited, but doing it here will show error to @@ -616,10 +614,36 @@ static void ladish_save_studio(struct dbus_method_call * call_ptr) if (!studio_is_started()) { lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "Cannot save not-started studio"); + return false; + } + + return ladish_command_save_studio(call_ptr, &g_studio.cmd_queue, new_studio_name); +} + +static void ladish_save_studio(struct dbus_method_call * call_ptr) +{ + log_info("Save studio request"); + + if (ladish_save_studio_internal(call_ptr, g_studio.name)) + { + method_return_new_void(call_ptr); + } +} + +static void ladish_save_as_studio(struct dbus_method_call * call_ptr) +{ + const char * new_name; + + log_info("SaveAs studio request"); + + if (!dbus_message_get_args(call_ptr->message, &g_dbus_error, DBUS_TYPE_STRING, &new_name, DBUS_TYPE_INVALID)) + { + lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message); + dbus_error_free(&g_dbus_error); return; } - if (ladish_command_save_studio(call_ptr, &g_studio.cmd_queue)) + if (ladish_save_studio_internal(call_ptr, new_name)) { method_return_new_void(call_ptr); } @@ -679,6 +703,10 @@ METHOD_ARGS_END METHOD_ARGS_BEGIN(Save, "Save studio") METHOD_ARGS_END +METHOD_ARGS_BEGIN(SaveAs, "SaveAs studio") + METHOD_ARG_DESCRIBE_IN("studio_name", "s", "New name") +METHOD_ARGS_END + METHOD_ARGS_BEGIN(Unload, "Unload studio") METHOD_ARGS_END @@ -696,6 +724,7 @@ METHODS_BEGIN METHOD_DESCRIBE(GetName, ladish_get_studio_name) METHOD_DESCRIBE(Rename, ladish_rename_studio) METHOD_DESCRIBE(Save, ladish_save_studio) + METHOD_DESCRIBE(SaveAs, ladish_save_as_studio) METHOD_DESCRIBE(Unload, ladish_unload_studio) METHOD_DESCRIBE(Start, ladish_start_studio) METHOD_DESCRIBE(Stop, ladish_stop_studio) diff --git a/gui/gui.glade b/gui/gui.glade index f16b1d95..c331582f 100644 --- a/gui/gui.glade +++ b/gui/gui.glade @@ -129,6 +129,22 @@ + + True + False + _Save Studio As... + True + + + + True + gtk-save + 1 + + + + + True False diff --git a/gui/main.c b/gui/main.c index 9c29eaa5..11e22828 100644 --- a/gui/main.c +++ b/gui/main.c @@ -55,6 +55,7 @@ GtkWidget * g_menu_item_new_studio; GtkWidget * g_menu_item_start_studio; GtkWidget * g_menu_item_stop_studio; GtkWidget * g_menu_item_save_studio; +GtkWidget * g_menu_item_save_as_studio; GtkWidget * g_menu_item_unload_studio; GtkWidget * g_menu_item_rename_studio; GtkWidget * g_menu_item_create_room; @@ -211,6 +212,8 @@ bool name_dialog(const char * title, const char * object, const char * old_name, bool ok; GtkEntry * entry = GTK_ENTRY(get_glade_widget("name_entry")); + gtk_window_set_title(GTK_WINDOW(g_app_dialog), title); + gtk_widget_show(g_name_dialog); gtk_label_set_text(GTK_LABEL(get_glade_widget("name_label")), object); @@ -433,6 +436,23 @@ static void save_studio(void) } } +static void save_as_studio(void) +{ + char * new_name; + + log_info("save as studio request"); + + if (name_dialog("Save studio as", "Studio name", "", &new_name)) + { + if (!studio_proxy_save_as(new_name)) + { + error_message_box("Saving of studio failed, please inspect logs."); + } + + free(new_name); + } +} + static void new_studio(void) { char * new_name; @@ -520,6 +540,7 @@ bool studio_state_changed(char ** name_ptr_ptr) gtk_widget_set_sensitive(g_menu_item_start_studio, g_studio_state == STUDIO_STATE_STOPPED); gtk_widget_set_sensitive(g_menu_item_stop_studio, g_studio_state == STUDIO_STATE_STARTED); gtk_widget_set_sensitive(g_menu_item_save_studio, g_studio_state == STUDIO_STATE_STARTED); + gtk_widget_set_sensitive(g_menu_item_save_as_studio, g_studio_state == STUDIO_STATE_STARTED); gtk_widget_set_sensitive(g_menu_item_unload_studio, g_studio_state != STUDIO_STATE_UNLOADED); gtk_widget_set_sensitive(g_menu_item_rename_studio, g_studio_state == STUDIO_STATE_STOPPED || g_studio_state == STUDIO_STATE_STARTED); gtk_widget_set_sensitive(g_menu_item_start_app, g_studio_state == STUDIO_STATE_STOPPED || g_studio_state == STUDIO_STATE_STARTED); @@ -886,6 +907,7 @@ int main(int argc, char** argv) g_menu_item_start_studio = get_glade_widget("menu_item_start_studio"); g_menu_item_stop_studio = get_glade_widget("menu_item_stop_studio"); g_menu_item_save_studio = get_glade_widget("menu_item_save_studio"); + g_menu_item_save_as_studio = get_glade_widget("menu_item_save_as_studio"); g_menu_item_unload_studio = get_glade_widget("menu_item_unload_studio"); g_menu_item_rename_studio = get_glade_widget("menu_item_rename_studio"); g_menu_item_create_room = get_glade_widget("menu_item_create_room"); @@ -940,6 +962,7 @@ int main(int argc, char** argv) g_signal_connect(G_OBJECT(g_menu_item_stop_studio), "activate", G_CALLBACK(stop_studio), NULL); g_signal_connect(G_OBJECT(g_menu_item_unload_studio), "activate", G_CALLBACK(unload_studio), NULL); g_signal_connect(G_OBJECT(g_menu_item_save_studio), "activate", G_CALLBACK(save_studio), NULL); + g_signal_connect(G_OBJECT(g_menu_item_save_as_studio), "activate", G_CALLBACK(save_as_studio), NULL); g_signal_connect(G_OBJECT(g_menu_item_rename_studio), "activate", G_CALLBACK(rename_studio), NULL); g_signal_connect(G_OBJECT(g_menu_item_daemon_exit), "activate", G_CALLBACK(daemon_exit), NULL); g_signal_connect(G_OBJECT(g_menu_item_jack_configure), "activate", G_CALLBACK(jack_configure), NULL); diff --git a/proxies/studio_proxy.c b/proxies/studio_proxy.c index 76f81090..72bdbb4d 100644 --- a/proxies/studio_proxy.c +++ b/proxies/studio_proxy.c @@ -155,6 +155,11 @@ bool studio_proxy_save(void) return dbus_call(SERVICE_NAME, STUDIO_OBJECT_PATH, IFACE_STUDIO, "Save", "", ""); } +bool studio_proxy_save_as(const char * name) +{ + return dbus_call(SERVICE_NAME, STUDIO_OBJECT_PATH, IFACE_STUDIO, "SaveAs", "s", &name, ""); +} + bool studio_proxy_unload(void) { return dbus_call(SERVICE_NAME, STUDIO_OBJECT_PATH, IFACE_STUDIO, "Unload", "", ""); diff --git a/proxies/studio_proxy.h b/proxies/studio_proxy.h index e87ae5bd..d3748958 100644 --- a/proxies/studio_proxy.h +++ b/proxies/studio_proxy.h @@ -35,6 +35,7 @@ void studio_proxy_uninit(void); bool studio_proxy_get_name(char ** name); bool studio_proxy_rename(const char * name); bool studio_proxy_save(void); +bool studio_proxy_save_as(const char * name); bool studio_proxy_unload(void); void studio_proxy_set_renamed_callback(void (* callback)(const char * new_studio_name)); -- 2.11.4.GIT