From ada4aaef9718f87892b9ddeba62ba8013242a1f9 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sat, 4 Mar 2023 10:32:29 +0200
Subject: [PATCH 18/18] gtk4: Add "Production" -> "Add First" menu to
 cityreport

See osdn #47520

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/gui-gtk-4.0/cityrep.c | 111 ++++++++++++++---------------------
 1 file changed, 43 insertions(+), 68 deletions(-)

diff --git a/client/gui-gtk-4.0/cityrep.c b/client/gui-gtk-4.0/cityrep.c
index 4494f356a3..d0084c9365 100644
--- a/client/gui-gtk-4.0/cityrep.c
+++ b/client/gui-gtk-4.0/cityrep.c
@@ -91,11 +91,12 @@ static void update_total_buy_cost(void);
 static GMenu *create_production_menu(GActionGroup *group);
 static GMenu *create_select_menu(GActionGroup *group);
 
-static GMenu *create_change_menu(GActionGroup *group);
+static GMenu *create_change_menu(GActionGroup *group, const char *mname,
+                                 const char *human_mname,
+                                 enum city_operation_type oper);
 
 #ifdef MENUS_GTK3
 static void create_last_menu(GtkWidget *item);
-static void create_first_menu(GtkWidget *item);
 static void create_next_menu(GtkWidget *item);
 static void create_next_to_last_menu(GtkWidget *item);
 #endif /* MENUS_GTK3 */
@@ -114,7 +115,6 @@ static GtkListStore *city_model;
 #ifdef MENUS_GTK3
 static void popup_select_menu(GtkMenuShell *menu, gpointer data);
 static void popup_last_menu(GtkMenuShell *menu, gpointer data);
-static void popup_first_menu(GtkMenuShell *menu, gpointer data);
 static void popup_next_menu(GtkMenuShell *menu, gpointer data);
 static void popup_next_to_last_menu(GtkMenuShell *menu, gpointer data);
 #endif /* MENUS_GTK3 */
@@ -132,16 +132,13 @@ static GtkWidget *city_total_buy_cost_label;
 
 static GMenu *prod_menu = NULL;
 static GMenu *change_menu;
+static GMenu *add_first_menu;
 
 #ifdef MENUS_GTK3
 static GtkWidget *last_improvements_item;
 static GtkWidget *last_units_item;
 static GtkWidget *last_wonders_item;
 
-static GtkWidget *first_improvements_item;
-static GtkWidget *first_units_item;
-static GtkWidget *first_wonders_item;
-
 static GtkWidget *next_improvements_item;
 static GtkWidget *next_units_item;
 static GtkWidget *next_wonders_item;
@@ -334,6 +331,7 @@ void city_report_dialog_popdown(void)
 static void append_impr_or_unit_to_menu(GMenu *menu,
                                         GActionGroup *act_group,
                                         const char *act_pfx,
+                                        const char *act_pfx2,
                                         bool append_units,
                                         bool append_wonders,
                                         enum city_operation_type
@@ -415,11 +413,11 @@ static void append_impr_or_unit_to_menu(GMenu *menu,
 
     get_city_dialog_production_row(row, sizeof(buf[0]), &target, NULL);
 
-    fc_snprintf(actbuf, sizeof(actbuf), "win.%s%d", act_pfx, item);
+    fc_snprintf(actbuf, sizeof(actbuf), "win.%s%s%d", act_pfx, act_pfx2, item);
 
     menu_item = g_menu_item_new(buf[0], actbuf);
 
-    fc_snprintf(actbuf, sizeof(actbuf), "%s%d", act_pfx, item);
+    fc_snprintf(actbuf, sizeof(actbuf), "%s%s%d", act_pfx, act_pfx2, item);
     act = g_simple_action_new(actbuf, NULL);
     g_object_set_data(G_OBJECT(act), "freeciv_test_func", test_func);
     g_object_set_data(G_OBJECT(act), "freeciv_city_operation",
@@ -1158,10 +1156,6 @@ static GtkWidget *create_city_report_menu(void)
   cityrep_menu = g_menu_new();
 
 #ifdef MENUS_GTK3
-  item = gtk_menu_item_new_with_mnemonic(_("Add _First"));
-  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-  create_first_menu(item);
-
   item = gtk_menu_item_new_with_mnemonic(_("Add _Next"));
   gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
   create_next_menu(item);
@@ -1607,36 +1601,48 @@ void real_city_report_update_city(struct city *pcity)
 }
 
 /************************************************************************//**
-  Create submenu for changing production target
+  Create submenu for changing production target.
+
+  @param group       Group to add actions to
+  @param mname       Menu name part of the action identifier
+  @param human_mname Format of the human visible menu name
+  @param oper        Operation to do when user selectes an entry
+  @return Create menu
 ****************************************************************************/
-static GMenu *create_change_menu(GActionGroup *group)
+static GMenu *create_change_menu(GActionGroup *group, const char *mname,
+                                 const char *human_mname,
+                                 enum city_operation_type oper)
 {
   GMenu *menu = g_menu_new();
   GMenu *submenu;
   int n;
+  char buf[128];
 
   n = gtk_tree_selection_count_selected_rows(city_selection);
 
   submenu = g_menu_new();
-  append_impr_or_unit_to_menu(submenu, group, "change_u",
-                              TRUE, FALSE, CO_CHANGE,
+  append_impr_or_unit_to_menu(submenu, group, mname, "_u",
+                              TRUE, FALSE, oper,
                               can_city_build_now,
                               G_CALLBACK(select_impr_or_unit_callback), n);
-  submenu_append_unref(menu, _("Units"), G_MENU_MODEL(submenu));
+  fc_snprintf(buf, sizeof(buf), human_mname, _("Unit"));
+  submenu_append_unref(menu, buf, G_MENU_MODEL(submenu));
 
   submenu = g_menu_new();
-  append_impr_or_unit_to_menu(submenu, group, "change_i",
-                              FALSE, FALSE, CO_CHANGE,
+  append_impr_or_unit_to_menu(submenu, group, mname, "_i",
+                              FALSE, FALSE, oper,
                               can_city_build_now,
                               G_CALLBACK(select_impr_or_unit_callback), n);
-  submenu_append_unref(menu, _("Improvements"), G_MENU_MODEL(submenu));
+  fc_snprintf(buf, sizeof(buf), human_mname, _("Improvement"));
+  submenu_append_unref(menu, buf, G_MENU_MODEL(submenu));
 
   submenu = g_menu_new();
-  append_impr_or_unit_to_menu(submenu, group, "change_i",
-                              FALSE, TRUE, CO_CHANGE,
+  append_impr_or_unit_to_menu(submenu, group, mname, "_w",
+                              FALSE, TRUE, oper,
                               can_city_build_now,
                               G_CALLBACK(select_impr_or_unit_callback), n);
-  submenu_append_unref(menu, _("Wonders"), G_MENU_MODEL(submenu));
+  fc_snprintf(buf, sizeof(buf), human_mname, _("Wonder"));
+  submenu_append_unref(menu, buf, G_MENU_MODEL(submenu));
 
   return menu;
 }
@@ -1661,25 +1667,6 @@ static void create_last_menu(GtkWidget *item)
   gtk_menu_shell_append(GTK_MENU_SHELL(menu), last_wonders_item);
 }
 
-/************************************************************************//**
-  Creates the first menu.
-****************************************************************************/
-static void create_first_menu(GtkWidget *item)
-{
-  GtkWidget *menu;
-
-  menu = gtk_menu_button_new();
-  gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
-  g_signal_connect(menu, "show", G_CALLBACK(popup_first_menu), NULL);
-
-  first_units_item = gtk_menu_item_new_with_label(_("Units"));
-  gtk_menu_shell_append(GTK_MENU_SHELL(menu), first_units_item);
-  first_improvements_item = gtk_menu_item_new_with_label(_("Improvements"));
-  gtk_menu_shell_append(GTK_MENU_SHELL(menu), first_improvements_item);
-  first_wonders_item = gtk_menu_item_new_with_label(_("Wonders"));
-  gtk_menu_shell_append(GTK_MENU_SHELL(menu), first_wonders_item);
-}
-
 /************************************************************************//**
   Creates the next menu.
 ****************************************************************************/
@@ -1747,29 +1734,6 @@ static void popup_last_menu(GtkMenuShell *menu, gpointer data)
                                    G_CALLBACK(select_impr_or_unit_callback), n);
 }
 
-/************************************************************************//**
-  Pops up the first menu.
-****************************************************************************/
-static void popup_first_menu(GtkMenuShell *menu, gpointer data)
-{
-  int n;
-
-  n = gtk_tree_selection_count_selected_rows(city_selection);
-
-  append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(first_improvements_item),
-                                   FALSE, FALSE, CO_FIRST,
-                                   can_city_build_now,
-                                   G_CALLBACK(select_impr_or_unit_callback), n);
-  append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(first_units_item),
-                                   TRUE, FALSE, CO_FIRST,
-                                   can_city_build_now,
-                                   G_CALLBACK(select_impr_or_unit_callback), n);
-  append_impr_or_unit_to_menu_item(GTK_MENU_ITEM(first_wonders_item),
-                                   FALSE, TRUE, CO_FIRST,
-                                   can_city_build_now,
-                                   G_CALLBACK(select_impr_or_unit_callback), n);
-}
-
 /************************************************************************//**
   Pops up the next menu.
 ****************************************************************************/
@@ -1835,7 +1799,7 @@ static void recreate_sell_menu(GActionGroup *group)
 
   n = gtk_tree_selection_count_selected_rows(city_selection);
 
-  append_impr_or_unit_to_menu(menu, group, "sell",
+  append_impr_or_unit_to_menu(menu, group, "sell", "",
                               FALSE, FALSE, CO_SELL,
                               can_city_sell_universal,
                               G_CALLBACK(select_impr_or_unit_callback),
@@ -1854,9 +1818,19 @@ static GMenu *create_production_menu(GActionGroup *group)
 
   prod_menu = g_menu_new();
 
-  change_menu = create_change_menu(group);
+  /* TRANS: Menu name part to be used like "Change to Improvement"
+   *        This is about changing current production. */
+  change_menu = create_change_menu(group, "change", _("Change to %s"), CO_CHANGE);
   submenu_append_unref(prod_menu, _("Chan_ge"), G_MENU_MODEL(change_menu));
 
+  add_first_menu = g_menu_new();
+
+  /* TRANS: Menu name to be used like "Set Improvement first"
+   *        This is about adding item to the beginning of the worklist. */
+  add_first_menu = create_change_menu(group, "first", _("Set %s first"), CO_FIRST);
+  submenu_append_unref(prod_menu, _("Add _First"),
+                       G_MENU_MODEL(add_first_menu));
+
   act = g_simple_action_new("clear_worklist", NULL);
   g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
   g_signal_connect(act, "activate", G_CALLBACK(city_clear_worklist_callback),
@@ -1874,6 +1848,7 @@ static void recreate_production_menu(GActionGroup *group)
 {
   if (prod_menu != NULL) {
     g_menu_remove_all(change_menu);
+    g_menu_remove_all(add_first_menu);
     g_menu_remove_all(prod_menu);
   }
   g_menu_remove(cityrep_menu, 0);
-- 
2.39.2