void dt_styles_update (const char *name, const char *newname, const char *newdescription, GList *filter, int imgid, GList *update) { sqlite3_stmt *stmt; int id=0; gchar *desc = NULL; id = dt_styles_get_id_by_name(name); if(id == 0) return; desc = dt_styles_get_description (name); if ((g_strcmp0(name, newname)) || (g_strcmp0(desc, newdescription))) { DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "UPDATE styles SET name=?1, description=?2 WHERE id=?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, newname, strlen (newname), SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, newdescription, strlen (newdescription), SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, id); sqlite3_step(stmt); sqlite3_finalize(stmt); } if (filter) { GList *list=filter; char tmp[64]; char include[2048] = {0}; g_strlcat(include,"num not in (", 2048); do { if(list!=g_list_first(list)) g_strlcat(include, ",", 2048); sprintf(tmp, "%d", GPOINTER_TO_INT(list->data)); g_strlcat(include, tmp, 2048); } while ((list=g_list_next(list))); g_strlcat(include,")", 2048); char query[4096]= {0}; sprintf(query,"delete from style_items where styleid=?1 and %s", include); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, id); sqlite3_step(stmt); sqlite3_finalize(stmt); } _dt_style_update_from_image(id,imgid,filter,update); _dt_style_cleanup_multi_instance(id); /* backup style to disk */ char stylesdir[1024]; dt_loc_get_user_config_dir(stylesdir, 1024); g_strlcat(stylesdir,"/styles",1024); g_mkdir_with_parents(stylesdir,00755); dt_styles_save_to_file(newname,stylesdir,TRUE); /* delete old accelerator and create a new one */ //TODO: should better use dt_accel_rename_global() to keep the old accel_key untouched, but it seems to be buggy if (g_strcmp0(name, newname)) { char tmp_accel[1024]; snprintf(tmp_accel, 1024, C_("accel", "styles/apply %s"), name); dt_accel_deregister_global(tmp_accel); gchar* tmp_name = g_strdup(newname); // freed by _destroy_style_shortcut_callback snprintf(tmp_accel, 1024, C_("accel", "styles/apply %s"), newname); dt_accel_register_global( tmp_accel, 0, 0); GClosure *closure; closure = g_cclosure_new( G_CALLBACK(_apply_style_shortcut_callback), tmp_name, _destroy_style_shortcut_callback); dt_accel_connect_global(tmp_accel, closure); } g_free(desc); }
void dt_styles_save_to_file(const char *style_name,const char *filedir,gboolean overwrite) { int rc = 0; char stylename[520]; sqlite3_stmt *stmt; snprintf(stylename,512,"%s/%s.dtstyle",filedir,style_name); // check if file exists if( g_file_test(stylename, G_FILE_TEST_EXISTS) == TRUE ) { if(overwrite) { if(unlink(stylename)) { dt_control_log(_("failed to overwrite style file for %s"),style_name); return; } } else { dt_control_log(_("style file for %s exists"),style_name); return; } } if ( !dt_styles_exists (style_name) ) return; xmlTextWriterPtr writer = xmlNewTextWriterFilename(stylename, 0); if (writer == NULL) { fprintf(stderr,"[dt_styles_save_to_file] Error creating the xml writer\n, path: %s", stylename); return; } rc = xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL); if (rc < 0) { fprintf(stderr,"[dt_styles_save_to_file]: Error on encoding setting"); return; } xmlTextWriterStartElement(writer, BAD_CAST "darktable_style"); xmlTextWriterWriteAttribute(writer, BAD_CAST "version", BAD_CAST "1.0"); xmlTextWriterStartElement(writer, BAD_CAST "info"); xmlTextWriterWriteFormatElement(writer, BAD_CAST "name", "%s", style_name); xmlTextWriterWriteFormatElement(writer, BAD_CAST "description", "%s", dt_styles_get_description(style_name)); xmlTextWriterEndElement(writer); xmlTextWriterStartElement(writer, BAD_CAST "style"); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select num,module,operation,op_params,enabled,blendop_params,blendop_version,multi_priority,multi_name from style_items where styleid =?1",-1, &stmt,NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt,1,dt_styles_get_id_by_name(style_name)); while (sqlite3_step (stmt) == SQLITE_ROW) { xmlTextWriterStartElement(writer, BAD_CAST "plugin"); xmlTextWriterWriteFormatElement(writer, BAD_CAST "num", "%d", sqlite3_column_int(stmt,0)); xmlTextWriterWriteFormatElement(writer, BAD_CAST "module", "%d", sqlite3_column_int(stmt,1)); xmlTextWriterWriteFormatElement(writer, BAD_CAST "operation", "%s", sqlite3_column_text(stmt,2)); xmlTextWriterWriteFormatElement(writer, BAD_CAST "op_params", "%s", dt_style_encode(stmt,3)); xmlTextWriterWriteFormatElement(writer, BAD_CAST "enabled", "%d", sqlite3_column_int(stmt,4)); xmlTextWriterWriteFormatElement(writer, BAD_CAST "blendop_params", "%s", dt_style_encode(stmt,5)); xmlTextWriterWriteFormatElement(writer, BAD_CAST "blendop_version", "%d", sqlite3_column_int(stmt,6)); xmlTextWriterWriteFormatElement(writer, BAD_CAST "multi_priority", "%d", sqlite3_column_int(stmt,7)); xmlTextWriterWriteFormatElement(writer, BAD_CAST "multi_name", "%s", sqlite3_column_text(stmt,8)); xmlTextWriterEndElement(writer); } sqlite3_finalize(stmt); xmlTextWriterEndDocument(writer); xmlFreeTextWriter(writer); }
static void _gui_styles_dialog_run (gboolean edit,const char *name,int imgid) { char title[512]; /* check if style exists */ if (name && (dt_styles_exists (name))==0) return; /* initialize the dialog */ dt_gui_styles_dialog_t *sd=(dt_gui_styles_dialog_t *)g_malloc (sizeof (dt_gui_styles_dialog_t)); sd->nameorig = g_strdup(name); if (edit) { sprintf (title,_("edit style")); g_strlcat (title, " \"", 512); g_strlcat(title, name, 512); g_strlcat(title, "\"", 512); sd->duplicate = gtk_check_button_new_with_label(_("duplicate style")); g_object_set (sd->duplicate, "tooltip-text", _("creates a duplicate of the style before applying changes"), (char *)NULL); } else { sd->imgid = imgid; sprintf (title,"%s",_("create new style")); sd->duplicate = NULL; } GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkDialog *dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (title, GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL)); GtkContainer *content_area = GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))); GtkWidget *alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); gtk_alignment_set_padding (GTK_ALIGNMENT(alignment), 5, 5, 5, 5); gtk_container_add (content_area, alignment); GtkBox *box = GTK_BOX (gtk_vbox_new(FALSE, 5)); gtk_container_add (GTK_CONTAINER (alignment), GTK_WIDGET (box)); sd->name = gtk_entry_new(); g_object_set (sd->name, "tooltip-text", _("enter a name for the new style"), (char *)NULL); sd->description = gtk_entry_new(); g_object_set (sd->description, "tooltip-text", _("enter a description for the new style, this description is searchable"), (char *)NULL); /*set values*/ if (edit) { /* name */ gtk_entry_set_text(GTK_ENTRY(sd->name), name); /* description */ gchar *desc = dt_styles_get_description (name); if (desc) { gtk_entry_set_text (GTK_ENTRY (sd->description),desc); g_free (desc); } } gtk_box_pack_start (box,sd->name,FALSE,FALSE,0); gtk_box_pack_start (box,sd->description,FALSE,FALSE,0); /* create the list of items */ sd->items = GTK_TREE_VIEW (gtk_tree_view_new ()); GtkListStore *liststore = gtk_list_store_new (DT_STYLE_ITEMS_NUM_COLS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_UINT); /* enabled */ GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new (); gtk_cell_renderer_toggle_set_activatable (GTK_CELL_RENDERER_TOGGLE (renderer), TRUE); g_object_set_data (G_OBJECT (renderer), "column", (gint *)DT_STYLE_ITEMS_COL_ENABLED); g_signal_connect (renderer, "toggled", G_CALLBACK (_gui_styles_item_toggled), sd); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (sd->items), -1, _("include"), renderer, "active", DT_STYLE_ITEMS_COL_ENABLED, NULL); /* name */ renderer = gtk_cell_renderer_text_new (); g_object_set_data (G_OBJECT (renderer), "column", (gint *)DT_STYLE_ITEMS_COL_NAME); g_object_set (renderer, "xalign", 0.0, NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (sd->items), -1, _("item"), renderer, "text", DT_STYLE_ITEMS_COL_NAME, NULL); gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(sd->items)), GTK_SELECTION_SINGLE); gtk_tree_view_set_model (GTK_TREE_VIEW(sd->items), GTK_TREE_MODEL(liststore)); gtk_box_pack_start (box,GTK_WIDGET (sd->items),TRUE,TRUE,0); if (edit) gtk_box_pack_start (box,GTK_WIDGET (sd->duplicate),FALSE,FALSE,0); /* fill list with history items */ GtkTreeIter iter; if (edit) { /* get history items for named style and populate the items list */ GList *items = dt_styles_get_item_list (name, FALSE); if (items) { do { dt_style_item_t *item=(dt_style_item_t *)items->data; gtk_list_store_append (GTK_LIST_STORE(liststore), &iter); gtk_list_store_set (GTK_LIST_STORE(liststore), &iter, DT_STYLE_ITEMS_COL_ENABLED, TRUE, DT_STYLE_ITEMS_COL_NAME, item->name, DT_STYLE_ITEMS_COL_NUM, (guint)item->num, -1); g_free(item->name); g_free(item); } while ((items=g_list_next(items))); } } else { GList *items = dt_history_get_items (imgid,FALSE); if (items) { do { dt_history_item_t *item = (dt_history_item_t *)items->data; /* lookup history item module */ gboolean enabled = TRUE; dt_iop_module_t *module=NULL; GList *modules = g_list_first(darktable.develop->iop); if (modules) { GList *result = g_list_find_custom (modules, item->op, _g_list_find_module_by_name); // (dt_iop_module_t *)(modules->data); if( result ) { module = (dt_iop_module_t *)(result->data); enabled = (module->flags() & IOP_FLAGS_INCLUDE_IN_STYLES)?TRUE:FALSE; } } gchar name[256]= {0}; g_snprintf(name,256,"%s",item->name); gtk_list_store_append (GTK_LIST_STORE(liststore), &iter); gtk_list_store_set (GTK_LIST_STORE(liststore), &iter, DT_STYLE_ITEMS_COL_ENABLED, enabled, DT_STYLE_ITEMS_COL_NAME, name, DT_STYLE_ITEMS_COL_NUM, (guint)item->num, -1); g_free(item->op); g_free(item->name); g_free(item); } while ((items=g_list_next(items))); } else { dt_control_log(_("can't create style out of unaltered image")); return; } } g_object_unref (liststore); /* run dialog */ if (edit) g_signal_connect (dialog, "response", G_CALLBACK (_gui_styles_edit_style_response), sd); else g_signal_connect (dialog, "response", G_CALLBACK (_gui_styles_new_style_response), sd); gtk_widget_show_all (GTK_WIDGET (dialog)); gtk_dialog_run(GTK_DIALOG(dialog)); }