Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2004:
[Freeciv-Dev] (PR#4340) more gtk2 'change production' button woes
Home

[Freeciv-Dev] (PR#4340) more gtk2 'change production' button woes

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: per@xxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#4340) more gtk2 'change production' button woes
From: "Vasco Alexandre da Silva Costa" <vasc@xxxxxxxxxxxxxx>
Date: Sat, 3 Apr 2004 18:28:15 -0800
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=4340 >

> [vasc - Mon Jul 07 23:43:01 2003]:
> 
> [rfalke - Sun Jun  8 16:47:20 2003]:
> 
> > Is it possible that we get a "real" queue? Currently the item in
> > production is special. There is no reason for this except maybe
> > historical roots. This change would be GUI/client only. The server can
> > still think in the current schema (current production + queue). But I
> > have the feeling that the convsersion of the server will also enable
> > us to make the code simpler.

For now, I have just made a wrapper in client/ to hide that braindamage
called the worklist code from my sight. I hope to one day be able to
nuke that for something better, but for now, this will have to do.

This patch adds the current production to the top of the "worklist" like
you people wanted. It also allows besides appending, prepending. It adds
new buttons for these features and some of the older features, plus a
new SHIFT+Insert keyboard shortcut for prepending, etc, etc.

The new worklist dialog does everything the old GTK+ 1.2 dialog used to
do, but undo, and adds several features more.

And before you ask for it (aha, got you!) forget about undo, because
this code is instant apply, not like the old code was. Undo never made
much sense anyway, because none of the operations are destructive of
anything with real value to the player.


> > So I would change the Production info in the Overview page to a
> > read-only list. It is enough if it only shows the tree top-most
> > entries. Name and time is enough for these entries.
> > 
> > In the Production page the Change button will go and also the info at
> > the top.
> > 
> > Also related to this: can we move the Buy button to the overview page?

After this patch there are two buy buttons in the city dialog, for your
pleasure.

I bet if I just moved the button someone would moan about how they have
to switch tabs to buy after they change production, yadayadayada. Like
it wasn't enough to have two buy buttons in the GUI already, now you
have *three*! I could bet there will be four soon. :-)

Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.30
diff -u -r1.30 citydlg_common.c
--- client/citydlg_common.c     9 Mar 2004 19:10:40 -0000       1.30
+++ client/citydlg_common.c     4 Apr 2004 02:08:37 -0000
@@ -20,6 +20,7 @@
 #include "log.h"
 #include "support.h"
 
+#include "citydlg_g.h"
 #include "mapview_g.h"
 
 #include "citydlg_common.h"
@@ -474,6 +475,57 @@
   copy.name[0] = '\0';
 
   return dsend_packet_city_worklist(&aconnection, pcity->id, &copy);
+}
+
+/**************************************************************************
+  Get the city current production and the worklist, like it should be.
+**************************************************************************/
+void city_get_queue(struct city *pcity, struct worklist *pqueue)
+{
+  int id;
+  bool is_unit;
+
+  copy_worklist(pqueue, &pcity->worklist);
+
+  /* The GUI wants current production to be in the task list, but the
+     worklist API wants it out for reasons unknown. Perhaps someone enjoyed
+     making things more complicated than necessary? So I dance around it. */
+
+  /* We want the current production to be in the queue. Always. */
+  worklist_remove(pqueue, MAX_LEN_WORKLIST - 1);
+
+  id = pcity->currently_building;
+  is_unit = pcity->is_building_unit;
+  worklist_insert(pqueue, id, is_unit, 0);
+}
+
+/**************************************************************************
+  Set the city current production and the worklist, like it should be.
+**************************************************************************/
+void city_set_queue(struct city *pcity, struct worklist *pqueue)
+{
+  struct worklist copy;
+  int id;
+  bool is_unit;
+
+  copy_worklist(&copy, pqueue);
+
+  /* The GUI wants current production to be in the task list, but the
+     worklist API wants it out for reasons unknown. Perhaps someone enjoyed
+     making things more complicated than necessary? So I dance around it. */
+  if (worklist_peek(&copy, &id, &is_unit)) {
+    worklist_advance(&copy);
+
+    city_set_worklist(pcity, &copy);
+    city_change_production(pcity, is_unit, id);
+  } else {
+    /* You naughty boy, you can't erase the current production. Nyah! */
+    if (worklist_is_empty(&pcity->worklist)) {
+      refresh_city_dialog(pcity);
+    } else {
+      city_set_worklist(pcity, &copy);
+    }
+  }
 }
 
 /**************************************************************************
Index: client/citydlg_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.h,v
retrieving revision 1.19
diff -u -r1.19 citydlg_common.h
--- client/citydlg_common.h     8 Mar 2004 07:20:49 -0000       1.19
+++ client/citydlg_common.h     4 Apr 2004 02:08:37 -0000
@@ -60,6 +60,8 @@
 
 int city_change_production(struct city *pcity, bool is_unit, int build_id);
 int city_set_worklist(struct city *pcity, struct worklist *pworklist);
+void city_get_queue(struct city *pcity, struct worklist *pqueue);
+void city_set_queue(struct city *pcity, struct worklist *pqueue);
 int city_sell_improvement(struct city *pcity, Impr_Type_id sell_id);
 int city_buy_production(struct city *pcity);
 int city_change_specialist(struct city *pcity, enum specialist_type from,
Index: client/gui-gtk-2.0/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.c,v
retrieving revision 1.80
diff -u -r1.80 citydlg.c
--- client/gui-gtk-2.0/citydlg.c        2 Apr 2004 13:49:25 -0000       1.80
+++ client/gui-gtk-2.0/citydlg.c        4 Apr 2004 02:08:38 -0000
@@ -111,8 +111,8 @@
     GtkWidget *map_canvas_pixmap;
     GtkWidget *tradelist;
     GtkWidget *production_bar;
-    GtkWidget *improvement_list;
     GtkWidget *buy_command;
+    GtkWidget *improvement_list;
 
     GtkWidget *supported_units_frame;
     GtkWidget *supported_unit_table;
@@ -131,6 +131,7 @@
  
   struct { 
     GtkWidget *production_bar;
+    GtkWidget *buy_command;
     GtkWidget *worklist;
   } production;
 
@@ -366,6 +367,7 @@
   if (city_owner(pcity) == game.player_ptr) {
     bool have_present_units =
        (unit_list_size(&map_get_tile(pcity->x, pcity->y)->units) > 0);
+    gboolean sensitive;
 
     refresh_worklist(pdialog->production.worklist);
 
@@ -377,12 +379,15 @@
     gtk_widget_set_sensitive(pdialog->show_units_command,
                             can_client_issue_orders() &&
                             have_present_units);
-    gtk_widget_set_sensitive(pdialog->overview.buy_command,
-                            city_buy_cost(pdialog->pcity) > 0 &&
-                            can_client_issue_orders());
+
+    sensitive = (city_buy_cost(pdialog->pcity) > 0
+       && can_client_issue_orders());
+    gtk_widget_set_sensitive(pdialog->overview.buy_command, sensitive);
+    gtk_widget_set_sensitive(pdialog->production.buy_command, sensitive);
   } else {
     /* Set the buttons we do not want live while a Diplomat investigates */
     gtk_widget_set_sensitive(pdialog->overview.buy_command, FALSE);
+    gtk_widget_set_sensitive(pdialog->production.buy_command, FALSE);
     gtk_widget_set_sensitive(pdialog->show_units_command, FALSE);
   }
 }
@@ -692,12 +697,24 @@
                       "label", _("Production:"),
                       "xalign", 0.0, "yalign", 0.5, NULL);
   gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-  
+
+
+  hbox = gtk_hbox_new(FALSE, 10);
+  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
   bar = gtk_progress_bar_new();
   pdialog->overview.production_bar = bar;
-  gtk_box_pack_start(GTK_BOX(vbox), bar, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(hbox), bar, TRUE, TRUE, 0);
   gtk_progress_bar_set_text(GTK_PROGRESS_BAR(bar), _("%d/%d %d turns"));
 
+  pdialog->overview.buy_command = gtk_stockbutton_new(GTK_STOCK_EXECUTE,
+                                                     _("_Buy"));
+  gtk_box_pack_start(GTK_BOX(hbox), pdialog->overview.buy_command,
+                    FALSE, FALSE, 0);
+  g_signal_connect(pdialog->overview.buy_command, "clicked",
+                  G_CALLBACK(buy_callback), pdialog);
+
+
   label = g_object_new(GTK_TYPE_LABEL,
                       "use-underline", TRUE,
                       "mnemonic-widget", view,
@@ -787,12 +804,12 @@
   g_signal_connect(bar, "drag_data_received",
                   G_CALLBACK(target_drag_data_received), pdialog);
 
-  pdialog->overview.buy_command = gtk_stockbutton_new(GTK_STOCK_EXECUTE,
+  pdialog->production.buy_command = gtk_stockbutton_new(GTK_STOCK_EXECUTE,
                                                      _("_Buy"));
-  gtk_box_pack_start(GTK_BOX(hbox), pdialog->overview.buy_command,
+  gtk_box_pack_start(GTK_BOX(hbox), pdialog->production.buy_command,
                     FALSE, FALSE, 0);
 
-  g_signal_connect(pdialog->overview.buy_command, "clicked",
+  g_signal_connect(pdialog->production.buy_command, "clicked",
                   G_CALLBACK(buy_callback), pdialog);
 
 
@@ -881,7 +898,7 @@
 static void create_and_append_trade_page(struct city_dialog *pdialog)
 {
   GtkWidget *page, *label;
-  char *tab_title = _("_Trade Routes");
+  char *tab_title = _("Trade Ro_utes");
 
   page = gtk_hbox_new(TRUE, 0);
 
@@ -1397,9 +1414,11 @@
   struct city *pcity = pdialog->pcity;
   gdouble pct;
   int cost;
+  gboolean sensitive;
 
-  gtk_widget_set_sensitive(pdialog->overview.buy_command,
-                          can_client_issue_orders() && !pcity->did_buy);
+  sensitive = (can_client_issue_orders() && !pcity->did_buy);
+  gtk_widget_set_sensitive(pdialog->overview.buy_command, sensitive);
+  gtk_widget_set_sensitive(pdialog->production.buy_command, sensitive);
 
   get_city_dialog_production(pcity, buf, sizeof(buf));
 
@@ -1410,6 +1429,7 @@
     if (pcity->currently_building == B_CAPITAL) {
       /* You can't buy capitalization */
       gtk_widget_set_sensitive(pdialog->overview.buy_command, FALSE);
+      gtk_widget_set_sensitive(pdialog->production.buy_command, FALSE);
       cost = 0;
     } else {
       cost = impr_build_shield_cost(pcity->currently_building);;
Index: client/gui-gtk-2.0/wldlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/wldlg.c,v
retrieving revision 1.31
diff -u -r1.31 wldlg.c
--- client/gui-gtk-2.0/wldlg.c  3 Apr 2004 01:57:22 -0000       1.31
+++ client/gui-gtk-2.0/wldlg.c  4 Apr 2004 02:08:40 -0000
@@ -298,6 +298,7 @@
   GtkTreeViewColumn *src_col, *dst_col;
 
   GtkWidget *add_cmd, *change_cmd, *help_cmd;
+  GtkWidget *up_cmd, *down_cmd, *prepend_cmd, *append_cmd;
 
   bool future;
 };
@@ -570,6 +571,131 @@
 /****************************************************************
 ...
 *****************************************************************/
+static void queue_bubble_up(struct worklist_data *ptr)
+{
+  GtkTreePath *path;
+  GtkTreeViewColumn *col;
+  GtkTreeModel *model;
+
+  if (!GTK_WIDGET_IS_SENSITIVE(ptr->dst_view)) {
+    return;
+  }
+
+  model = GTK_TREE_MODEL(ptr->dst);
+  gtk_tree_view_get_cursor(GTK_TREE_VIEW(ptr->dst_view), &path, &col);
+  if (path) {
+    GtkTreeIter it, it_prev;
+
+    if (gtk_tree_path_prev(path)) {
+      gtk_tree_model_get_iter(model, &it_prev, path);
+      it = it_prev;
+      gtk_tree_model_iter_next(model, &it);
+
+      gtk_list_store_swap(GTK_LIST_STORE(model), &it, &it_prev);
+
+      gtk_tree_view_set_cursor(GTK_TREE_VIEW(ptr->dst_view), path, col, FALSE);
+      commit_worklist(ptr);
+    }
+  }
+  gtk_tree_path_free(path);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void queue_bubble_down(struct worklist_data *ptr)
+{
+  GtkTreePath *path;
+  GtkTreeViewColumn *col;
+  GtkTreeModel *model;
+
+  if (!GTK_WIDGET_IS_SENSITIVE(ptr->dst_view)) {
+    return;
+  }
+
+  model = GTK_TREE_MODEL(ptr->dst);
+  gtk_tree_view_get_cursor(GTK_TREE_VIEW(ptr->dst_view), &path, &col);
+  if (path) {
+    GtkTreeIter it, it_next;
+
+    gtk_tree_model_get_iter(model, &it, path);
+    it_next = it;
+    if (gtk_tree_model_iter_next(model, &it_next)) {
+      gtk_list_store_swap(GTK_LIST_STORE(model), &it, &it_next);
+
+      gtk_tree_path_next(path);
+      gtk_tree_view_set_cursor(GTK_TREE_VIEW(ptr->dst_view), path, col, FALSE);
+      commit_worklist(ptr);
+    }
+  }
+  gtk_tree_path_free(path);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void queue_insert(struct worklist_data *ptr, bool prepend)
+{
+  GtkTreeModel *model;
+  GtkTreeIter it;
+  GtkTreePath *path;
+
+  GtkTreeModel *src_model, *dst_model;
+  GtkTreeIter src_it, dst_it;
+  gint i, ncols;
+
+  if (!GTK_WIDGET_IS_SENSITIVE(ptr->dst_view)) {
+    return;
+  }
+
+  if (!gtk_tree_selection_get_selected(ptr->src_selection, &model, &it)) {
+    return;
+  }
+
+  path = gtk_tree_model_get_path(model, &it);
+
+  src_model = GTK_TREE_MODEL(ptr->src);
+  dst_model = GTK_TREE_MODEL(ptr->dst);
+
+  gtk_tree_model_get_iter(src_model, &src_it, path);
+  if (prepend) {
+    gtk_list_store_prepend(GTK_LIST_STORE(dst_model), &dst_it);
+  } else {
+    gtk_list_store_append(GTK_LIST_STORE(dst_model), &dst_it);
+  }
+
+  ncols = gtk_tree_model_get_n_columns(src_model);
+
+  for (i = 0; i < ncols; i++) {
+    GValue value = { 0, };
+
+    gtk_tree_model_get_value(src_model, &src_it, i, &value);
+    gtk_list_store_set_value(GTK_LIST_STORE(dst_model), &dst_it, i, &value);
+  }
+  commit_worklist(ptr);
+
+  gtk_tree_path_free(path);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void queue_prepend(struct worklist_data *ptr)
+{
+  queue_insert(ptr, TRUE);
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void queue_append(struct worklist_data *ptr)
+{
+  queue_insert(ptr, FALSE);
+}
+
+/****************************************************************
+...
+*****************************************************************/
 static void src_row_callback(GtkTreeView *view, GtkTreePath *path,
                             GtkTreeViewColumn *col, gpointer data)
 {
@@ -615,6 +741,7 @@
   dst_model = GTK_TREE_MODEL(ptr->dst);
 
   gtk_tree_model_get_iter(dst_model, &it, path);
+
   gtk_list_store_remove(GTK_LIST_STORE(dst_model), &it);
   commit_worklist(ptr);
 }
@@ -633,18 +760,11 @@
     return FALSE;
   }
   
-  if (ev->keyval == GDK_Insert) {
-    GtkTreeModel *model;
-    GtkTreeIter it;
-    GtkTreePath *path;
-
-    if (!gtk_tree_selection_get_selected(ptr->src_selection, &model, &it)) {
-      return FALSE;
-    }
-
-    path = gtk_tree_model_get_path(model, &it);
-    src_row_callback(NULL, path, NULL, ptr);
-    gtk_tree_path_free(path);
+  if ((ev->state & GDK_SHIFT_MASK) && ev->keyval == GDK_Insert) {
+    queue_prepend(ptr);
+    return TRUE;
+  } else if (ev->keyval == GDK_Insert) {
+    queue_append(ptr);
     return TRUE;
   } else {
     return FALSE;
@@ -665,9 +785,8 @@
 
   if (ev->keyval == GDK_Delete) {
     GtkTreeIter it, it_next;
-    bool deleted;
+    bool deleted = FALSE;
 
-    deleted = FALSE;
     if (gtk_tree_model_get_iter_first(model, &it)) {
       bool more;
 
@@ -690,46 +809,11 @@
     return TRUE;
 
   } else if ((ev->state & GDK_MOD1_MASK) && ev->keyval == GDK_Up) {
-    GtkTreePath *path;
-    GtkTreeViewColumn *col;
-
-    gtk_tree_view_get_cursor(GTK_TREE_VIEW(w), &path, &col);
-    if (path) {
-      GtkTreeIter it, it_prev;
-
-      if (gtk_tree_path_prev(path)) {
-       gtk_tree_model_get_iter(model, &it_prev, path);
-       it = it_prev;
-       gtk_tree_model_iter_next(model, &it);
-
-       gtk_list_store_swap(GTK_LIST_STORE(model), &it, &it_prev);
-
-       gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, col, FALSE);
-       commit_worklist(ptr);
-      }
-    }
-    gtk_tree_path_free(path);
+    queue_bubble_up(ptr);
     return TRUE;
 
   } else if ((ev->state & GDK_MOD1_MASK) && ev->keyval == GDK_Down) {
-    GtkTreePath *path;
-    GtkTreeViewColumn *col;
-
-    gtk_tree_view_get_cursor(GTK_TREE_VIEW(w), &path, &col);
-    if (path) {
-      GtkTreeIter it, it_next;
-
-      gtk_tree_model_get_iter(model, &it, path);
-      it_next = it;
-      if (gtk_tree_model_iter_next(model, &it_next)) {
-       gtk_list_store_swap(GTK_LIST_STORE(model), &it, &it_next);
-
-       gtk_tree_path_next(path);
-       gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, col, FALSE);
-       commit_worklist(ptr);
-      }
-    }
-    gtk_tree_path_free(path);
+    queue_bubble_down(ptr);
     return TRUE;
 
   } else {
@@ -755,9 +839,32 @@
       gtk_widget_set_sensitive(ptr->change_cmd, FALSE);
     }
     gtk_widget_set_sensitive(ptr->help_cmd, TRUE);
+    gtk_widget_set_sensitive(ptr->prepend_cmd, TRUE);
+    gtk_widget_set_sensitive(ptr->append_cmd, TRUE);
   } else {
     gtk_widget_set_sensitive(ptr->change_cmd, FALSE);
     gtk_widget_set_sensitive(ptr->help_cmd, FALSE);
+    gtk_widget_set_sensitive(ptr->prepend_cmd, FALSE);
+    gtk_widget_set_sensitive(ptr->append_cmd, FALSE);
+  }
+}
+
+/****************************************************************
+...
+*****************************************************************/
+static void dst_selection_callback(GtkTreeSelection *selection, gpointer data)
+{
+  struct worklist_data *ptr;
+
+  ptr = data;
+
+  /* update widget sensitivity. */
+  if (gtk_tree_selection_count_selected_rows(selection) > 0) {
+    gtk_widget_set_sensitive(ptr->up_cmd, TRUE);
+    gtk_widget_set_sensitive(ptr->down_cmd, TRUE);
+  } else {
+    gtk_widget_set_sensitive(ptr->up_cmd, FALSE);
+    gtk_widget_set_sensitive(ptr->down_cmd, FALSE);
   }
 }
 
@@ -891,12 +998,12 @@
 /****************************************************************
   Worklist editor shell.
 *****************************************************************/
-GtkWidget *create_worklist()
+GtkWidget *create_worklist(void)
 {
   GtkWidget *editor, *table, *sw, *bbox;
   GtkWidget *src_view, *dst_view, *label, *button;
   GtkWidget *menubar, *item, *menu, *image;
-  GtkWidget *align, *arrow, *check;
+  GtkWidget *table2, *arrow, *check;
   GtkSizeGroup *group;
 
   GtkListStore *src_store, *dst_store;
@@ -958,12 +1065,51 @@
   g_signal_connect(check, "toggled", G_CALLBACK(future_callback), ptr);
 
 
-  align = gtk_alignment_new(0.5, 0.5, 6.0, 1.0);
-  gtk_table_attach(GTK_TABLE(table), align, 2, 3, 1, 2,
+  table2 = gtk_table_new(4, 1, FALSE);
+  gtk_table_attach(GTK_TABLE(table), table2, 2, 3, 1, 2,
                   GTK_FILL, GTK_FILL, 0, 0);
 
+  button = gtk_button_new();
+  ptr->prepend_cmd = button;
+  gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+  gtk_table_attach(GTK_TABLE(table2), button, 0, 1, 0, 1,
+      0, GTK_EXPAND|GTK_FILL, 0, 24);
+
+  arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE);
+  gtk_container_add(GTK_CONTAINER(button), arrow);
+  g_signal_connect_swapped(button, "clicked",
+                          G_CALLBACK(queue_prepend), ptr);
+
+  button = gtk_button_new();
+  ptr->up_cmd = button;
+  gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+  gtk_table_attach(GTK_TABLE(table2), button, 0, 1, 1, 2, 0, 0, 0, 0);
+
+  arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_NONE);
+  gtk_container_add(GTK_CONTAINER(button), arrow);
+  g_signal_connect_swapped(button, "clicked",
+                          G_CALLBACK(queue_bubble_up), ptr);
+
+  button = gtk_button_new();
+  ptr->down_cmd = button;
+  gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+  gtk_table_attach(GTK_TABLE(table2), button, 0, 1, 2, 3, 0, 0, 0, 0);
+
+  arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_IN);
+  gtk_container_add(GTK_CONTAINER(button), arrow);
+  g_signal_connect_swapped(button, "clicked",
+                          G_CALLBACK(queue_bubble_down), ptr);
+
+  button = gtk_button_new();
+  ptr->append_cmd = button;
+  gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+  gtk_table_attach(GTK_TABLE(table2), button, 0, 1, 3, 4,
+      0, GTK_EXPAND|GTK_FILL, 0, 24);
+
   arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE);
-  gtk_container_add(GTK_CONTAINER(align), arrow);
+  gtk_container_add(GTK_CONTAINER(button), arrow);
+  g_signal_connect_swapped(button, "clicked",
+                          G_CALLBACK(queue_append), ptr);
 
 
   sw = gtk_scrolled_window_new(NULL, NULL);
@@ -1048,6 +1194,9 @@
 
   g_signal_connect(ptr->src_selection, "changed",
                   G_CALLBACK(src_selection_callback), ptr);
+  g_signal_connect(ptr->dst_selection, "changed",
+                  G_CALLBACK(dst_selection_callback), ptr);
+
 
   gtk_widget_show_all(table);
   gtk_widget_show_all(bbox);
@@ -1096,7 +1245,7 @@
 void refresh_worklist(GtkWidget *editor)
 {
   struct worklist_data *ptr;
-  struct worklist *pwl;
+  struct worklist *pwl, queue;
 
   cid cids[U_LAST + B_LAST];
   int i, cids_used;
@@ -1111,7 +1260,6 @@
   GtkTreeModel *model;
   gboolean exists;
 
-
   ptr = g_object_get_data(G_OBJECT(editor), "data");
   pwl = ptr->pwl;
   
@@ -1150,14 +1298,21 @@
   model = GTK_TREE_MODEL(ptr->dst);
   exists = gtk_tree_model_get_iter_first(model, &it);
 
+  /* dance around worklist braindamage. */
+  if (ptr->pcity) {
+    city_get_queue(ptr->pcity, &queue);
+  } else {
+    copy_worklist(&queue, pwl);
+  }
+
   for (i = 0; i < MAX_LEN_WORKLIST; i++) {
     cid cid;
 
-    if (pwl->wlefs[i] == WEF_END) {
+    if (queue.wlefs[i] == WEF_END) {
       break;
     }
 
-    cid = cid_encode(pwl->wlefs[i] == WEF_UNIT, pwl->wlids[i]);
+    cid = cid_encode(queue.wlefs[i] == WEF_UNIT, queue.wlids[i]);
 
     if (!exists) {
       gtk_list_store_append(ptr->dst, &it);
@@ -1201,11 +1356,10 @@
 *****************************************************************/
 static void commit_worklist(struct worklist_data *ptr)
 {
-  struct worklist *pwl;
+  struct worklist *pwl, queue;
   GtkTreeModel *model;
   GtkTreeIter it;
   int i;
-  char name[MAX_LEN_NAME];
 
   pwl = ptr->pwl;
   
@@ -1215,31 +1369,31 @@
 
   model = GTK_TREE_MODEL(ptr->dst);
   
-  strcpy(name, pwl->name);
-  init_worklist(pwl);
+  init_worklist(&queue);
+  sz_strlcpy(queue.name, pwl->name);
 
   i = 0;
   if (gtk_tree_model_get_iter_first(model, &it)) {
     do {
       gint cid;
-      
-      gtk_tree_model_get(model, &it, 0, &cid, -1);
-      pwl->wlefs[i] = cid_is_unit(cid) ? WEF_UNIT : WEF_IMPR;
-      pwl->wlids[i] = cid_id(cid);
-
-      i++;
 
       /* oops, the player has a worklist longer than what we can store. */
-      if (i == MAX_LEN_WORKLIST) {
+      if (i >= MAX_LEN_WORKLIST) {
        break;
       }
-      
+
+      gtk_tree_model_get(model, &it, 0, &cid, -1);
+      queue.wlefs[i] = cid_is_unit(cid) ? WEF_UNIT : WEF_IMPR;
+      queue.wlids[i] = cid_id(cid);
+
+      i++;
     } while (gtk_tree_model_iter_next(model, &it));
   }
 
-  strcpy(pwl->name, name);
-
+  /* dance around worklist braindamage. */
   if (ptr->pcity) {
-    city_set_worklist(ptr->pcity, pwl);
+    city_set_queue(ptr->pcity, &queue);
+  } else {
+    copy_worklist(pwl, &queue);
   }
 }

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#4340) more gtk2 'change production' button woes, Vasco Alexandre da Silva Costa <=