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

Alright, obviously attaching via "Jumbo" doesn't do what
I expect. Let's see if this will work. :)


-----------------------------------------------------------------------
この野郎!
 client/gui-gtk-2.0/chatline.c |   60 ++++++++++++++++++++++++++++++++++++++++-
 client/gui-gtk-2.0/gui_main.c |   52 +++++++++++++++++++++++++++++++++--
 client/gui-gtk-2.0/gui_main.h |    3 ++
 client/gui-gtk-2.0/pages.c    |    1 +
 4 files changed, 112 insertions(+), 4 deletions(-)

diff --git a/client/gui-gtk-2.0/chatline.c b/client/gui-gtk-2.0/chatline.c
index 1354ea3..9753f36 100644
--- a/client/gui-gtk-2.0/chatline.c
+++ b/client/gui-gtk-2.0/chatline.c
@@ -26,6 +26,7 @@
 #include "packets.h"
 #include "support.h"
 
+#include "civclient.h"
 #include "climisc.h"
 #include "gui_main.h"
 #include "gui_stuff.h"
@@ -36,6 +37,56 @@
 struct genlist *history_list;
 int history_pos;
 
+/**************************************************************************
+  Helper function to determine if a given client input line is intended as
+  a "plain" public message. Note that messages prefixed with : are a
+  special case (explicit public messages), and will return FALSE.
+**************************************************************************/
+static bool is_plain_public_message(const char *s)
+{
+  /* FIXME: These constants' definitions are duplicated in the server. */
+  const char ALLIESCHAT_COMMAND_PREFIX = '.';
+  const char SERVER_COMMAND_PREFIX = '/';
+  const char MESSAGE_PREFIX = ':';
+
+  const char *p;
+
+  /* If it is a server command or an explicit ally
+   * message, then it is not a public message. */
+  if (s[0] == SERVER_COMMAND_PREFIX
+      || s[0] == ALLIESCHAT_COMMAND_PREFIX) {
+    return FALSE;
+  }
+
+  /* It might be a private message of the form
+   *   'player name with spaces':the message
+   * or with ". So skip past the player name part. */
+  if (s[0] == '\'' || s[0] == '"') {
+    p = strchr(s + 1, s[0]);
+  } else {
+    p = s;
+  }
+
+  /* Now we just need to check that it is not a private
+   * message. If we encounter a space then the preceeding
+   * text could not have been a user/player name (the
+   * quote check above eliminated names with spaces) so
+   * it must be a public message. Otherwise if we encounter
+   * the message prefix : then the text parsed up until now
+   * was a player/user name and the line is intended as
+   * a private message (or explicit public message if the
+   * first character is :). */
+  while (p != NULL && *p != '\0') {
+    if (my_isspace(*p)) {
+      return TRUE;
+    } else if (*p == MESSAGE_PREFIX) {
+      return FALSE;
+    }
+    p++;
+  }
+  return TRUE;
+}
+
 
 /**************************************************************************
 ...
@@ -47,7 +98,14 @@ void inputline_return(GtkEntry *w, gpointer data)
   theinput = gtk_entry_get_text(w);
   
   if (*theinput) {
-    send_chat(theinput);
+    if (client_state() == C_S_RUNNING && allied_chat_only
+        && is_plain_public_message(theinput)) {
+      char buf[MAX_LEN_MSG];
+      my_snprintf(buf, sizeof(buf), ". %s", theinput);
+      send_chat(buf);
+    } else {
+      send_chat(theinput);
+    }
 
     if (genlist_size(history_list) >= MAX_CHATLINE_HISTORY) {
       void *data;
diff --git a/client/gui-gtk-2.0/gui_main.c b/client/gui-gtk-2.0/gui_main.c
index 1ed2e8b..dd7dc95 100644
--- a/client/gui-gtk-2.0/gui_main.c
+++ b/client/gui-gtk-2.0/gui_main.c
@@ -55,6 +55,7 @@
 #include "clinet.h"
 #include "colors.h"
 #include "connectdlg.h"
+#include "connectdlg_common.h"
 #include "control.h"
 #include "cma_fe.h"
 #include "dialogs.h"
@@ -95,6 +96,7 @@ int overview_canvas_store_height = 2 * 50;
 
 bool enable_tabs = TRUE;
 bool better_fog = TRUE;
+bool allied_chat_only = FALSE;
 
 GtkWidget *toplevel;
 GdkWindow *root_window;
@@ -271,6 +273,7 @@ static int unit_ids[MAX_NUM_UNITS_BELOW];  /* ids of the units icons in
 GtkTextView *main_message_area;
 GtkTextBuffer *message_buffer;
 static GtkWidget *inputline;
+static GtkWidget *allied_chat_toggle_button;
 
 static enum Display_color_type display_color_type;  /* practically unused */
 static gint timer_id;                               /*       ditto        */
@@ -300,6 +303,8 @@ static gboolean select_unit_pixmap_callback(GtkWidget *w, GdkEvent *ev,
 					    gpointer data);
 static gboolean quit_dialog_callback(void);
 
+static void allied_chat_button_toggled(GtkToggleButton *button,
+                                       gpointer user_data);
 
 /****************************************************************************
   Called by the tileset code to set the font size that should be used to
@@ -986,7 +991,7 @@ void enable_menus(bool enable)
 static void setup_widgets(void)
 {
   GtkWidget *box, *ebox, *hbox, *sbox, *align, *label;
-  GtkWidget *frame, *table, *table2, *paned, *sw, *text;
+  GtkWidget *frame, *table, *table2, *paned, *sw, *text, *button;
   int i;
   char buf[256];
   struct sprite *sprite;
@@ -1346,13 +1351,24 @@ static void setup_widgets(void)
   chat_welcome_message();
 
   /* the chat line */
-  inputline = gtk_entry_new();
-  gtk_box_pack_start(GTK_BOX(vbox), inputline, FALSE, FALSE, 3);
+  hbox = gtk_hbox_new(FALSE, 4);
+  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
 
+  inputline = gtk_entry_new();
   g_signal_connect(inputline, "activate",
 		   G_CALLBACK(inputline_return), NULL);
   g_signal_connect(inputline, "key_press_event",
                    G_CALLBACK(inputline_handler), NULL);
+  gtk_box_pack_start(GTK_BOX(hbox), inputline, TRUE, TRUE, 0);
+
+  button = gtk_toggle_button_new_with_label(_("Allies Only"));
+  gtk_button_set_focus_on_click(GTK_BUTTON(button), FALSE);
+  allied_chat_toggle_button = button;
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
+                               allied_chat_only);
+  g_signal_connect(button, "toggled",
+                   G_CALLBACK(allied_chat_button_toggled), NULL);
+  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
 
   /* Other things to take care of */
 
@@ -2067,3 +2083,33 @@ void add_idle_callback(void (callback)(void *), void *data)
   cb->data = data;
   gtk_idle_add(idle_callback_wrapper, cb);
 }
+
+/**************************************************************************
+  Initialize chatline buttons to a suitable state. This function is
+  intended to be called when the game starts.
+**************************************************************************/
+void init_chat_buttons(void)
+{
+  const bool is_multiplayer_game = !is_server_running();
+
+  if (is_multiplayer_game) {
+    allied_chat_only = TRUE;
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(allied_chat_toggle_button),
+                                 allied_chat_only);
+    gtk_widget_show(allied_chat_toggle_button);
+  } else {
+    allied_chat_only = FALSE;
+    gtk_widget_hide(allied_chat_toggle_button);
+  }
+}
+
+/**************************************************************************
+  Handle a toggle of the state of the "Allies Only" chat button.
+**************************************************************************/
+static void allied_chat_button_toggled(GtkToggleButton *button,
+                                       gpointer user_data)
+{
+  allied_chat_only
+    = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+}
+
diff --git a/client/gui-gtk-2.0/gui_main.h b/client/gui-gtk-2.0/gui_main.h
index 67aec27..d6c33fd 100644
--- a/client/gui-gtk-2.0/gui_main.h
+++ b/client/gui-gtk-2.0/gui_main.h
@@ -26,6 +26,9 @@ extern PangoFontDescription *        city_productions_font;
 
 extern bool enable_tabs;
 extern bool better_fog;
+extern bool allied_chat_only;
+
+void init_chat_buttons(void);
 
 extern GdkGC *          civ_gc;
 extern GdkGC *          mask_fg_gc;
diff --git a/client/gui-gtk-2.0/pages.c b/client/gui-gtk-2.0/pages.c
index 347f886..902d65e 100644
--- a/client/gui-gtk-2.0/pages.c
+++ b/client/gui-gtk-2.0/pages.c
@@ -2224,6 +2224,7 @@ void set_client_page(enum client_pages page)
     gtk_tree_view_focus(gtk_tree_selection_get_tree_view(scenario_selection));
     break;
   case PAGE_GAME:
+    init_chat_buttons();
     break;
   case PAGE_NETWORK:
     update_network_lists();
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to