You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
775 lines
23 KiB
775 lines
23 KiB
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// gui.cc is part of TestModbus-Server.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
|
|
#else
|
|
#include <unistd.h> /* close() */
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <list>
|
|
#include "gui.h"
|
|
#include "modbussrv.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;
|
|
modbussrv.EnableAll(0);
|
|
MBData_EnableAll(0);
|
|
modbussrv.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 (modbussrv.isRunning()) {
|
|
printf ("Stop Server\n");
|
|
modbussrv.Stop();
|
|
gtk_widget_set_sensitive(portentry, TRUE);
|
|
gtk_button_set_label(GTK_BUTTON(widget), _("Start"));
|
|
}
|
|
else {
|
|
printf ("Start Server (port: %d)\n", port);
|
|
if (modbussrv.Start(port)) {
|
|
gtk_button_set_label(GTK_BUTTON(widget),_("Stop"));
|
|
gtk_widget_set_sensitive(portentry, FALSE);
|
|
}
|
|
usleep (250000);
|
|
if (modbussrv.isRunning() == 0) {
|
|
modbussrv.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)) {
|
|
modbussrv.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 + " Cnt: " + 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);
|
|
|
|
//
|
|
//
|
|
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) {
|
|
modbussrv.EnableAll(1);
|
|
MBData_EnableAll(1);
|
|
};
|
|
|
|
|
|
void cb_btn_disableall (GtkWidget *widget, gpointer data) {
|
|
modbussrv.EnableAll(0);
|
|
MBData_EnableAll(0);
|
|
};
|
|
|
|
|
|
void cb_btn_clearreq (GtkWidget *widget, gpointer data) {
|
|
modbussrv.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;
|
|
}
|
|
|
|
modbussrv.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<JSONElement> 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;
|
|
|
|
|
|
modbussrv.EnableAll(0);
|
|
MBData_EnableAll(0);
|
|
modbussrv.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);
|
|
}
|
|
};
|
|
|
|
|