RFC - edit nick names dialog added to gtk-gui.c
Amit Chaudhuri
amit.k.chaudhuri at gmail.com
Fri Jan 11 08:02:34 PST 2013
Hi.
Attached is a diff which partially implements the edit nick names
functionality. It leans heavily on the stand alone prototype Lubomir
worked up and a bunch of discussions with Dirk. On advice, I've resisted
the urge to move this to separate files.
I believe it works for editing but for delete it only printf's my intended
hooks to complete.
The recent introduction of device_info cut across the previous code
slightly. With the move to separate files for the newly named struct I had
to add a function to device.[ch] to return the head of list. Is this a
complete no-no?
All comments etc. gratefully received. As it is my first contribution
direct to list, please shout if things are wrong / awkward. I think I'm ok
on whitespace and sign-offs...
Regards,
Amit
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.hohndel.org/pipermail/subsurface/attachments/20130111/a26d6bef/attachment.html>
-------------- next part --------------
diff --git a/device.c b/device.c
index 39f742a..5b74422 100644
--- a/device.c
+++ b/device.c
@@ -4,6 +4,11 @@
static struct device_info *device_info_list;
+struct device_info *head_of_device_info_list(void)
+{
+ return device_info_list;
+}
+
static int match_device_info(struct device_info *entry, const char *model, uint32_t deviceid)
{
return !strcmp(entry->model, model) && entry->deviceid == deviceid;
diff --git a/device.h b/device.h
index 896bcb8..31e4a74 100644
--- a/device.h
+++ b/device.h
@@ -17,5 +17,6 @@ extern struct device_info *get_different_device_info(const char *model, uint32_t
extern struct device_info *create_device_info(const char *model, uint32_t deviceid);
extern struct device_info *remove_device_info(const char *model, uint32_t deviceid);
extern void clear_device_saved_status(void);
+extern struct device_info *head_of_device_info_list(void);
#endif
diff --git a/gtk-gui.c b/gtk-gui.c
index 4dcffbd..cc87974 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -1,4 +1,4 @@
-/* gtk-gui.c */
+ /* gtk-gui.c */
/* gtk UI implementation */
/* creates the window and overall layout
* divelist, dive info, equipment and printing are handled in their own source files
@@ -36,6 +36,38 @@ const char *divelist_font;
const char *default_filename;
char *nicknamestring;
+static struct device_info *nicknamelist;
+static struct device_info *holdnicknames = NULL;
+
+static void clear_hold_nicknames(void){
+
+ if( !holdnicknames )
+ holdnicknames = (struct device_info *) malloc(sizeof( struct device_info ));
+
+ holdnicknames->model = NULL;
+ holdnicknames->deviceid = 0;
+ holdnicknames->serial_nr = NULL;
+ holdnicknames->firmware = NULL;
+ holdnicknames->nickname = NULL;
+ holdnicknames->next = NULL;
+ holdnicknames->saved = FALSE;
+
+}
+
+
+
+void dump_nickname_list_entry(struct device_info *nnl){
+
+ printf("\n");
+ printf("Address of entry is %p root is at %p\n", nnl, nicknamelist);
+ printf("Model = %s\n",nnl->model);
+ printf("Device = %x\n", nnl->deviceid);
+ printf("Nickname = %s\n", nnl->nickname);
+ printf("Address of next entry is %p\n",nnl->next);
+ printf("\n");
+
+}
+
static GtkWidget *dive_profile;
static const char *default_dive_computer_vendor;
@@ -1129,6 +1161,225 @@ static void next_dc(GtkWidget *w, gpointer data)
repaint_dive();
}
+
+/* list columns for nickname edit treeview */
+enum {
+ NE_MODEL,
+ NE_ID_STR,
+ NE_NICKNAME,
+ NE_NCOL
+};
+
+
+/* delete a selection of nicknames */
+static void edit_dc_delete_rows(GtkTreeView *view)
+{
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GtkTreeRowReference *ref;
+ GtkTreeSelection *selection;
+ GList *selected_rows, *list, *row_references = NULL;
+ guint len;
+
+ selection = gtk_tree_view_get_selection(view);
+ /* this isn't compatible bellow gtk 2.2, so should be done manually using 'for_each' ! */
+ selected_rows = gtk_tree_selection_get_selected_rows(selection, &model);
+
+ for (list = selected_rows; list; list = g_list_next(list)) {
+ path = list->data;
+ ref = gtk_tree_row_reference_new(model, path);
+ row_references = g_list_append(row_references, ref);
+ }
+ len = g_list_length(row_references);
+ if (len == 0){
+ //printf("Warn about empty selection?\n");
+ return;
+ }
+
+ clear_hold_nicknames();
+ printf("Call Dirk's delete function soon - after populating the holdnicknames structure with the list to delete\n");
+ for (list = row_references; list; list = g_list_next(list)) {
+ printf("Call to populate goes here...\n");
+ path = gtk_tree_row_reference_get_path((GtkTreeRowReference *)(list->data));
+ gtk_tree_model_get_iter(model, &iter, path);
+ gtk_list_store_remove(GTK_LIST_STORE (model), &iter);
+ gtk_tree_path_free(path);
+ }
+ printf("Commit delete here\n");
+ g_list_free(selected_rows);
+ g_list_free(row_references);
+ g_list_free(list);
+
+ if (gtk_tree_model_get_iter_first(model, &iter))
+ gtk_tree_selection_select_iter(selection, &iter);
+}
+
+/* repopulate the edited nickname cell of a DC */
+static void cell_edited_cb(GtkCellRendererText *cell,
+ gchar *path,
+ gchar *new_text,
+ gpointer store)
+{
+ /* iterator */
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path);
+
+ /* display new text */
+ gtk_list_store_set(GTK_LIST_STORE(store), &iter, NE_NICKNAME, new_text, -1);
+
+ /* params for remember_dc */
+ const char *model;
+ const char *deviceid_string;
+ uint32_t deviceid;
+ // and new_text
+ gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
+ NE_MODEL, &model,
+ NE_ID_STR, &deviceid_string,
+ -1);
+ printf("Model: %s\n", model);
+ printf("Dev str: %s\n", deviceid_string);
+
+ /* extract deviceid */
+ int matched = -1;
+ matched = sscanf(deviceid_string, "0x%x8", &deviceid);
+ printf("Number of items matched equals = %d (hopefully 1) & ", matched);
+ printf("device id is %u\n", deviceid);
+
+ /* remember pending commit */
+ if(matched == 1){
+ clear_hold_nicknames();
+ holdnicknames->nickname = strdup(new_text);
+ holdnicknames->model = strdup(model);
+ holdnicknames->deviceid = deviceid;
+ holdnicknames->next = NULL;
+ holdnicknames->saved = FALSE;
+ }
+
+
+ /* tidy up */
+ // Did gtk malloc anything for me?
+
+}
+
+/* show the dialog to edit dc nicknames */
+static void edit_dc_nicknames(GtkWidget *w, gpointer data)
+{
+ const gint SUB_RESPONSE_DELETE = 1;
+ const gchar *C_INACTIVE = "#e8e8ee", *C_ACTIVE = "#ffffff"; // light grey & white RGB hex colour codes
+ GtkWidget *dialog, *confirm, *view, *scroll, *vbox;
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ gint res = -1;
+
+ clear_hold_nicknames(); /* protect against user calling dialog, not editing and calling ok */
+
+ dialog = gtk_dialog_new_with_buttons( _("Edit Dive Computer Nicknames"),
+ GTK_WINDOW(main_window),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_DELETE,
+ SUB_RESPONSE_DELETE,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_APPLY,
+ GTK_RESPONSE_APPLY,
+ NULL);
+ gtk_widget_set_size_request(dialog, 500, 400);
+
+ scroll = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+
+ view = gtk_tree_view_new();
+ store = gtk_list_store_new(NE_NCOL, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ model = GTK_TREE_MODEL(store);
+
+ /* columns */
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "background", C_INACTIVE, NULL);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
+ -1, "Model", renderer, "text", NE_MODEL, NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "background", C_INACTIVE, NULL);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
+ -1, "Device Id", renderer, "text", NE_ID_STR, NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "background", C_INACTIVE, NULL);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
+ -1, "Nickname", renderer, "text", NE_NICKNAME, NULL);
+ g_object_set(renderer, "editable", TRUE, NULL);
+ g_object_set(renderer, "background", C_ACTIVE, NULL);
+ g_signal_connect(renderer, "edited", G_CALLBACK(cell_edited_cb), store);
+
+ gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
+ g_object_unref(model);
+
+ /* populate list store */
+ char id_string[11] = {0}; /* this buffer holds the id as hex string */
+
+ struct device_info * nnl = head_of_device_info_list();
+ while( nnl ) {
+
+ dump_nickname_list_entry(nnl);
+
+ sprintf(&id_string[0], "%#08x", nnl->deviceid);
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ NE_MODEL, nnl->model,
+ NE_ID_STR, id_string,
+ NE_NICKNAME, nnl->nickname,
+ -1);
+ nnl = nnl->next;
+ }
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+ gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE);
+ //gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE);
+
+ vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ gtk_container_add(GTK_CONTAINER(scroll), view);
+ gtk_container_add(GTK_CONTAINER(vbox),
+ gtk_label_new(_("Edit a DC's nickname by double-clicking inside the 'Nickname' column")));
+ gtk_container_add(GTK_CONTAINER(vbox), scroll);
+ gtk_widget_set_size_request(scroll, 500, 300);
+ gtk_widget_show_all(dialog);
+
+ do {
+ res = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (res == SUB_RESPONSE_DELETE) {
+ confirm = gtk_dialog_new_with_buttons(_("Delete DC nicknames"),
+ GTK_WINDOW(dialog),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_YES,
+ GTK_RESPONSE_YES,
+ GTK_STOCK_NO,
+ GTK_RESPONSE_NO,
+ NULL);
+ gtk_widget_set_size_request(confirm, 350, 90);
+ vbox = gtk_dialog_get_content_area(GTK_DIALOG(confirm));
+ gtk_container_add(GTK_CONTAINER(vbox),
+ gtk_label_new(_("Are you sure you want to delete the selected entries?")));
+ gtk_widget_show_all(confirm);
+ if (gtk_dialog_run(GTK_DIALOG(confirm)) == GTK_RESPONSE_YES)
+ edit_dc_delete_rows(GTK_TREE_VIEW(view));
+ gtk_widget_destroy(confirm);
+ }
+ if (res == GTK_RESPONSE_APPLY && holdnicknames->model != NULL ) {
+ //printf("remember_dc\n");
+ remember_dc(holdnicknames->model, holdnicknames->deviceid, holdnicknames->nickname, TRUE);
+ }
+ } while (res != GTK_RESPONSE_CANCEL && res != GTK_RESPONSE_DELETE_EVENT && res != GTK_RESPONSE_APPLY);
+ gtk_widget_destroy(dialog);
+}
+
+
+
+
+
static GtkActionEntry menu_items[] = {
{ "FileMenuAction", NULL, N_("File"), NULL, NULL, NULL},
{ "LogMenuAction", NULL, N_("Log"), NULL, NULL, NULL},
@@ -1155,6 +1406,7 @@ static GtkActionEntry menu_items[] = {
{ "ViewProfile", NULL, N_("Profile"), CTRLCHAR "2", NULL, G_CALLBACK(view_profile) },
{ "ViewInfo", NULL, N_("Info"), CTRLCHAR "3", NULL, G_CALLBACK(view_info) },
{ "ViewThree", NULL, N_("Three"), CTRLCHAR "4", NULL, G_CALLBACK(view_three) },
+ { "EditNames", NULL, N_("Edit Names"), CTRLCHAR "E", NULL, G_CALLBACK(edit_dc_nicknames) },
{ "PrevDC", NULL, N_("Prev DC"), NULL, NULL, G_CALLBACK(prev_dc) },
{ "NextDC", NULL, N_("Next DC"), NULL, NULL, G_CALLBACK(next_dc) },
{ "InputPlan", NULL, N_("Input Plan"), NULL, NULL, G_CALLBACK(input_plan) },
@@ -1187,6 +1439,7 @@ static const gchar* ui_string = " \
</menu> \
<menu name=\"LogMenu\" action=\"LogMenuAction\"> \
<menuitem name=\"Download From Dive Computer\" action=\"DownloadLog\" /> \
+ <menuitem name=\"Edit Dive Computer Names\" action=\"EditNames\" /> \
<separator name=\"Separator1\"/> \
<menuitem name=\"Add Dive\" action=\"AddDive\" /> \
<separator name=\"Separator2\"/> \
More information about the subsurface
mailing list