diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2012-12-06 22:54:16 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-12-07 10:12:10 -0800 |
commit | 3d80d9283daa82847eb0fe1ae2f9879e9a80c9e5 (patch) | |
tree | 7e3c44263f70184ddb0dcbfac2b5c16865ab2cdb | |
parent | c796c16115dc3d7d52976395dfcfedc7e8bd1bec (diff) | |
download | subsurface-3d80d9283daa82847eb0fe1ae2f9879e9a80c9e5.tar.gz |
Sort the divecomputers alphabetically and have fixed width dropdown
Instead of just taking the vendors and products for the supported
divecomputers in the order libdivecomputer provides them to us we sort
them as we add them to our list of lists. While doing this we also track
the longest product name and try to make sure that the combobox for the
product is set to a fixed width that's wider then the longest product
name.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | gtk-gui.c | 73 |
1 files changed, 36 insertions, 37 deletions
@@ -1465,6 +1465,7 @@ struct mydescriptor { unsigned int model; }; +/* create a list of lists and keep the elements sorted */ static void add_dc(const char *vendor, const char *product, dc_descriptor_t *descriptor) { struct vendor *dcl = dc_list; @@ -1473,25 +1474,27 @@ static void add_dc(const char *vendor, const char *product, dc_descriptor_t *des if (!vendor || !product) return; - while (dcl && strcmp(dcl->vendor, vendor)) { + while (dcl && strcmp(dcl->vendor, vendor) < 0) { dclp = &dcl->next; dcl = dcl->next; } - if (!dcl) { - *dclp = calloc(sizeof(struct vendor), 1); - dcl = *dclp; + if (!dcl || strcmp(dcl->vendor, vendor)) { + dcl = calloc(sizeof(struct vendor), 1); + dcl->next = *dclp; + *dclp = dcl; dcl->vendor = strdup(vendor); } /* we now have a pointer to the requested vendor */ plp = &dcl->productlist; pl = *plp; - while (pl && strcmp(pl->product, product)) { + while (pl && strcmp(pl->product, product) < 0) { plp = &pl->next; pl = pl->next; } - if (!pl) { - *plp = calloc(sizeof(struct product), 1); - pl = *plp; + if (!pl || strcmp(pl->product, product)) { + pl = calloc(sizeof(struct product), 1); + pl->next = *plp; + *plp = pl; pl->product = strdup(product); } /* one would assume that the vendor / product combinations are unique, @@ -1506,9 +1509,11 @@ static void add_dc(const char *vendor, const char *product, dc_descriptor_t *des pl->descriptor = descriptor; } -static int fill_computer_list(GtkListStore *vendorstore, GtkListStore ***productstore, int *product_index) +/* fill the vendors and create and fill the respective product stores; return the longest product name + * and also the indices of the default vendor / product */ +static int fill_computer_list(GtkListStore *vendorstore, GtkListStore ***productstore, int *vendor_index, int *product_index) { - int index = -1, i, j, numvendor; + int i, j, numvendor, width = 10; GtkTreeIter iter; dc_iterator_t *iterator = NULL; dc_descriptor_t *descriptor = NULL; @@ -1522,19 +1527,32 @@ static int fill_computer_list(GtkListStore *vendorstore, GtkListStore ***product const char *vendor = dc_descriptor_get_vendor(descriptor); const char *product = dc_descriptor_get_product(descriptor); add_dc(vendor, product, descriptor); + if (product && strlen(product) > width) + width = strlen(product); } dc_iterator_free(iterator); + /* and add the Uemis Zurich which we are handling internally + THIS IS A HACK as we magically have a data structure here that + happens to match a data structure that is internal to libdivecomputer; + this WILL BREAK if libdivecomputer changes the dc_descriptor struct... + eventually the UEMIS code needs to move into libdivecomputer, I guess */ + mydescriptor = malloc(sizeof(struct mydescriptor)); + mydescriptor->vendor = "Uemis"; + mydescriptor->product = "Zurich"; + mydescriptor->type = DC_FAMILY_NULL; + mydescriptor->model = 0; + add_dc("Uemis", "Zurich", (dc_descriptor_t *)mydescriptor); dcl = dc_list; numvendor = 0; while (dcl) { numvendor++; dcl = dcl->next; } - /* we need two extra vendors, Uemis and an empty one */ - numvendor += 2; + /* we need an extra vendor for the empty one */ + numvendor += 1; dcl = dc_list; i = 0; - *product_index = -1; + *vendor_index = *product_index = -1; if (*productstore) free(*productstore); pstores = *productstore = malloc(numvendor * sizeof(GtkListStore *)); @@ -1552,7 +1570,7 @@ static int fill_computer_list(GtkListStore *vendorstore, GtkListStore ***product 0, pl->descriptor, -1); if (is_default_dive_computer(dcl->vendor, pl->product)) { - index = i; + *vendor_index = i; *product_index = j; } j++; @@ -1561,33 +1579,13 @@ static int fill_computer_list(GtkListStore *vendorstore, GtkListStore ***product i++; dcl = dcl->next; } - /* and add the Uemis Zurich which we are handling internally - THIS IS A HACK as we use the internal of libdivecomputer - data structures... eventually the UEMIS code needs to move - into libdivecomputer, I guess */ - mydescriptor = malloc(sizeof(struct mydescriptor)); - mydescriptor->vendor = "Uemis"; - mydescriptor->product = "Zurich"; - mydescriptor->type = DC_FAMILY_NULL; - mydescriptor->model = 0; - gtk_list_store_append(vendorstore, &iter); - gtk_list_store_set(vendorstore, &iter, - 0, mydescriptor->vendor, -1); - pstores[i] = gtk_list_store_new(1, G_TYPE_POINTER); - gtk_list_store_append(pstores[i], &iter); - gtk_list_store_set(pstores[i], &iter, - 0, mydescriptor, -1); - if (is_default_dive_computer("Uemis", "Zurich")) { - index = i; - *product_index = 0; - } /* now add the empty product list in case no vendor is selected */ i++; pstores[i] = gtk_list_store_new(1, G_TYPE_POINTER); if (*product_index == -1) *product_index = i; - return index; + return width; } void render_dc_vendor(GtkCellLayout *cell, @@ -1638,14 +1636,14 @@ static GtkComboBox *dive_computer_selector(GtkWidget *vbox) GtkWidget *hbox, *vendor_combo_box, *product_combo_box, *frame; GtkListStore *vendor_model; GtkCellRenderer *vendor_renderer, *product_renderer; - int vendor_default_index, product_default_index; + int vendor_default_index, product_default_index, width; hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); vendor_model = gtk_list_store_new(1, G_TYPE_POINTER); - vendor_default_index = fill_computer_list(vendor_model, &product_model, &product_default_index); + width = fill_computer_list(vendor_model, &product_model, &vendor_default_index, &product_default_index); frame = gtk_frame_new(_("Dive computer vendor and product")); gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, TRUE, 3); @@ -1666,6 +1664,7 @@ static GtkComboBox *dive_computer_selector(GtkWidget *vbox) gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(vendor_combo_box), vendor_renderer, render_dc_vendor, NULL, NULL); product_renderer = gtk_cell_renderer_text_new(); + gtk_cell_renderer_set_fixed_size(product_renderer, 10 * width, -1); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(product_combo_box), product_renderer, TRUE); gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(product_combo_box), product_renderer, render_dc_product, NULL, NULL); |