///////////////////////////////////////////////////////////////////////////////// // // gui.cc is part of TestModbus-Server. // ///////////////////////////////////////////////////////////////////////////////// #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) #else #include /* close() */ #endif #include #include #include "gui.h" #include "modbus.h" #include "guivalues.h" #include "json.h" #include "mbsconfig.h" #include "config.h" extern GtkBuilder *_builder_; // work around for threads extern void addvar_displaywithvalues (gpointer data, GuiValue *v); ////////////////////////////////////////////////////////////////////////////////////////////////// // // call back functions // gboolean cb_window_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data) { // GtkBuilder *builder = (GtkBuilder *) data; cb_menu_save(widget, data); return FALSE; } void cb_window_show (GtkWidget *widget, gpointer data) { // GtkBuilder *builder = (GtkBuilder *) data; mbdata_show(widget, data); valdata_show(widget, data); g_timeout_add(100, Value_Loop, NULL); }; void cb_menu_new (GtkWidget *widget, gpointer data) { // GtkBuilder *builder = (GtkBuilder *) data; modbus.EnableAll(0); MBData_EnableAll(0); modbus.RequestsClear(); MBData_ReqReset (); Value_DelAll(); }; void cb_menu_open (GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWindow *window = GTK_WINDOW (gtk_builder_get_object (builder, "testmodbus-server")); GtkWidget *dialog; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; GtkFileFilter *filter; gint res; printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); dialog = gtk_file_chooser_dialog_new ("Open File", window, action, "_Cancel", GTK_RESPONSE_CANCEL, "_Open", GTK_RESPONSE_ACCEPT, NULL); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*.modbus"); gtk_file_filter_set_name(filter, "Test Modbus Config"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*.*"); gtk_file_filter_set_name(filter, "All Files"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); filename = gtk_file_chooser_get_filename (chooser); config.SetFilename(filename); g_free (filename); load_file(config.GetFilename().c_str()); } gtk_widget_destroy (dialog); }; void cb_menu_save (GtkWidget *widget, gpointer data) { // GtkBuilder *builder = (GtkBuilder *) data; if (config.GetFilename().length() == 0) cb_menu_saveas (widget, data); else { save_file(config.GetFilename().c_str()); } }; void cb_menu_saveas (GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWindow *window = GTK_WINDOW (gtk_builder_get_object (builder, "testmodbus-server")); GtkWidget *dialog; GtkFileChooser *chooser; GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE; GtkFileFilter *filter; gint res; dialog = gtk_file_chooser_dialog_new ("Save File", window, action, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL); chooser = GTK_FILE_CHOOSER (dialog); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*.modbus"); gtk_file_filter_set_name(filter, "Test Modbus Config"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*.*"); gtk_file_filter_set_name(filter, "All Files"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE); if (config.GetFilename().length () == 0) gtk_file_chooser_set_current_name (chooser, "noname.modbus"); else gtk_file_chooser_set_filename (chooser, config.GetFilename().c_str()); res = gtk_dialog_run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (chooser); config.SetFilename(filename); cb_menu_save (widget, data); g_free (filename); } gtk_widget_destroy (dialog); }; void cb_menu_quit (GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWindow *window = GTK_WINDOW (gtk_builder_get_object (builder, "testmodbus-server")); cb_menu_save(widget, data); gtk_window_close(window); }; // // try to set new port void cb_port_enter (GtkWidget *widget, gpointer data) { config.SetPort(atoi(gtk_entry_get_text (GTK_ENTRY(widget)))); gtk_entry_set_text(GTK_ENTRY(widget), std::to_string(config.GetPort()).c_str()); }; void cb_btn_start (GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWidget *portentry = GTK_WIDGET (gtk_builder_get_object (builder, "port_entry")); int port = atoi(gtk_entry_get_text(GTK_ENTRY(portentry))); if (modbus.isRunning()) { printf ("Stop Server\n"); modbus.Stop(); gtk_widget_set_sensitive(portentry, TRUE); gtk_button_set_label(GTK_BUTTON(widget), _("Start")); } else { printf ("Start Server (port: %d)\n", port); if (modbus.Start(port)) { gtk_button_set_label(GTK_BUTTON(widget),_("Stop")); gtk_widget_set_sensitive(portentry, FALSE); } usleep (250000); if (modbus.isRunning() == 0) { modbus.Stop(); displayerror("modbus server could not been started.\nSee console output for errors."); gtk_widget_set_sensitive(portentry, TRUE); gtk_button_set_label(GTK_BUTTON(widget), _("Start")); } } }; void addvar_displaywithvalues (gpointer data, GuiValue *v) { GtkBuilder *builder = (GtkBuilder *) data; GtkWidget *dlg = GTK_WIDGET (gtk_builder_get_object (builder, "addvar")); GtkWidget *reg = GTK_WIDGET (gtk_builder_get_object (builder, "adddlg_regnum")); GtkWidget *typeCB = GTK_WIDGET (gtk_builder_get_object (builder, "adddlg_type")); GtkWidget *simCB = GTK_WIDGET (gtk_builder_get_object (builder, "adddlg_simmulation")); GtkWidget *name = GTK_WIDGET (gtk_builder_get_object (builder, "adddlg_name")); GtkWidget *value = GTK_WIDGET (gtk_builder_get_object (builder, "adddlg_value")); GtkWidget *change = GTK_WIDGET (gtk_builder_get_object (builder, "adddlg_change")); GtkWidget *fc[4]; int i, fcnum; GtkWidget *type = gtk_bin_get_child(GTK_BIN(typeCB)); GtkWidget *sim = gtk_bin_get_child(GTK_BIN(simCB)); gtk_entry_set_text(GTK_ENTRY(name), "noname"); if (v == NULL) { fcnum = 1; } else if (v->fc < 1 || v-> fc > 4) fcnum = 1; else fcnum = v->fc; for (i = 0; i < 4; i++) { fc[i] = GTK_WIDGET (gtk_builder_get_object (builder, ((string)"adddlg_FC"+std::to_string(i+1)).c_str())); } if (v != NULL) { gtk_entry_set_text(GTK_ENTRY(name), v->name.c_str()); gtk_entry_set_text(GTK_ENTRY(value), v->value.c_str()); gtk_entry_set_text(GTK_ENTRY(type), v->type.c_str()); gtk_entry_set_text(GTK_ENTRY(sim), v->sim.c_str()); gtk_entry_set_text(GTK_ENTRY(reg), std::to_string(v->reg).c_str()); } gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fc[fcnum-1]), true); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(change), false); gint result = gtk_dialog_run(GTK_DIALOG(dlg)); if (result == GTK_RESPONSE_ACCEPT || result == GTK_RESPONSE_APPLY) { GuiValue vn; vn.value = gtk_entry_get_text(GTK_ENTRY(value)); vn.name = gtk_entry_get_text(GTK_ENTRY(name)); vn.type = gtk_entry_get_text(GTK_ENTRY(type)); vn.sim = gtk_entry_get_text(GTK_ENTRY(sim)); vn.reg = atoi (gtk_entry_get_text(GTK_ENTRY(reg))); for (i = 0; i < 4; i++) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fc[i]))) vn.fc = i+1; } Value_Set(&vn); // this will reset the vn.value with the reigsters.. if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(change)) == true) { uint16_t regvals[4]; int regstowrite = 1; vn.value = gtk_entry_get_text(GTK_ENTRY(value)); // load the from the entry if (Value_SetValue(vn.value, vn.type, vn.fc, ®stowrite, regvals)) { modbus.SetRegValue(vn.fc, vn.reg, regstowrite, (uint16_t*)regvals); } } } gtk_widget_hide(GTK_WIDGET(dlg)); }; void cb_btn_addvar (GtkWidget *widget, gpointer data) { addvar_displaywithvalues(data, NULL); }; void cb_btn_editvar (GtkWidget *widget, gpointer data) { GuiValue v; GtkTreeIter iter; GtkTreeModel *model; GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv")); gchar *v_name; gchar *v_fc; gchar *v_reg; gchar *v_type; gchar *v_sim; gchar *v_value; GtkTreeSelection *sel; sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(vars)); if (sel && gtk_tree_selection_get_selected(GTK_TREE_SELECTION(sel), &model, &iter)) { gtk_tree_model_get (model, &iter, VALDATA_COL_NAME, &v_name, VALDATA_COL_FC, &v_fc, VALDATA_COL_REGSTART, &v_reg, VALDATA_COL_TYPE, &v_type, VALDATA_COL_SIM, &v_sim, VALDATA_COL_VALUE, &v_value, -1); v.name = v_name; v.reg = atoi (v_reg); v.fc = atoi (v_fc); v.type = v_type; v.sim = v_sim; v.value = v_value; addvar_displaywithvalues(data, &v); } }; void cb_btn_delvar (GtkWidget *widget, gpointer data) { GtkTreeIter iter; GtkTreeModel *model; GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv")); gchar *v_name; GtkTreeSelection *sel; sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(vars)); if (sel && gtk_tree_selection_get_selected(GTK_TREE_SELECTION(sel), &model, &iter)) { gtk_tree_model_get (model, &iter, VALDATA_COL_NAME, &v_name, -1); Value_Del(v_name); g_free (v_name); } }; ////////////////////////////////////////////////////// // // update gui/add netdata side // gboolean cb_thread_network_data_add (gpointer data) { GtkWidget *textview = GTK_WIDGET(gtk_builder_get_object (_builder_, "network_text")); GtkTextBuffer *textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); GtkTextIter start, end; if (data) { struct modbus_data *mbdata = (struct modbus_data *)data; std::string text; char timetext[255]; GtkTextTag *tag_datetime; GtkTextTag *tag_data; GtkTextTag *tag_info; GtkTextTag *tag_modbus; time_t _tm =time(NULL); struct tm * curtime = localtime (&_tm); static int _once = 0; if (_once == 0) { _once = 1; tag_datetime = gtk_text_buffer_create_tag (textbuffer, "Date_Time", "foreground", "blue", "style", PANGO_WEIGHT_BOLD, "family", "Monospace", NULL); tag_data = gtk_text_buffer_create_tag (textbuffer, "Data", "foreground", "black", "style", PANGO_WEIGHT_NORMAL, "family", "Monospace", NULL); tag_info = gtk_text_buffer_create_tag (textbuffer, "Info", "foreground", "green", "style", PANGO_WEIGHT_THIN, "family", "Sans", NULL); tag_modbus = gtk_text_buffer_create_tag (textbuffer, "Modbus", "foreground", "black", "style", PANGO_WEIGHT_NORMAL, "family", "Sans", NULL); } strftime (timetext, 255, "%H:%M:%S", curtime); // // build hex dump // text = ""; for (int i = 0; i < mbdata->bufferlen; i++) { unsigned char c = mbdata->buffer[i]; char hexnum[] = "0123456789ABCDEF"; if (i == 0) text += " "; else if (i % 32 == 0) text += "\n "; else if (i % 4 == 0 && i > 0) text += " : "; else if (i % 2 == 0 && i > 0) text += ":"; // else text += " "; text += hexnum[c/16]; text += hexnum[c%16]; } gtk_text_buffer_get_start_iter(textbuffer, &start); gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "Data", NULL); // // first line // text = ""; if (mbdata->fc != 0) { text = text + "\n TransactionID: " + std::to_string(mbdata->transactionid); text = text + " ProtocolID: " + std::to_string(mbdata->protoolid); text = text + " Length: " + std::to_string(mbdata->length); text = text + "\n UnitID: " + std::to_string(mbdata->unitid); if (mbdata->fc < 10) text = text + " FC0" + std::to_string(mbdata->fc); else text = text + " FC" + std::to_string(mbdata->fc); if (mbdata->fc >= 5) { text = text + " WRITE "; if (mbdata->fc == 5) text = text + " Flag/Coil: " + std::to_string(mbdata->regstart); else if (mbdata->fc == 6) text = text + " Register: " + std::to_string(mbdata->regstart); else if (mbdata->fc == 15) text = text + " Flag/Coil: " + std::to_string(mbdata->regstart) + " Count: " + std::to_string (mbdata->regcnt); else if (mbdata->fc == 16) text = text + " Register: " + std::to_string(mbdata->regstart) + " Count: " + std::to_string (mbdata->regcnt); } else { text = text + " Registers: " + std::to_string (mbdata->regstart); text = text + " Bytes: " + std::to_string (mbdata->regcnt); } } text = text + "\n"; gtk_text_buffer_get_start_iter(textbuffer, &start); gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "Modbus", NULL); // // text =""; text += mbdata->hostname; if (mbdata->direction == 0) text = text + " RECV "; else text = text + " SEND "; text = text + std::to_string(mbdata->bufferlen) + " Bytes"; gtk_text_buffer_get_start_iter(textbuffer, &start); gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "Info", NULL); // // add date // text = "\n"; text += timetext; text += " "; gtk_text_buffer_get_start_iter(textbuffer, &start); gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "Date_Time", NULL); free (mbdata); } gtk_text_buffer_get_iter_at_line(textbuffer, &start, 2000); gtk_text_buffer_get_iter_at_line(textbuffer, &end, 2050); gtk_text_buffer_delete(textbuffer, &start, &end); return FALSE; }; ////////////////////////////////////////////////////// // // add a text line // gboolean cb_thread_network_text_add (gpointer data) { if (data) { std::string text; char timetext[255]; GtkWidget *textview = GTK_WIDGET(gtk_builder_get_object (_builder_, "network_text")); GtkTextBuffer *textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); GtkTextIter start, end; GtkTextTag *tag_datetime; GtkTextTag *tag_info; char *textprm = (char*) data; time_t _tm =time(NULL); struct tm * curtime = localtime (&_tm); static int _once = 0; if (_once == 0) { _once = 1; tag_datetime = gtk_text_buffer_create_tag (textbuffer, "Date_Time", "foreground", "blue", "style", PANGO_WEIGHT_BOLD, "family", "Monospace", NULL); tag_info = gtk_text_buffer_create_tag (textbuffer, "Connection", "foreground", "red", "style", PANGO_WEIGHT_BOLD, "family", "Sans", NULL); } strftime (timetext, 255, "%H:%M:%S", curtime); // // build hex dump // // // text =""; text += textprm; gtk_text_buffer_get_start_iter(textbuffer, &start); gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "Connection", NULL); // // add date // text = "\n"; text += timetext; text += " "; gtk_text_buffer_get_start_iter(textbuffer, &start); gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "Date_Time", NULL); free (textprm); } return FALSE; }; gboolean cb_thread_status (gpointer data) { string *s = (string *)data; GtkWidget *status = GTK_WIDGET(gtk_builder_get_object (_builder_, "status_lb")); gtk_label_set_text(GTK_LABEL(status), s->c_str()); return FALSE; } void cb_networkdata_show (GtkWidget *widget, gpointer data) { GtkWidget *textview = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(data), "network_text")); GtkTextBuffer *textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); printf ("*************************** \n"); }; void cb_addvar_close (GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWidget *dlg = GTK_WIDGET (gtk_builder_get_object (builder, "addvar")); printf ("%s\n", __FUNCTION__); gtk_dialog_response(GTK_DIALOG(dlg), GTK_RESPONSE_CANCEL); }; void displayerror (string error) { GtkWidget *dialog; GtkWidget *window = GTK_WIDGET (gtk_builder_get_object (_builder_, "testmodbus-server")); dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, error.c_str()); gtk_window_set_title(GTK_WINDOW(dialog), "Error"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void cb_addvar_addedit (GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWidget *dlg = GTK_WIDGET (gtk_builder_get_object (builder, "addvar")); GtkWidget *name = GTK_WIDGET (gtk_builder_get_object (builder, "adddlg_name")); GtkWidget *dialog; int result; if (Value_Exist((string)gtk_entry_get_text(GTK_ENTRY(name))) == true) { dialog = gtk_message_dialog_new(GTK_WINDOW(dlg), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "Are you sure you want to save?"); gtk_window_set_title(GTK_WINDOW(dialog), "Question"); result = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); if (result == GTK_RESPONSE_YES) gtk_dialog_response(GTK_DIALOG(dlg), GTK_RESPONSE_APPLY); } else { gtk_dialog_response(GTK_DIALOG(dlg), GTK_RESPONSE_APPLY); } return; }; void cb_menu_about(GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWidget *dlg = GTK_WIDGET (gtk_builder_get_object (builder, "dlgabout")); GtkWidget *label = GTK_WIDGET (gtk_builder_get_object (builder, "dlgabout_version")); gtk_label_set_text(GTK_LABEL(label), VERSION); gint result = gtk_dialog_run(GTK_DIALOG(dlg)); gtk_widget_hide(GTK_WIDGET(dlg)); return; } void cb_about_btnclose(GtkWidget *widget, gpointer data) { GtkBuilder *builder = (GtkBuilder *) data; GtkWidget *dlg = GTK_WIDGET (gtk_builder_get_object (builder, "dlgabout")); gtk_dialog_response(GTK_DIALOG(dlg), GTK_RESPONSE_CLOSE); } void cb_btn_enableall (GtkWidget *widget, gpointer data) { modbus.EnableAll(1); MBData_EnableAll(1); }; void cb_btn_disableall (GtkWidget *widget, gpointer data) { modbus.EnableAll(0); MBData_EnableAll(0); }; void cb_btn_clearreq (GtkWidget *widget, gpointer data) { modbus.RequestsClear(); MBData_ReqReset (); }; void cb_btn_enablevalues (GtkWidget *widget, gpointer data) { GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv")); GtkTreeIter iter; GtkTreeModel *model; gboolean result; gchar *v_name = NULL; gchar *v_reg = NULL; gchar *v_fc = NULL; gchar *v_type = NULL; int cnt = 0; model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars)); for (cnt = 0, result = gtk_tree_model_get_iter_first(model, &iter); result == TRUE; result = gtk_tree_model_iter_next(model, &iter), cnt++) { gtk_tree_model_get (model, &iter, VALDATA_COL_NAME, &v_name, VALDATA_COL_FC, &v_fc, VALDATA_COL_REGSTART, &v_reg, VALDATA_COL_TYPE, &v_type, -1); if (v_name == NULL) { if (v_fc != NULL) free (v_fc); if (v_reg != NULL) free (v_reg); if (v_type != NULL) free (v_type); break; } modbus.Enable(atoi(v_fc), atoi(v_reg), Value_GetSize(v_type), 1); MBData_Enable(atoi(v_fc), atoi(v_reg), Value_GetSize(v_type), 1); if (v_name != NULL) free (v_name); if (v_fc != NULL) free (v_fc); if (v_reg != NULL) free (v_reg); if (v_type != NULL) free (v_type); } }; void save_file(std::string fn) { GtkWidget *guiautovalue = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "conf_autoaddvalues")); GtkWidget *vars = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "vars_tv")); GtkTreeIter iter; GtkTreeModel *model; gboolean result; gchar *v_name = NULL; gchar *v_reg = NULL; gchar *v_fc = NULL; gchar *v_type = NULL; gchar *v_value = NULL; gchar *v_sim = NULL; int cnt = 0; JSONParse jp; JSONParse jv; JSONElement je; std::list values; FILE *f; jp.Clear(); values.clear(); je.Clear(); je.type = JSON_T_ARRAY; je.name = "values"; model = gtk_tree_view_get_model(GTK_TREE_VIEW(vars)); for (cnt = 0, result = gtk_tree_model_get_iter_first(model, &iter); result == TRUE; result = gtk_tree_model_iter_next(model, &iter), cnt++) { gtk_tree_model_get (model, &iter, VALDATA_COL_NAME, &v_name, VALDATA_COL_FC, &v_fc, VALDATA_COL_REGSTART, &v_reg, VALDATA_COL_TYPE, &v_type, VALDATA_COL_SIM, &v_sim, VALDATA_COL_VALUE, &v_value, -1); if (v_name == NULL) { if (v_fc != NULL) free (v_fc); if (v_reg != NULL) free (v_reg); if (v_type != NULL) free (v_type); if (v_sim != NULL) free (v_sim); if (v_value != NULL) free (v_value); break; } jv.Clear(); jv.AddObject("name", v_name); jv.AddObject("type", v_type); jv.AddObject("fc", v_fc); jv.AddObject("reg", v_reg); jv.AddObject("sim", v_sim); jv.AddObject("value", v_value); if(cnt != 0) je.value += ','; je.value += jv.ToString(); if (v_name != NULL) free (v_name); if (v_fc != NULL) free (v_fc); if (v_reg != NULL) free (v_reg); if (v_type != NULL) free (v_type); if (v_sim != NULL) free (v_sim); if (v_value != NULL) free (v_value); } jp.AddObject(je); jp.AddObject("port", config.GetPort()); cnt = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(guiautovalue)); jp.AddObject("auto_valueadd", cnt); f = fopen(fn.c_str(),"w"); if (f != NULL) { int err = fprintf (f, "%s\n",jp.ToString().c_str()); if (err < 0) printf ("error on writing: %s\n", strerror(errno)); fclose (f); } else printf ("error on open (write): %s\n", strerror(errno)); }; #define FILEBUFFER 0x10000 void load_file(std::string fn) { GtkWidget *guiautovalue = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "conf_autoaddvalues")); GtkWidget *guiport = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "port_entry")); GuiValue g; int autoadd = 0; modbus.EnableAll(0); MBData_EnableAll(0); modbus.RequestsClear(); MBData_ReqReset (); Value_DelAll(); std::string confdata; FILE *f; char buffer[FILEBUFFER]; int i; JSONParse json; JSONParse value; std::string temp; confdata = ""; f = fopen(fn.c_str(),"r"); if (f != NULL) { while (!feof(f)) { fgets (buffer, FILEBUFFER, f); confdata += buffer; } fclose (f); } else printf ("error on open (read): %s\n", strerror(errno)); json.Set(confdata); if (json.GetValueInt("port", &i)) { config.SetPort(i); gtk_entry_set_text(GTK_ENTRY(guiport), std::to_string(i).c_str()); } if (json.GetValueInt("auto_valueadd", &i)) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(guiautovalue), i); } for (i = 0; json.GetObjectIdx("values", i, &value); i++) { value.GetValue("name", &g.name); value.GetValue("type", &g.type); value.GetValue("sim", &g.sim); value.GetValue("value", &g.value); value.GetValue("fc", &temp); g.fc = atoi(temp.c_str()); value.GetValue("reg", &temp); g.reg = atoi(temp.c_str()); Value_Add(&g); } };