<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40126 >

So here is the previous patchset rolled into a one
not very large diff.

Interface changes:
- As per the wikia Editor page the Edit Mode checkitem
  is checked if and only if edit mode is active in the
  server, and sensitive if and only if the client may
  toggle edit mode.
- The Edit Mode checkitem has shortcut ctrl-e.

Internal changes:
- When edit mode is set, the notify message includes the
  connection that set it.
- A variation on the menus_set_active function is added,
  menus_set_active_no_callback, that can set the "active"
  state of menu items (e.g. the checked-in status of check
  items) without the menu item's associated callback being
  called.
- With menus_set_active_no_callback being used in place of
  menus_set_active where appropriate, the global flag
  variable "menu_updating" is no longer needed and removed.
- A call to update_menus is added in handle_conn_info so
  that the client can correctly setup the menus (e.g. to
  set the correct sensitivity of the Edit Mode checkitem
  when the required access level is received).
- For new connections to the server, if edit mode is
  active the server sends a notify message to that effect.


----------------------------------------------------------------------
町を歩くときには、変ものを探すのが楽しいですね。
diff --git a/client/gui-gtk-2.0/menu.c b/client/gui-gtk-2.0/menu.c
index c12ac39..1c4929d 100644
--- a/client/gui-gtk-2.0/menu.c
+++ b/client/gui-gtk-2.0/menu.c
@@ -70,6 +70,8 @@ GtkAccelGroup *toplevel_accel = NULL;
 static enum unit_activity road_activity;
 
 static void menus_rename(const char *path, const char *s);
+static void menus_set_active_no_callback(const gchar *path,
+                                         gboolean active);
 
 /****************************************************************
 ...
@@ -603,22 +605,23 @@ static void reports_menu_callback(gpointer callback_data,
   }
 }
 
-static int menu_updating = FALSE;
-
 /****************************************************************************
   Callback function for when an item is chosen from the "editor" menu.
 ****************************************************************************/
 static void editor_menu_callback(gpointer callback_data,
                                  guint callback_action, GtkWidget *widget)
 {   
-  if (menu_updating) {
-    return;
-  }
-
   switch(callback_action) {
   case MENU_EDITOR_TOGGLE:
     key_editor_toggle();
     popdown_science_dialog(); /* Unreachbale techs in reqtree on/off */
+
+    /* Because the user click on this check menu item would
+     * cause the checkmark to appear, indicating wrongly that
+     * edit mode is activated, reset the checkmark to the
+     * correct, expected setting. */
+    menus_set_active_no_callback("<main>/_Edit/Editing _Mode",
+                                 game.info.is_edit_mode);
     break;
   case MENU_EDITOR_TOOLS:
     editdlg_show_tools();
@@ -791,7 +794,7 @@ static GtkItemFactoryEntry menu_items[]	=
   { "/" N_("_Edit") "/sep1",				NULL,
 	NULL,			0,					"<Separator>"	},
   /* was Editor menu */
-  { "/" N_("_Edit") "/" N_("Editing _Mode"), NULL,
+  { "/" N_("_Edit") "/" N_("Editing _Mode"), "<control>e",
 	editor_menu_callback, MENU_EDITOR_TOGGLE, "<CheckItem>" },
   { "/" N_("_Edit") "/" N_("Editing _Tools"), NULL,
 	editor_menu_callback, MENU_EDITOR_TOOLS },
@@ -1165,6 +1168,55 @@ static void menus_set_sensitive(const char *path, int sensitive)
 }
 
 /****************************************************************
+  Sets the toggled state on the check menu item given by 'path'
+  according to 'active', without the associated callback being
+  called.
+*****************************************************************/
+static void menus_set_active_no_callback(const gchar *path,
+                                         gboolean active)
+{
+  GtkWidget *w, *item;
+  guint sid;
+  gulong hid;
+
+  path = menu_path_remove_uline(path);
+
+  if (!(item = gtk_item_factory_get_item(item_factory, path))) {
+    freelog(LOG_ERROR, "Can't set active for non-existent menu %s.",
+            path);
+    return;
+  }
+
+  if (!(w = gtk_item_factory_get_widget(item_factory, path))) {
+    freelog(LOG_ERROR, "Can't set active for non-existent menu %s.",
+            path);
+    return;
+  }
+
+  sid = g_signal_lookup("activate", G_TYPE_FROM_INSTANCE(w));
+  if (sid == 0) {
+    freelog(LOG_ERROR, "Can't block menu callback because "
+            "the \"activate\" signal id was not found for "
+            "the menu widget at path \"%s\".", path);
+    return;
+  }
+
+  hid = g_signal_handler_find(w, G_SIGNAL_MATCH_ID,
+                              sid, 0, NULL, NULL, NULL);
+
+  if (hid == 0) {
+    freelog(LOG_ERROR, "Can't block menu callback because "
+            "the \"activate\" signal handler id was not found "
+            "for the menu widget at path \"%s\".", path);
+    return;
+  }
+
+  g_signal_handler_block(w, hid);
+  gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), active);
+  g_signal_handler_unblock(w, hid);
+}
+
+/****************************************************************
 ...
 *****************************************************************/
 static void menus_set_active(const char *path, int active)
@@ -1335,11 +1387,10 @@ void update_menus(void)
 
     menus_set_sensitive("<main>/_Edit/Worklists",
 			can_client_issue_orders());
-
-    menu_updating = TRUE;
-
-    menus_set_active("<main>/_Edit/Editing _Mode",
-		     can_conn_enable_editing(&client.conn));
+    menus_set_active_no_callback("<main>/_Edit/Editing _Mode",
+                                 game.info.is_edit_mode);
+    menus_set_sensitive("<main>/_Edit/Editing _Mode",
+                        can_conn_enable_editing(&client.conn));
     menus_set_sensitive("<main>/_Edit/Editing _Tools",
 			can_conn_edit(&client.conn));
     menus_set_sensitive("<main>/_Edit/Recalculate _Borders",
@@ -1347,8 +1398,6 @@ void update_menus(void)
     menus_set_sensitive("<main>/_Edit/Regenerate _Water",
 			can_conn_edit(&client.conn));
 
-    menu_updating = FALSE;
-
     /* If the client is not attached to a player, disable these reports. */
     menus_set_sensitive("<main>/_Reports/_Cities",
 			(NULL != client.conn.playing));
diff --git a/client/packhand.c b/client/packhand.c
index 8cf8782..af1ac15 100644
--- a/client/packhand.c
+++ b/client/packhand.c
@@ -1951,6 +1951,12 @@ void handle_conn_info(struct packet_conn_info *pinfo)
 
   update_players_dialog();
   update_conn_list_dialog();
+
+  if (pinfo->used && pinfo->id == client.conn.id) {
+    /* For updating the sensitivity of the "Edit Mode" menu item,
+     * among other things. */
+    update_menus();
+  }
 }
 
 /*************************************************************************
diff --git a/server/connecthand.c b/server/connecthand.c
index c9ab291..7991d33 100644
--- a/server/connecthand.c
+++ b/server/connecthand.c
@@ -195,6 +195,11 @@ void establish_new_connection(struct connection *pconn)
     show_players(pconn);
   }
 
+  if (game.info.is_edit_mode) {
+    notify_conn(NULL, NULL, E_SETTING,
+                _(" *** Server is in edit mode. *** "));
+  }
+
   reset_all_start_commands();
   (void) send_server_info_to_metaserver(META_INFO);
 }
diff --git a/server/edithand.c b/server/edithand.c
index 0a4d3ae..8837a9b 100644
--- a/server/edithand.c
+++ b/server/edithand.c
@@ -50,7 +50,8 @@ void handle_edit_mode(struct connection *pc, bool is_edit_mode)
   if (!game.info.is_edit_mode && is_edit_mode) {
     /* Someone could be cheating! Warn people. */
     notify_conn(NULL, NULL, E_SETTING,
-		_(" *** Server set to edit mode! *** "));
+                _(" *** Server set to edit mode by %s! *** "),
+                conn_description(pc));
   }
   if (game.info.is_edit_mode && !is_edit_mode) {
     notify_conn(NULL, NULL, E_SETTING,
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to