aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremias Stotter <jeremias@stotter.eu>2023-10-01 23:32:15 +0200
committerJeremias Stotter <jeremias@stotter.eu>2023-10-01 23:32:15 +0200
commitd77caf955f15e1f28c26b6657c1727ac138bf0ed (patch)
tree8eaf4f75e5847ee9020233c2259be282a9f9e3e2
parent0da079272c273871e3fa568bef3a6092d4339b3f (diff)
downloadnetwork-simulator-d77caf955f15e1f28c26b6657c1727ac138bf0ed.tar.gz
network-simulator-d77caf955f15e1f28c26b6657c1727ac138bf0ed.tar.bz2
network-simulator-d77caf955f15e1f28c26b6657c1727ac138bf0ed.zip
Use functions not deprecated in GTK 4.10
This will propably break building with anything below gtk 4.10 tho
-rw-r--r--Project.ede2
-rw-r--r--device.c2
-rw-r--r--files.c2
-rw-r--r--gui.c250
-rw-r--r--gui_device.c52
-rw-r--r--interface.c26
-rw-r--r--interface.h3
7 files changed, 186 insertions, 151 deletions
diff --git a/Project.ede b/Project.ede
index 20d326e..06b56ba 100644
--- a/Project.ede
+++ b/Project.ede
@@ -18,4 +18,4 @@
:object-name "netsim"
:makefile-type Makefile
:variables '(("LUA_VERSION" . "lua5.4") ("PKG_CONFIG" . "pkgconf") ("CFLAGS" . "-std=c99 $(shell $(PKG_CONFIG) --cflags $(LUA_VERSION) json-c gtk4)") ("LDFLAGS" . "$(shell $(PKG_CONFIG) --libs $(LUA_VERSION) json-c gtk4) -lm"))
- :configuration-variables '(("debug" ("CFLAGS" . "-O0 -Wno-deprecated-declarations -Wall -g")) ("release" ("CFLAGS" . "-O2"))))
+ :configuration-variables '(("debug" ("CFLAGS" . "-O0 -Wall -g")) ("release" ("CFLAGS" . "-O2"))))
diff --git a/device.c b/device.c
index 52771d5..759e229 100644
--- a/device.c
+++ b/device.c
@@ -225,7 +225,7 @@ struct device* new_device(struct device** start, char* device_name, struct dev_t
for(int i = 0; i < cur_template->slots; i++) {
char* int_template_name = cur_template->interfaces[i];
if(int_template_name) {
- new_interface(new_device, i, int_template_name);
+ new_interface_from_template_name(new_device, i, int_template_name);
}
}
diff --git a/files.c b/files.c
index c1c3b0b..3ab157e 100644
--- a/files.c
+++ b/files.c
@@ -221,7 +221,7 @@ int load_file(char* filename) {
json_object* int_name_json = json_object_array_get_idx(slots, j);
const char* int_name = json_object_get_string(int_name_json);
if(!int_name) continue;
- new_interface(load_dev, j, int_name);
+ new_interface_from_template_name(load_dev, j, int_name);
}
}
diff --git a/gui.c b/gui.c
index cfd88ef..dd901da 100644
--- a/gui.c
+++ b/gui.c
@@ -92,8 +92,10 @@ GtkWidget* text_button = NULL;
GtkWidget* rect_button = NULL;
GtkWidget* circle_button = NULL;
-// The packet list
-GtkListStore* packet_list = NULL;
+GListStore* file_filter_list = NULL;
+
+// The packet list store
+GListStore* packet_list_store = NULL;
enum {
PACKET_COL_DEV1,
PACKET_COL_DEV2,
@@ -437,16 +439,6 @@ void update_main_drawing_area(GtkDrawingArea* drawing_area,
cairo_surface_destroy(image_surface);
}
-// Remove a row from the list
-int free_packet_data(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer data) {
- void* free_data = NULL;
- gtk_tree_model_get(model, iter, PACKET_COL_DATA, &free_data, -1);
- free(free_data);
- gtk_list_store_remove(GTK_LIST_STORE(model), iter);
- return true;
-}
-
-
// Call after a packet drawing has completed to make the packet disapear from the gui
int clean_draw() {
// Free what we don't need
@@ -488,14 +480,13 @@ int clean_draw() {
void sidebar_select_current() {
if(!drawing_entries) return;
// Set the active element in the list to the current entry
- GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(packet_tree));
+ GtkSelectionModel* selection = gtk_column_view_get_model(GTK_COLUMN_VIEW(packet_tree));
// See how many indices we have
- gtk_tree_selection_unselect_all(selection);
+ gtk_selection_model_unselect_all(selection);
struct timestep_entry_ll* sel_entry = drawing_entries;
unsigned long sel_time = sel_entry->send_timestamp;
do {
- GtkTreePath* select_path = gtk_tree_path_new_from_indices(sel_entry->send_entry->gui_index, -1);
- gtk_tree_selection_select_path(selection, select_path);
+ gtk_selection_model_select_item(selection, sel_entry->send_entry->gui_index, true);
sel_entry = sel_entry->next;
} while(sel_entry && sel_entry->send_timestamp == sel_time);
}
@@ -530,7 +521,7 @@ void toggle_fast_mode(GtkWidget* self, gpointer data) {
NULL
);
fastmode = true;
- gtk_widget_hide(packet_tree_scroll);
+ gtk_widget_set_visible(packet_tree_scroll, false);
// Make the buttons inacetive
gtk_widget_set_sensitive(rewind_button, false);
gtk_widget_set_sensitive(play_button, false);
@@ -538,7 +529,7 @@ void toggle_fast_mode(GtkWidget* self, gpointer data) {
gtk_widget_set_sensitive(speed_slider, false);
// Clear the packet list
// Kinda shitty way to manually free this, maybe look into g_boxed someday?
- gtk_tree_model_foreach(GTK_TREE_MODEL(packet_list), free_packet_data, NULL);
+ g_list_store_remove_all(packet_list_store);
while(allocated_entries != drawing_entries && drawing_entries) {
free(drawing_entries->send_entry);
struct timestep_entry_ll* old_entry = drawing_entries;
@@ -1182,7 +1173,7 @@ void copy_selection_clipboard(struct device_selection* selection) {
for(int i = 0; i < dev->template->slots; i++) {
if(!dev->interfaces[i].parent_device)
continue;
- new_interface(new_dev, i, dev->interfaces[i].template->name);
+ new_interface(new_dev, i, dev->interfaces[i].template);
// Check in the originial how the neighbour device is called
if(dev->interfaces[i].connection) {
char* neigh_name;
@@ -1280,7 +1271,8 @@ int gui_send_info(struct interface* send_interface, const char* send_data, int d
if(!fastmode) {
if(!send_interface || !send_interface->connection) return -1;
struct connection* con = send_interface->connection;
- GtkTreeIter packet_iter;
+
+ /*GtkTreeIter packet_iter;
gtk_list_store_append(packet_list, &packet_iter);
// Copy the data to a buffer so that is stays persistent
char* data_buffer = malloc_or_abort(data_len);
@@ -1296,7 +1288,27 @@ int gui_send_info(struct interface* send_interface, const char* send_data, int d
con ? "Buffered" : "Disconected", -1);
// Get the index of the packet in the list
GtkTreePath* new_path = gtk_tree_model_get_path(GTK_TREE_MODEL(packet_list), &packet_iter);
- int index = *(gtk_tree_path_get_indices(new_path));
+ int index = *(gtk_tree_path_get_indices(new_path));*/
+
+ GObject* data_object = g_object_new(G_TYPE_OBJECT, NULL);
+ g_object_set_data(data_object, "Status", con ? "Buffered" : "Disconected");
+ g_object_set_data(data_object, "Device1", send_interface->parent_device->name);
+ g_object_set_data(data_object, "Device2", send_interface == send_interface->connection->interface1 ?
+ send_interface->connection->interface2->parent_device->name :
+ send_interface->connection->interface1->parent_device->name);
+ char* data_buffer = malloc_or_abort(data_len);
+ memcpy(data_buffer, send_data, data_len);
+ g_object_set_data_full(data_object, "Data", data_buffer, free);
+
+ int* size_buffer = malloc_or_abort(sizeof(int));
+ *size_buffer = data_len;
+ g_object_set_data_full(data_object, "Size", size_buffer, free);
+
+ g_object_set_data(data_object, "Type", (char*)type);
+
+ g_list_store_append(packet_list_store, data_object);
+ int index = g_list_model_get_n_items(G_LIST_MODEL(packet_list_store))-1;
+
return index;
} else return 0;
}
@@ -1306,10 +1318,9 @@ void gui_con_send(struct connection* con, int send_side) {
if(!fastmode) {
struct interface* inter = (send_side == 1) ? con->interface1 : con->interface2;
int gui_index = inter->start_queue->gui_index;
- GtkTreeIter set_iter;
- GtkTreePath* set_path = gtk_tree_path_new_from_indices(gui_index, -1);
- gtk_tree_model_get_iter(GTK_TREE_MODEL(packet_list), &set_iter, set_path);
- gtk_list_store_set(packet_list, &set_iter, PACKET_COL_STATUS, "Sent\0", -1);
+ GObject* data_object = g_list_model_get_object(G_LIST_MODEL(packet_list_store), gui_index);
+
+ g_object_set_data(data_object, "Status", "Sent");
}
}
@@ -1362,18 +1373,14 @@ void update_zoom(GtkWidget* self, const int* change) {
}
// === Called when a packet in the list is selected
-void packet_selected(GtkTreeView* self, GtkTreePath* path, GtkTreeViewColumn* column, gpointer user_data) {
- GtkTreeModel* select_model = gtk_tree_view_get_model(self);
- GtkTreeIter selected_iter;
- if(!gtk_tree_model_get_iter(select_model, &selected_iter, path)) {
- fprintf(stderr, "Couldn't get iter for packet\n");
- return;
- }
- int data_size = 0;
- char* data = NULL;
- char* data_type;
- gtk_tree_model_get(select_model, &selected_iter, PACKET_COL_SIZE, &data_size, PACKET_COL_DATA, &data, PACKET_COL_TYPE, &data_type, -1);
- show_packet_window(data_size, data, data_type);
+void packet_selected(GtkColumnView* self, int position, gpointer user_data) {
+ GObject* data_object = g_list_model_get_object(G_LIST_MODEL(packet_list_store)
+ , position);
+ char* data = g_object_get_data(data_object, "Data");
+ char* data_type = g_object_get_data(data_object, "Type");
+ int* data_size = g_object_get_data(data_object, "Size");
+
+ show_packet_window(*data_size, data, data_type);
}
void forward_timestep(GtkButton* self, gpointer user_data) {
@@ -1397,31 +1404,30 @@ void rewind_timestep(GtkButton* self, gpointer user_data) {
sidebar_select_current();
}
-char* file_chooser_get_path(GtkFileChooser* dialog) {
- GFile* selected_file = gtk_file_chooser_get_file(dialog);
- char* path = g_file_get_path(selected_file);
- g_object_unref(selected_file);
- return path;
-}
-
-void save_response(GtkDialog* dialog, int response_id) {
- if(response_id == 1) {
+void save_response(GObject* save_dialog, GAsyncResult* res, gpointer data) {
+ GFile* result_file = gtk_file_dialog_save_finish (GTK_FILE_DIALOG(save_dialog),
+ res,
+ NULL);
+ if(result_file) {
+ if(save_path)
+ g_free(save_path);
+ save_path = g_file_get_path(result_file);
+ g_object_unref(result_file);
+ g_object_unref(result_file);
if(save_path)
g_free(save_path);
//@todo: check for errors when saving
- save_path = file_chooser_get_path(GTK_FILE_CHOOSER(dialog));
save_file(save_path);
actions_since_save = 0;
+
}
- gtk_window_destroy(GTK_WINDOW(dialog));
gtk_widget_queue_draw(main_drawing_area);
}
void gui_save_as_action(GSimpleAction* self, GVariant* parameter, gpointer user_data) {
- GtkWidget* save_dialog = gtk_file_chooser_dialog_new("Save", GTK_WINDOW(window),
- GTK_FILE_CHOOSER_ACTION_SAVE, "Save", 1, NULL);
- g_signal_connect(save_dialog, "response", G_CALLBACK(save_response), NULL);
- gtk_widget_set_visible(save_dialog, true);
+
+ GtkFileDialog* save_dialog = gtk_file_dialog_new();
+ gtk_file_dialog_save(save_dialog, GTK_WINDOW(window), NULL, save_response, NULL);
}
void gui_save_action(GSimpleAction* self, GVariant* parameter, gpointer user_data) {
@@ -1433,8 +1439,11 @@ void gui_save_action(GSimpleAction* self, GVariant* parameter, gpointer user_dat
}
}
-void load_response(GtkDialog* dialog, int response_id) {
- if(response_id == 1) {
+void load_response(GObject* load_dialog, GAsyncResult* res, gpointer data) {
+ GFile* result_file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG(load_dialog),
+ res,
+ NULL);
+ if(result_file) {
// Free all devices
for(struct device* cur_dev = start_device; cur_dev;) {
struct device* free_dev = cur_dev;
@@ -1450,40 +1459,29 @@ void load_response(GtkDialog* dialog, int response_id) {
if(save_path)
g_free(save_path);
- save_path = file_chooser_get_path(GTK_FILE_CHOOSER(dialog));
+ save_path = g_file_get_path(result_file);
+ g_object_unref(result_file);
load_file(save_path);
}
- gtk_window_destroy(GTK_WINDOW(dialog));
gtk_widget_queue_draw(main_drawing_area);
}
void do_load() {
- GtkFileFilter* json_filter = gtk_file_filter_new();
- gtk_file_filter_add_suffix(json_filter, "json");
- GtkWidget* load_dialog = gtk_file_chooser_dialog_new("Load", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN,
- "Load", 1, NULL);
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(load_dialog), json_filter);
- g_signal_connect(load_dialog, "response", G_CALLBACK(load_response), NULL);
- gtk_widget_set_visible(load_dialog, true);
-
+ GtkFileDialog* load_dialog = gtk_file_dialog_new();
+ gtk_file_dialog_set_filters(load_dialog, G_LIST_MODEL(file_filter_list));
+ gtk_file_dialog_open(load_dialog, GTK_WINDOW(window), NULL, load_response, NULL);
}
-void load_yn_response(GtkDialog* self, int response_id, gpointer user_data) {
- if(response_id == GTK_RESPONSE_YES) {
- gtk_window_close(GTK_WINDOW(self));
+void load_yn_response(GObject* self, GAsyncResult* response_id, gpointer data) {
+ int result = gtk_alert_dialog_choose_finish(GTK_ALERT_DIALOG(self), response_id, NULL);
+ if(result == 0)
do_load();
- } else
- gtk_window_close(GTK_WINDOW(self));
}
void gui_load_action(GSimpleAction* self, GVariant* parameter, gpointer user_data) {
// File filter for only allowing json files
if(actions_since_save > 0) {
- // If there have been any changes ask if we should discard before loading
- GtkWidget* load_yn_dialog = gtk_message_dialog_new(GTK_WINDOW(window),
- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "You made changes since you last saved, do you really want to load another file and overwrite those changes?");
- g_signal_connect(G_OBJECT(load_yn_dialog), "response", G_CALLBACK(load_yn_response), NULL);
- gtk_widget_set_visible(load_yn_dialog, true);
+ GtkAlertDialog* load_yn_dialog = gtk_alert_dialog_new("You made changes since you last saved, do you really want to load another file and overwrite those changes?");
+ gtk_alert_dialog_set_buttons(load_yn_dialog, (const char*[]){"Yes", "No", NULL});
+ gtk_alert_dialog_set_cancel_button(load_yn_dialog, 1);
+ gtk_alert_dialog_choose(load_yn_dialog, GTK_WINDOW(window), NULL, load_yn_response, NULL);
} else
// No changes have been made, just load
do_load();
@@ -1500,26 +1498,19 @@ void gui_redo_action(GSimpleAction* self, GVariant* parameter, gpointer user_dat
}
// Ask the user if he wants to close without saving
-void close_response(GtkDialog* self, int response_id, gpointer user_data) {
- if(response_id == GTK_RESPONSE_YES) {
- actions_since_save = 0;
+void close_yn_response(GObject* self, GAsyncResult* response_id, gpointer data) {
+ int result = gtk_alert_dialog_choose_finish(GTK_ALERT_DIALOG(self), response_id, NULL);
+ if(result == 0)
// I don't know why this won't just accept a normal gtk_window_close...
gtk_application_remove_window(gtk_window_get_application(GTK_WINDOW(window)), GTK_WINDOW(window));
- }
- gtk_window_close(GTK_WINDOW(self));
}
bool gui_close(GtkWindow* window) {
if(actions_since_save) {
- GtkWidget* close_yn_dialog = gtk_message_dialog_new(
- window,
- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "You made changes since you last saved, do you really want to close the application?"
- );
- g_signal_connect(G_OBJECT(close_yn_dialog), "response", G_CALLBACK(close_response), NULL);
- gtk_widget_set_visible(close_yn_dialog, true);
+ GtkAlertDialog* close_yn_dialog = gtk_alert_dialog_new("You made changes since you last saved, do you really want to close the application?");
+ gtk_alert_dialog_set_buttons(close_yn_dialog, (const char*[]){"Yes", "No", NULL});
+ gtk_alert_dialog_set_cancel_button(close_yn_dialog, 1);
+ gtk_alert_dialog_choose(close_yn_dialog, GTK_WINDOW(window), NULL, close_yn_response, NULL);
return true;
}
return false;
@@ -1569,11 +1560,45 @@ void gui_toggle_interface_nums_action(GSimpleAction* action, GVariant* value, gp
gtk_widget_queue_draw(main_drawing_area);
}
+void packet_list_item_text_factory_bind(GtkSignalListItemFactory* self, GObject* object, gpointer user_data) {
+ gtk_list_item_set_child(GTK_LIST_ITEM(object), gtk_label_new(g_object_get_data(gtk_list_item_get_item(GTK_LIST_ITEM(object)), user_data)));
+}
+
+
+GtkListItemFactory* packet_list_string_data_factory_new(char* key) {
+ GtkListItemFactory* new_factory = gtk_signal_list_item_factory_new();
+ g_signal_connect(G_OBJECT(new_factory), "bind", G_CALLBACK(packet_list_item_text_factory_bind), key);
+ return new_factory;
+}
+
+void packet_list_item_int_factory_bind(GtkSignalListItemFactory* self, GObject* object, gpointer user_data) {
+ char text[16] = "";
+ sprintf(text, "%d", *(int*)g_object_get_data(gtk_list_item_get_item(GTK_LIST_ITEM(object)), user_data));
+ gtk_list_item_set_child(GTK_LIST_ITEM(object), gtk_label_new(text));
+}
+
+GtkListItemFactory* packet_list_int_data_factory_new(char* key) {
+ GtkListItemFactory* new_factory = gtk_signal_list_item_factory_new();
+ g_signal_connect(G_OBJECT(new_factory), "bind", G_CALLBACK(packet_list_item_int_factory_bind), key);
+ return new_factory;
+}
+
/*
* ====== GTK INITIALIZATION ======
*/
extern int sim_flag;
void activate_main_window(GtkApplication* app, gpointer user_data) {
+ // Initialize filter list
+ file_filter_list = g_list_store_new(GTK_TYPE_FILE_FILTER);
+ GtkFileFilter* json_filter = gtk_file_filter_new();
+ gtk_file_filter_add_suffix(json_filter, "json");
+ gtk_file_filter_set_name(json_filter, "JSON");
+ g_list_store_append(file_filter_list, json_filter);
+ GtkFileFilter* all_filter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(all_filter, "*");
+ gtk_file_filter_set_name(all_filter, "ALL");
+ g_list_store_append(file_filter_list, all_filter);
+
window = gtk_application_window_new(app);
// Needed for gui_packet
GtkCssProvider* css_prov = gtk_css_provider_new();
@@ -1779,36 +1804,27 @@ void activate_main_window(GtkApplication* app, gpointer user_data) {
gtk_stack_add_titled(GTK_STACK(sidebar_stack), connection_view_scroll, NULL, "Connections");
// === Packet details
- // Create a list
- packet_list = gtk_list_store_new(PACKET_N_COL, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING);
// Create a tree view
packet_tree_scroll = gtk_scrolled_window_new();
- packet_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(packet_list));
+ //packet_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(packet_list));
+ packet_list_store = g_list_store_new(G_TYPE_OBJECT);
+
+ GtkSingleSelection* packet_list_selection = gtk_single_selection_new(G_LIST_MODEL(packet_list_store));
+
+ packet_tree = gtk_column_view_new(GTK_SELECTION_MODEL(packet_list_selection));
+ gtk_column_view_set_single_click_activate(GTK_COLUMN_VIEW(packet_tree), true);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(packet_tree_scroll), packet_tree);
- GtkCellRenderer* text_render = gtk_cell_renderer_text_new();
- // Status
- GtkTreeViewColumn* status_col = gtk_tree_view_column_new_with_attributes("status", text_render, "text", PACKET_COL_STATUS, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(packet_tree), status_col);
- // Sending device column
- GtkTreeViewColumn* dev_col1 = gtk_tree_view_column_new_with_attributes("from device", text_render, "text", PACKET_COL_DEV1, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(packet_tree), dev_col1);
- // Receiving device column
- GtkTreeViewColumn* dev_col2 = gtk_tree_view_column_new_with_attributes("to device", text_render, "text", PACKET_COL_DEV2, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(packet_tree), dev_col2);
- // Type
- GtkTreeViewColumn* type_col = gtk_tree_view_column_new_with_attributes("protocol", text_render, "text", PACKET_COL_TYPE, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(packet_tree), type_col);
- // Size
- GtkTreeViewColumn* p_size_col = gtk_tree_view_column_new_with_attributes("size", text_render, "text", PACKET_COL_SIZE, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(packet_tree), p_size_col);
- // Make a packet window appear when clicked
- g_signal_connect(G_OBJECT(packet_tree), "row-activated", G_CALLBACK(packet_selected), NULL);
+ g_signal_connect(G_OBJECT(packet_tree), "activate", G_CALLBACK(packet_selected), NULL);
- // Activate on single click
- gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(packet_tree), true);
- // Allow only one packet to be activated
- GtkTreeSelection* packet_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(packet_tree));
- gtk_tree_selection_set_mode(packet_selection, GTK_SELECTION_MULTIPLE);
+ gtk_column_view_append_column(GTK_COLUMN_VIEW(packet_tree), gtk_column_view_column_new("Status", packet_list_string_data_factory_new("Status")));
+ gtk_column_view_append_column(GTK_COLUMN_VIEW(packet_tree), gtk_column_view_column_new("Device1", packet_list_string_data_factory_new("Device1")));
+ gtk_column_view_append_column(GTK_COLUMN_VIEW(packet_tree), gtk_column_view_column_new("Device2", packet_list_string_data_factory_new("Device2")));
+
+ gtk_column_view_append_column(GTK_COLUMN_VIEW(packet_tree), gtk_column_view_column_new("Protocols", packet_list_string_data_factory_new("Type")));
+
+ gtk_column_view_append_column(GTK_COLUMN_VIEW(packet_tree), gtk_column_view_column_new("Size", packet_list_int_data_factory_new("Size")));
+
+ // Set the data with g_object_set_data
gtk_paned_set_end_child(GTK_PANED(right_pane), packet_tree_scroll);
diff --git a/gui_device.c b/gui_device.c
index 32676be..f9b3799 100644
--- a/gui_device.c
+++ b/gui_device.c
@@ -42,21 +42,23 @@ void cmd_entry_changed(GtkEditable* self, gpointer user_data) {
gtk_entry_buffer_set_text(buffer, "", 0);
}
-void interface_selection_updated(GtkComboBox* self, gpointer user_data) {
+void interface_selection_updated(GtkDropDown* self, void* pspec, gpointer user_data) {
struct device* parent_device = (struct device*)user_data;
assert(parent_device);
// Get the slot index
- int* index = g_object_get_data(G_OBJECT(self), "index");
+ int* index = g_object_get_data(G_OBJECT(self), "int_index");
if(!index) {
fprintf(stderr, "Could not find the index for interface_selection_updated\n");
return;
}
- const char* new_template = gtk_combo_box_get_active_id(self);
- if(!strcmp(new_template, "none")) {
+ int template_index = gtk_drop_down_get_selected(GTK_DROP_DOWN(self));
+ if(template_index == 0) {
+ printf("DELETE INTERFACE\n");
// delete if the user selects none
delete_interface(&parent_device->interfaces[*index]);
} else {
- new_interface(parent_device, *index, gtk_combo_box_get_active_id(self) + 1);
+ template_index--;
+ new_interface(parent_device, *index, &interface_templates[template_index]);
}
actions_since_save++;
// Redraw the drawing area
@@ -106,7 +108,11 @@ bool entry_key_pressed(GtkEventControllerKey* self,
}
void help_clicked(GtkButton* self, gpointer user_data) {
- gtk_show_uri(NULL, (char*)user_data, GDK_CURRENT_TIME);
+ GFile* help_file = g_file_new_for_uri((char*)user_data);
+ GtkFileLauncher* help_file_launcher = gtk_file_launcher_new(help_file);
+ gtk_file_launcher_launch(help_file_launcher, NULL, NULL, NULL, NULL);
+ g_object_unref(help_file_launcher);
+ g_object_unref(help_file);
}
// Show the gui for the device dev
@@ -174,32 +180,34 @@ void show_device_window(struct device* dev) {
gtk_label_set_markup(GTK_LABEL(slot_label), slot_index);
gtk_box_append(GTK_BOX(interface_box), slot_label);
// Add the dropdown
- GtkWidget* slot_selection = gtk_combo_box_text_new();
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(slot_selection), "none", "None");
- // Add the index to the dropdown so we can set things later
- int* index = malloc_or_abort(sizeof(int));
- *index = i;
- g_object_set_data_full(G_OBJECT(slot_selection), "index", index, free);
+ char** interface_template_list = malloc_or_abort(interface_template_n + 2);
+ interface_template_list[0] = "None";
// Fill up the dropdown
for(int j = 0; j < interface_template_n; j++) {
// Prepend a _ to the name of the device so that a template can not take the id none by mistake
- char* template_id = malloc_or_abort(strlen(interface_templates[j].name) + 2);
- sprintf(template_id, "_%s", interface_templates[j].name);
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(slot_selection), template_id, interface_templates[j].name);
- free(template_id);
+ interface_template_list[j+1] = (char*)interface_templates[j].name;
}
+ interface_template_list[interface_template_n+1] = NULL;
+
+ GtkWidget* slot_selection = gtk_drop_down_new_from_strings((const char* const *)interface_template_list);
+ free(interface_template_list);
+
+ // Add the index to the dropdown so we can set things later
+ int* index = malloc_or_abort(sizeof(int));
+ *index = i;
+ g_object_set_data_full(G_OBJECT(slot_selection), "int_index", index, free);
+
// Set the interface that is in the slot
if(dev->interfaces[i].template) {
// The slot is used
- char* template_id = malloc_or_abort(strlen(dev->interfaces[i].template->name) + 2);
- sprintf(template_id, "_%s", dev->interfaces[i].template->name);
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(slot_selection), template_id);
- free(template_id);
+ int template_index = (dev->interfaces[i].template - interface_templates) / sizeof(struct interface_template) + 1;
+ gtk_drop_down_set_selected(GTK_DROP_DOWN(slot_selection), template_index);
+
} else {
// The slot is unused
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(slot_selection), "none");
+ gtk_drop_down_set_selected(GTK_DROP_DOWN(slot_selection), 0);
}
- g_signal_connect(G_OBJECT(slot_selection), "changed", G_CALLBACK(interface_selection_updated), dev);
+ g_signal_connect(G_OBJECT(slot_selection), "notify::selected", G_CALLBACK(interface_selection_updated), dev);
gtk_box_append(GTK_BOX(interface_box), slot_selection);
// Add the interface to the flow box
gtk_flow_box_append(GTK_FLOW_BOX(interfaces_box), interface_box);
diff --git a/interface.c b/interface.c
index a836025..79510c9 100644
--- a/interface.c
+++ b/interface.c
@@ -41,16 +41,10 @@ int delete_interface(struct interface* del_interface) {
return 0;
}
-int new_interface(struct device* parent_device, int slot_index, const char* template_name) {
- if(!parent_device) return -1;
- if(slot_index > parent_device->template->slots - 1) {
- fprintf(stderr, "Slot %d is not available in device %s with %d slots", slot_index, parent_device->name, parent_device->template->slots);
- return -1;
- }
-
+int new_interface_from_template_name(struct device* parent_device, int slot_index, const char* template_name) {
struct interface_template* cur_template = interface_templates;
bool template_found = false;
- for(int i = 0; i < interface_template_n; i++, cur_template += sizeof(struct interface_template)) {
+ for(int i = 0; i < interface_template_n; i++, cur_template = &interface_templates[i]) {
if(strcmp(cur_template->name, template_name) == 0) {
template_found = true;
break;
@@ -61,6 +55,22 @@ int new_interface(struct device* parent_device, int slot_index, const char* temp
fprintf(stderr, "Template %s was not found", template_name);
return -1;
}
+
+ return new_interface(parent_device, slot_index, cur_template);
+}
+
+int new_interface(struct device* parent_device, int slot_index, struct interface_template* cur_template) {
+ if(!parent_device) return -1;
+ if(slot_index > parent_device->template->slots - 1) {
+ fprintf(stderr, "Slot %d is not available in device %s with %d slots", slot_index, parent_device->name, parent_device->template->slots);
+ return -1;
+ }
+
+ if(!cur_template) {
+ fprintf(stderr, "Invalid interface template\n");
+ return -1;
+ }
+
// Remove any old interfaces still there
delete_interface(&parent_device->interfaces[slot_index]);
diff --git a/interface.h b/interface.h
index 4c60264..5a1c137 100644
--- a/interface.h
+++ b/interface.h
@@ -14,7 +14,8 @@
#ifndef NETSIM_INTERFACE
#define NETSIM_INTERFACE
#include "shared.h"
-int new_interface(struct device* parent_device, int slot_index, const char* template_name);
+int new_interface(struct device* parent_device, int slot_index, struct interface_template* cur_template);
+int new_interface_from_template_name(struct device* parent_device, int slot_index, const char* template_name);
int delete_interface(struct interface* del_interface);
int interface_send_frame(struct interface* send_interface, const char* frame, int frame_len, const char* frame_type);
int interface_recv_data(struct interface* recv_interface, const char* data, int data_length, const char* data_type);
Jeremias Stotters git repositories generated by CGIT