Crossfire Client, Branches  R11627
help.c
Go to the documentation of this file.
1 /*
2  Crossfire client, a client program for the crossfire program.
3 
4  Copyright (C) 2001-2005 Mark Wedel & Crossfire Development Team
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20  The author can be reached via e-mail to crossfire-devel@real-time.com
21 */
22 
23 
24 #include <gtk/gtk.h>
25 #include "client-types.h"
26 #include "../common/p_cmd.h"
27 
28 static GtkWidget *chelptext = NULL; /* HACK */
29 
30 static void replace_text(const char * new_text) {
31  gtk_text_set_point(GTK_TEXT(chelptext), 0);
32  gtk_text_forward_delete(GTK_TEXT(chelptext), gtk_text_get_length(GTK_TEXT(chelptext)) );
33  gtk_text_insert(GTK_TEXT(chelptext), NULL, &chelptext->style->black, NULL, new_text, -1);
34 }
35 
36 #define CLIENTHELP_LONG_LIST
37 /* Wossname. */
38 #define assumed_wrap 120
39 #define COLOSSAL_BUF 8192
40 
41 /* HACK Mostly duplicated from common/p_cmd.c. */
42 static void set_default_text(void) {
43  char out_buf[COLOSSAL_BUF];
44  char tmp_buf[COLOSSAL_BUF];
45  ConsoleCommand ** array_cc;
46  ConsoleCommand * cc;
47  int i;
48  CommCat current_cat = COMM_CAT_MISC;
49 #ifndef CLIENTHELP_LONG_LIST
50  size_t name_len;
51  char line_buf[MAX_BUF];
52  size_t line_len;
53 
54  line_buf[0] = '\0';
55  line_len = 0;
56 #endif
57 
58 /* HACK */
59 #define LINE(x) strncpy(tmp_buf, out_buf, COLOSSAL_BUF - 1); snprintf(out_buf, COLOSSAL_BUF - 1, "%s%s\n", tmp_buf, x);
60 
61  strcpy(out_buf,
62  "To get help on one of the commands listed below, enter the name in the text entry "
63  "box below, and press Enter. To get back to this list, clear the text box and press "
64  "Enter.\n"
65  "\n"
66  " === Client Side Command List === \n"
67  );
68 
69  array_cc = get_cat_sorted_commands();
70 
71  for (i = 0; i < get_num_commands(); i++) {
72  cc = array_cc[i];
73  if (cc->cat != current_cat) {
74  char buf[MAX_BUF];
75 
76 #ifndef CLIENTHELP_LONG_LIST
77  if (line_len > 0) {
78  LINE(line_buf);
79  line_buf[0] = '\0';
80  line_len = 0;
81  }
82 #endif
83 
84  snprintf(buf, MAX_BUF - 1, "%s Commands:", get_category_name(cc->cat));
85  LINE(buf);
86  current_cat = cc->cat;
87  }
88 
89 #ifdef CLIENTHELP_LONG_LIST
90  if (cc->desc != NULL) {
91  char buf[MAX_BUF];
92  snprintf(buf, MAX_BUF - 1, "%s - %s", cc->name, cc->desc);
93  LINE(buf);
94  } else {
95  LINE(cc->name);
96  }
97 #else
98  name_len = strlen(cc->name);
99 
100  if (strlen(cc->name) > MAX_BUF) {
101  LINE(cc->name);
102  } else if (name_len > assumed_wrap) {
103  LINE(line_buf);
104  LINE(cc->name);
105  line_len = 0;
106  } else if (line_len + name_len > assumed_wrap) {
107  LINE(line_buf);
108  strncpy(line_buf, cc->name, name_len + 1);
109  line_len = name_len;
110  } else {
111  if (line_len > 0) {
112  strncat(line_buf, " ", 2);
113  line_len += 1;
114  }
115  strncat(line_buf, cc->name, name_len + 1);
116  line_len += name_len;
117  }
118 #endif
119  }
120 
121 #ifndef CLIENTHELP_LONG_LIST
122  /* Dump dangling commands. Been there, got the fencepost.
123  Or is it a gap? */
124  if (line_len > 0) {
125  LINE(line_buf);
126  }
127 #endif
128 
129  replace_text(out_buf);
130 }
131 
132 static void chelp_entry_callback(GtkWidget * cargo_cult_ignored, GtkWidget * topic_entry) {
133  char buf[MAX_BUF];
134  const gchar * topic;
135  const ConsoleCommand * cc;
136  /* LOG(LOG_INFO, "chelp_entry_callback", "Got %s", gtk_entry_get_text(GTK_ENTRY(topic_entry))); */
137 
138  topic = gtk_entry_get_text(GTK_ENTRY(topic_entry));
139  /* TODO Select it, in case typing replaces selection. */
140 
141  if (topic == NULL || strlen(topic) <= 0) {
143  return;
144  }
145 
146  cc = find_command(topic);
147 
148  if (cc == NULL) {
149  snprintf(buf, MAX_BUF - 1, "No command '%s' found.", topic);
150  replace_text(buf);
151  } else {
152  char out_buf[COLOSSAL_BUF];
153  const char * extended;
154 
155  if (cc->desc != NULL) {
156  snprintf(buf, MAX_BUF - 1, "%s - %s",
157  cc->name,
158  cc->desc);
159  } else {
160  snprintf(buf, MAX_BUF - 1, cc->name);
161  }
162 
163  if (cc->helpfunc == NULL) {
164  extended = "This command is undocumented.";
165  } else {
166  extended = cc->helpfunc();
167  if (extended == NULL) {
168  extended = "This command is not yet documented.";
169  }
170  }
171 
172  snprintf(out_buf, COLOSSAL_BUF - 1, "%s Command:\n%s\n\n%s",
173  get_category_name(cc->cat),
174  buf,
175  extended);
176  replace_text(out_buf);
177  }
178 }
179 
180 static GtkWidget *gtkwin_chelp = NULL;
181 
182 void chelpdialog(GtkWidget *widget) {
183  GtkWidget *vbox;
184  GtkWidget *hbox;
185  GtkWidget *helpbutton;
186  GtkWidget *vscrollbar;
187  GtkWidget * topic_entry;
188  GtkWidget * lblCommand;
189  /* GtkStyle *style;*/
190 
191 
192  if(gtkwin_chelp == NULL) {
193 
194  gtkwin_chelp = gtk_window_new (GTK_WINDOW_DIALOG);
195  gtk_window_position (GTK_WINDOW (gtkwin_chelp), GTK_WIN_POS_CENTER);
196  gtk_widget_set_usize (gtkwin_chelp,400,300);
197  gtk_window_set_title (GTK_WINDOW (gtkwin_chelp), "Crossfire Client-Side Command Help");
198  gtk_window_set_policy (GTK_WINDOW (gtkwin_chelp), TRUE, TRUE, FALSE);
199 
200  gtk_signal_connect (GTK_OBJECT (gtkwin_chelp), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &gtkwin_chelp);
201 
202  gtk_container_border_width (GTK_CONTAINER (gtkwin_chelp), 1);
203  vbox = gtk_vbox_new(FALSE, 2);
204  gtk_container_add (GTK_CONTAINER(gtkwin_chelp),vbox);
205  hbox = gtk_hbox_new(FALSE, 2);
206  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
207 
208  chelptext = gtk_text_new (NULL, NULL);
209  gtk_text_set_editable (GTK_TEXT (chelptext), FALSE);
210  gtk_box_pack_start (GTK_BOX (hbox),chelptext, TRUE, TRUE, 0);
211  gtk_widget_show (chelptext);
212 
213  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (chelptext)->vadj);
214  gtk_box_pack_start (GTK_BOX (hbox),vscrollbar, FALSE, FALSE, 0);
215 
216  gtk_widget_show (vscrollbar);
217  gtk_widget_show (hbox);
218 
219  hbox = gtk_hbox_new(FALSE, 2);
220  lblCommand = gtk_label_new("Command: ");
221  gtk_box_pack_start(GTK_BOX(hbox), lblCommand, FALSE, FALSE, 0);
222 
223  topic_entry = gtk_entry_new ();
224  gtk_box_pack_start (GTK_BOX (hbox), topic_entry, TRUE, TRUE, 0);
225  gtk_signal_connect(GTK_OBJECT(topic_entry), "activate",
226  GTK_SIGNAL_FUNC(chelp_entry_callback),
227  topic_entry);
228  /* TODO Make it a combo box? No? */
229 
230  helpbutton = gtk_button_new_with_label ("Close");
231  gtk_signal_connect_object (GTK_OBJECT (helpbutton), "clicked",
232  GTK_SIGNAL_FUNC(gtk_widget_destroy),
233  GTK_OBJECT (gtkwin_chelp));
234  gtk_box_pack_end (GTK_BOX (hbox), helpbutton, FALSE, FALSE, 0);
235  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
236  gtk_widget_show (lblCommand);
237  gtk_widget_show (topic_entry);
238  gtk_widget_show (helpbutton);
239  gtk_widget_show (hbox);
240 
241  gtk_widget_show (vbox);
242  gtk_widget_show (gtkwin_chelp);
244  }
245  else {
246  gdk_window_raise (gtkwin_chelp->window);
247  }
248 }
void chelpdialog(GtkWidget *widget)
Definition: help.c:182
#define LINE(x)
static void set_default_text(void)
Definition: help.c:42
#define COLOSSAL_BUF
Definition: help.c:39
const char * get_category_name(CommCat cat)
Definition: p_cmd.c:335
CommCat cat
Definition: p_cmd.h:63
CommCat
Definition: p_cmd.h:48
#define TRUE
Definition: client-types.h:71
const char * desc
Definition: p_cmd.h:67
const char * name
Definition: p_cmd.h:62
CommHelpFunc helpfunc
Definition: p_cmd.h:66
#define MAX_BUF
Definition: client-types.h:128
int get_num_commands(void)
Definition: p_cmd.c:727
const ConsoleCommand * find_command(const char *cmd)
Definition: p_cmd.c:802
static GtkWidget * chelptext
Definition: help.c:28
static void chelp_entry_callback(GtkWidget *cargo_cult_ignored, GtkWidget *topic_entry)
Definition: help.c:132
static GtkWidget * gtkwin_chelp
Definition: help.c:180
static void replace_text(const char *new_text)
Definition: help.c:30
#define FALSE
Definition: client-types.h:68
#define assumed_wrap
Definition: help.c:38
ConsoleCommand ** get_cat_sorted_commands(void)
Definition: p_cmd.c:846