]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/gtkdlgs.cpp
* fixed a lot of compiler warnings (mostly const char * stuff and use of uninitialize...
[xonotic/netradiant.git] / radiant / gtkdlgs.cpp
1 /*
2 Copyright (c) 2001, Loki software, inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list
9 of conditions and the following disclaimer.
10
11 Redistributions in binary form must reproduce the above copyright notice, this
12 list of conditions and the following disclaimer in the documentation and/or
13 other materials provided with the distribution.
14
15 Neither the name of Loki software nor the names of its contributors may be used
16 to endorse or promote products derived from this software without specific prior
17 written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
23 DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 //
32 // Some small dialogs that don't need much
33 //
34 // Leonardo Zide (leo@lokigames.com)
35 //
36
37 #include "stdafx.h"
38 #include <gdk/gdkkeysyms.h>
39 #include <gtk/gtk.h>
40 #include <glib/gi18n.h>
41
42 #ifdef _WIN32
43 #include <gdk/gdkwin32.h>
44 #endif
45
46 #ifdef _WIN32
47 #include <shellapi.h>
48 #endif
49
50 // =============================================================================
51 // Color selection dialog
52
53 qboolean DoColor (int iIndex)
54 {
55   static bool bColorOpen = false;
56
57   if(bColorOpen)
58   {
59     Sys_FPrintf(SYS_WRN, "DoColor dialog is already open\n");
60     return false;
61   }
62
63   bColorOpen = true;
64
65   if (color_dialog (g_pParentWnd->m_pWidget, g_qeglobals.d_savedinfo.colors[iIndex]))
66   {
67     /*
68     ** scale colors so that at least one component is at 1.0F
69     ** if this is meant to select an entity color
70     */
71     if (iIndex == COLOR_ENTITY)
72     {
73       float largest = 0.0F;
74
75       if ( g_qeglobals.d_savedinfo.colors[iIndex][0] > largest )
76         largest = g_qeglobals.d_savedinfo.colors[iIndex][0];
77       if ( g_qeglobals.d_savedinfo.colors[iIndex][1] > largest )
78         largest = g_qeglobals.d_savedinfo.colors[iIndex][1];
79       if ( g_qeglobals.d_savedinfo.colors[iIndex][2] > largest )
80         largest = g_qeglobals.d_savedinfo.colors[iIndex][2];
81
82       if ( largest == 0.0F )
83       {
84         g_qeglobals.d_savedinfo.colors[iIndex][0] = 1.0F;
85         g_qeglobals.d_savedinfo.colors[iIndex][1] = 1.0F;
86         g_qeglobals.d_savedinfo.colors[iIndex][2] = 1.0F;
87       }
88       else
89       {
90         float scaler = 1.0F / largest;
91
92         g_qeglobals.d_savedinfo.colors[iIndex][0] *= scaler;
93         g_qeglobals.d_savedinfo.colors[iIndex][1] *= scaler;
94         g_qeglobals.d_savedinfo.colors[iIndex][2] *= scaler;
95       }
96     }
97
98     Sys_UpdateWindows (W_ALL);
99     bColorOpen = false;
100     return true;
101   }
102   else {
103     bColorOpen = false;
104     return false;
105   }
106 }
107
108 // =============================================================================
109 // Project settings dialog
110
111 static void UpdateBSPCommandList (GtkWidget *dialog);
112
113 static void DoProjectAddEdit (bool edit, GtkWidget *parent)
114 {
115   GtkWidget *dlg, *vbox, *hbox, *label, *table, *button;
116   GtkWidget *cmd, *text;
117   int loop = 1, ret = IDCANCEL;
118
119   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
120   if (edit)
121     gtk_window_set_title (GTK_WINDOW (dlg), "Edit Command");
122   else
123     gtk_window_set_title (GTK_WINDOW (dlg), "Add Command");
124   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
125                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
126   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
127                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
128   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
129   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
130
131   vbox = gtk_vbox_new (FALSE, 5);
132   gtk_widget_show (vbox);
133   gtk_container_add (GTK_CONTAINER (dlg), vbox);
134   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
135
136   table = gtk_table_new (2, 2, FALSE);
137   gtk_widget_show (table);
138   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
139   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
140   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
141
142   label = gtk_label_new ("Menu text");
143   gtk_widget_show (label);
144   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
145                     (GtkAttachOptions) (GTK_FILL),
146                     (GtkAttachOptions) (0), 0, 0);
147   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
148
149   label = gtk_label_new ("Command");
150   gtk_widget_show (label);
151   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
152                     (GtkAttachOptions) (GTK_FILL),
153                     (GtkAttachOptions) (0), 0, 0);
154   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
155
156   text = gtk_entry_new ();
157   g_object_set_data (G_OBJECT (dlg), "text", text);
158   gtk_widget_show (text);
159   gtk_table_attach (GTK_TABLE (table), text, 1, 2, 0, 1,
160                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
161                     (GtkAttachOptions) (0), 0, 0);
162   gtk_widget_set_usize (text, 300, -2);
163
164   cmd = gtk_entry_new ();
165   g_object_set_data (G_OBJECT (dlg), "cmd", cmd);
166   gtk_widget_show (cmd);
167   gtk_table_attach (GTK_TABLE (table), cmd, 1, 2, 1, 2,
168                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
169                     (GtkAttachOptions) (0), 0, 0);
170   gtk_widget_set_usize (cmd, 300, -2);
171
172   hbox = gtk_hbox_new (FALSE, 5);
173   gtk_widget_show (hbox);
174   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
175
176   button = gtk_button_new_with_label ("OK");
177   gtk_widget_show (button);
178   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
179   gtk_signal_connect (GTK_OBJECT (button), "clicked",
180                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
181   gtk_widget_set_usize (button, 60, -2);
182
183   button = gtk_button_new_with_label ("Cancel");
184   gtk_widget_show (button);
185   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
186   gtk_signal_connect (GTK_OBJECT (button), "clicked",
187                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
188   gtk_widget_set_usize (button, 60, -2);
189
190   if (edit)
191   {
192     GtkTreeView* view = GTK_TREE_VIEW (g_object_get_data (G_OBJECT(parent), "view"));
193     GtkTreeSelection* selection = gtk_tree_view_get_selection(view);
194     GtkTreeIter iter;
195     GtkTreeModel* model;
196     if(gtk_tree_selection_get_selected(selection, &model, &iter))
197     {
198       char* key;
199       gtk_tree_model_get(model, &iter, 0, &key, -1);
200       const char* value = ValueForKey (g_qeglobals.d_project_entity, key);
201       gtk_entry_set_text (GTK_ENTRY (text), key);
202       gtk_entry_set_text (GTK_ENTRY (cmd), value);
203       g_free(key);
204     }
205   }
206
207   gtk_grab_add (dlg);
208   gtk_widget_show (dlg);
209
210   while (loop)
211     gtk_main_iteration ();
212
213   if (ret == IDOK)
214   {
215     const char* key = gtk_entry_get_text (GTK_ENTRY (text));
216     const char* value = gtk_entry_get_text (GTK_ENTRY (cmd));
217
218     if (strlen (key) <= 0 || strlen (value) <= 0)
219     {
220       Sys_Printf ("Command not added\n");
221     }
222     else
223     {
224       if (edit)
225       {
226         SetKeyValue (g_qeglobals.d_project_entity, key, value);
227         FillBSPMenu ();
228       }
229       else
230       {
231               if (key[0] == 'b' && key[1] == 's' && key[2] == 'p')
232               {
233                 SetKeyValue (g_qeglobals.d_project_entity, key, value);
234                 FillBSPMenu ();
235               }
236               else
237                 Sys_Printf ("BSP commands must be preceded by \"bsp\"");
238       }
239
240       UpdateBSPCommandList (parent);
241     }
242   }
243
244   gtk_grab_remove (dlg);
245   gtk_widget_destroy (dlg);
246 }
247
248 static void UpdateBSPCommandList (GtkWidget *dialog)
249 {
250   GtkListStore* store = GTK_LIST_STORE (g_object_get_data (G_OBJECT(dialog), "bsp_commands"));
251
252   gtk_list_store_clear(store);
253
254   for(epair_t* ep = g_qeglobals.d_project_entity->epairs; ep != NULL; ep = ep->next)
255   {
256     if(ep->key[0] == 'b' && ep->key[1] == 's' && ep->key[2] == 'p')
257     {
258       GtkTreeIter iter;
259       gtk_list_store_append(store, &iter);
260       gtk_list_store_set(store, &iter, 0, ep->key, -1);
261     }
262   }
263 }
264
265 static void project_add (GtkWidget *widget, gpointer data)
266 {
267   GtkWidget *dlg = GTK_WIDGET (data);
268   DoProjectAddEdit (false, dlg);
269   UpdateBSPCommandList (dlg);
270 }
271
272 static void project_change (GtkWidget *widget, gpointer data)
273 {
274   GtkWidget *dlg = GTK_WIDGET (data);
275   DoProjectAddEdit (true, dlg);
276   UpdateBSPCommandList (dlg);
277 }
278
279 static void project_remove (GtkWidget *widget, gpointer data)
280 {
281   GtkWidget* project = GTK_WIDGET(data);
282
283   GtkTreeView* view = GTK_TREE_VIEW (g_object_get_data (G_OBJECT(project), "view"));
284   GtkTreeSelection* selection = gtk_tree_view_get_selection(view);
285   GtkTreeIter iter;
286   GtkTreeModel* model;
287   if(gtk_tree_selection_get_selected(selection, &model, &iter))
288   {
289     char* key;
290     gtk_tree_model_get(model, &iter, 0, &key, -1);
291     DeleteKey (g_qeglobals.d_project_entity, key);
292     g_free(key);
293
294     char* index = gtk_tree_model_get_string_from_iter(model, &iter);
295     Sys_Printf ("Selected %s\n", index);
296     g_free(index);
297
298     UpdateBSPCommandList(project);
299     FillBSPMenu();
300   }
301 }
302
303 static const char* sQ3ComboItem = "Quake III Arena";
304 static const char* sTAComboItem = "Quake III: Team Arena";
305 static const char* sModComboItem = "Custom Quake III modification";
306 static const char* sWolfComboItem = "Return To Castle Wolfenstein";
307 static const char* sWolfModComboItem = "Custom RTCW modification";
308 static const char* sHLComboItem = "Half-life";
309 static const char* sHLModComboItem = "Custom Half-life modification";
310
311 static const char* sWolfSPCombo = "Single Player mapping mode";
312 static const char* sWolfMPCombo = "Multiplayer mapping mode";
313
314 // Arnout
315 // HARD-CODED ET HACK
316 static const char* sETComboItem = "Wolfenstein: Enemy Territory";
317 static const char* sETModComboItem = "Custom ET modification";
318
319 // RIANT
320 // HARD-CODED JK2 HACK
321 static const char* sJK2ComboItem = "Jedi Knight II Outcast";
322 static const char* sJK2ModComboItem = "Custom JK2 modification";
323 static const char* sJK2SPCombo = "Single Player mapping mode";
324 static const char* sJK2MPCombo = "Multiplayer mapping mode";
325
326 // TTimo
327 // HARD-CODED JA HACK
328 static const char* sJAComboItem = "Jedi Knight Jedi Academy";
329 static const char* sJAModComboItem = "Custom JA modification";
330 static const char* sJASPCombo = "Single Player mapping mode";
331 static const char* sJAMPCombo = "Multiplayer mapping mode";
332
333 // RIANT
334 // HARD-CODED STVEF2 HACK
335 static const char* sSTVEFComboItem = "Star Trek Voyager : Elite Force";
336 static const char* sSTVEFModComboItem = "Custom Elite Force modification";
337 static const char* sSTVEFSPCombo = "Single Player mapping mode";
338 static const char* sSTVEFMPCombo = "Holo Match mapping mode";
339
340 // RIANT
341 // HARD-CODED SOF2 HACK
342 static const char* sSOF2ComboItem = "Soldier of Fortune II - Double Helix";
343 static const char* sSOF2ModComboItem = "Custom Sof2 modification";
344 static const char* sSOF2SPCombo = "Single Player mapping mode";
345 static const char* sSOF2MPCombo = "Multiplayer mapping mode";
346
347 static GtkWidget* game_select; // GTK_COMBO
348 static GtkEntry* fsgame_entry;
349
350 gint OnSelchangeComboWhatgame (GtkWidget *widget, GdkEvent* event, gpointer data)
351 {
352   const char *dir = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(game_select)->entry));
353   // HACK: Wolf
354   if (g_pGameDescription->mGameFile == "wolf.game")
355   {
356     if (!strcmp(dir,sWolfComboItem))
357     {
358       // disable the fs_game text entry
359       gtk_entry_set_text (fsgame_entry, "");
360       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
361     }
362     else
363     {
364       gtk_entry_set_text (fsgame_entry, "");
365       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), true);
366     }
367
368   }
369   // HACK: ET
370   else if (g_pGameDescription->mGameFile == "et.game")
371   {
372     if (!strcmp(dir,sETComboItem))
373     {
374       // disable the fs_game text entry
375       gtk_entry_set_text (fsgame_entry, "");
376       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
377     }
378     else
379     {
380       gtk_entry_set_text (fsgame_entry, "");
381       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), true);
382     }
383
384   }
385   else if (g_pGameDescription->mGameFile == "hl.game")
386   {
387     if (!strcmp(dir,sHLComboItem))
388     {
389       // disable the fs_game text entry
390       gtk_entry_set_text (fsgame_entry, "");
391       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
392     }
393     else
394     {
395       gtk_entry_set_text (fsgame_entry, "");
396       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), true);
397     }
398
399   }
400   // RIANT
401   // HACK: JK2
402   else if (g_pGameDescription->mGameFile == "jk2.game")
403   {
404     if (!strcmp(dir,sJK2ComboItem))
405     {
406       // disable the fs_game text entry
407       gtk_entry_set_text (fsgame_entry, "");
408       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
409     }
410     else
411     {
412       gtk_entry_set_text (fsgame_entry, "");
413       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), true);
414     }
415   }
416   // TTimo
417   // HACK: JA
418   else if (g_pGameDescription->mGameFile == "ja.game")
419   {
420     if (!strcmp(dir,sJAComboItem))
421     {
422       // disable the fs_game text entry
423       gtk_entry_set_text (fsgame_entry, "");
424       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
425     }
426     else
427     {
428       gtk_entry_set_text (fsgame_entry, "");
429       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), true);
430     }
431   }
432   // RIANT
433   // HACK: STVEF
434   else if (g_pGameDescription->mGameFile == "stvef.game")
435   {
436     if (!strcmp(dir,sSTVEFComboItem))
437     {
438       // disable the fs_game text entry
439       gtk_entry_set_text (fsgame_entry, "");
440       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
441     }
442     else
443     {
444       gtk_entry_set_text (fsgame_entry, "");
445       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), true);
446     }
447   }
448   // RIANT
449   // HACK: SOF2
450   else if (g_pGameDescription->mGameFile == "sof2.game")
451   {
452     if (!strcmp(dir,sSOF2ComboItem))
453     {
454       // disable the fs_game text entry
455       gtk_entry_set_text (fsgame_entry, "");
456       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
457     }
458     else
459     {
460       gtk_entry_set_text (fsgame_entry, "");
461       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), true);
462     }
463   }
464   // QUAKE 3
465   else
466   {
467     if (!strcmp(dir,sQ3ComboItem))
468     {
469       // disable the fs_game text entry
470       gtk_entry_set_text (fsgame_entry, "");
471       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
472     }
473     else if (!strcmp(dir,sTAComboItem))
474     {
475       gtk_entry_set_text (fsgame_entry, "missionpack");
476       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), false);
477     }
478     else
479     {
480       gtk_entry_set_text (fsgame_entry, "");
481       gtk_widget_set_sensitive(GTK_WIDGET(fsgame_entry), true);
482     }
483   }
484
485   return TRUE;
486 }
487
488 void DoProjectSettings ()
489 {
490   GtkWidget *project;
491   GtkWidget *frame, *label, *vbox, *table1, *table2, *button;
492   GtkWidget *brush;
493   GtkWidget *scr;
494   GtkWidget *base, *game;
495   GtkWidget *gamemode_combo;
496   GList *combo_list = (GList*)NULL;
497
498   int loop = 1, ret = IDCANCEL;
499
500   project = gtk_window_new (GTK_WINDOW_TOPLEVEL);
501   gtk_window_set_title (GTK_WINDOW (project), "Project Settings");
502   gtk_signal_connect (GTK_OBJECT (project), "delete_event",
503                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
504   gtk_signal_connect (GTK_OBJECT (project), "destroy",
505                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
506   g_object_set_data (G_OBJECT (project), "loop", &loop);
507   g_object_set_data (G_OBJECT (project), "ret", &ret);
508   gtk_window_set_default_size (GTK_WINDOW (project), 550, 400);
509
510   table1 = gtk_table_new (3, 2, FALSE);
511   gtk_widget_show (table1);
512   gtk_container_add (GTK_CONTAINER (project), table1);
513   gtk_container_set_border_width (GTK_CONTAINER (table1), 5);
514   gtk_table_set_row_spacings (GTK_TABLE (table1), 5);
515   gtk_table_set_col_spacings (GTK_TABLE (table1), 5);
516
517   vbox = gtk_vbox_new (FALSE, 5);
518   gtk_widget_show (vbox);
519   gtk_table_attach (GTK_TABLE (table1), vbox, 1, 2, 0, 1,
520                     (GtkAttachOptions) (GTK_FILL),
521                     (GtkAttachOptions) (GTK_FILL), 0, 0);
522
523   button = gtk_button_new_with_label ("OK");
524   gtk_widget_show (button);
525   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
526   gtk_signal_connect (GTK_OBJECT (button), "clicked",
527                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
528   gtk_widget_set_usize (button, 60, -2);
529
530   button = gtk_button_new_with_label ("Cancel");
531   gtk_widget_show (button);
532   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
533   gtk_signal_connect (GTK_OBJECT (button), "clicked",
534                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
535   gtk_widget_set_usize (button, 60, -2);
536
537   vbox = gtk_vbox_new (FALSE, 5);
538   gtk_widget_show (vbox);
539   gtk_table_attach (GTK_TABLE (table1), vbox, 1, 2, 1, 2,
540                     (GtkAttachOptions) (GTK_FILL),
541                     (GtkAttachOptions) (GTK_FILL), 0, 0);
542
543   button = gtk_button_new_with_label ("Add...");
544   gtk_widget_show (button);
545   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
546   gtk_signal_connect (GTK_OBJECT (button), "clicked",
547                       GTK_SIGNAL_FUNC (project_add), project);
548   gtk_widget_set_usize (button, 60, -2);
549
550   button = gtk_button_new_with_label ("Change...");
551   gtk_widget_show (button);
552   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
553   gtk_signal_connect (GTK_OBJECT (button), "clicked",
554                       GTK_SIGNAL_FUNC (project_change), project);
555   gtk_widget_set_usize (button, 60, -2);
556
557   button = gtk_button_new_with_label ("Remove");
558   gtk_widget_show (button);
559   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
560   gtk_signal_connect (GTK_OBJECT (button), "clicked",
561                       GTK_SIGNAL_FUNC (project_remove), project);
562   gtk_widget_set_usize (button, 60, -2);
563
564   frame = gtk_frame_new ("Misc settings");
565   gtk_widget_show (frame);
566   gtk_table_attach (GTK_TABLE (table1), frame, 0, 1, 2, 3,
567                     (GtkAttachOptions) (GTK_FILL),
568                     (GtkAttachOptions) (GTK_FILL), 0, 0);
569
570   brush = gtk_check_button_new_with_label ("Use brush primitives in MAP files (NOTE: experimental feature,\n"
571                                            "required by the texture tools plugin)");
572   gtk_widget_show (brush);
573   gtk_container_add (GTK_CONTAINER (frame), brush);
574   gtk_container_set_border_width (GTK_CONTAINER (brush), 5);
575
576   frame = gtk_frame_new ("Menu commands");
577   gtk_widget_show (frame);
578   gtk_table_attach (GTK_TABLE (table1), frame, 0, 1, 1, 2,
579                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
580                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
581
582   scr = gtk_scrolled_window_new ((GtkAdjustment*)NULL, (GtkAdjustment*)NULL);
583   gtk_widget_show (scr);
584   gtk_container_add (GTK_CONTAINER (frame), scr);
585   gtk_container_set_border_width (GTK_CONTAINER (scr), 5);
586   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
587   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
588
589
590   {
591     GtkListStore* store = gtk_list_store_new(1, G_TYPE_STRING);
592
593     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
594     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
595
596     GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
597     GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
598     gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
599
600     GtkTreeSelection* selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
601     gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
602
603     gtk_widget_show(view);
604
605     g_object_set_data(G_OBJECT (project), "view", view);
606     g_object_set_data(G_OBJECT (project), "bsp_commands", store);
607     gtk_container_add(GTK_CONTAINER (scr), view);
608
609     g_object_unref(G_OBJECT(store));
610   }
611
612   frame = gtk_frame_new ("Project settings");
613   gtk_widget_show (frame);
614   gtk_table_attach (GTK_TABLE (table1), frame, 0, 1, 0, 1,
615                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
616                     (GtkAttachOptions) (GTK_FILL), 0, 0);
617
618   // HACK: hardcoded game stuff
619   if (g_pGameDescription->mGameFile == "wolf.game" ||
620     g_pGameDescription->mGameFile == "et.game" ||
621     g_pGameDescription->mGameFile == "jk2.game" ||
622     g_pGameDescription->mGameFile == "stvef.game" ||
623     g_pGameDescription->mGameFile == "sof2.game" ||
624     g_pGameDescription->mGameFile == "ja.game" )
625   {
626     table2 = gtk_table_new (9, 2, FALSE);
627   }
628   else
629   {
630     table2 = gtk_table_new (8, 2, FALSE);
631   }
632   gtk_widget_show (table2);
633   gtk_container_add (GTK_CONTAINER (frame), table2);
634   gtk_container_set_border_width (GTK_CONTAINER (table2), 5);
635   gtk_table_set_row_spacings (GTK_TABLE (table2), 5);
636   gtk_table_set_col_spacings (GTK_TABLE (table2), 5);
637
638   /*
639   fill in the game selection combo
640   HACK: hardcoded Q3/Wolf/HL switch
641   \todo that stuff would be faster to write with implementation of property bags and associated code to edit
642   */
643   if (g_pGameDescription->mGameFile == "wolf.game")
644   {
645     combo_list = g_list_append (combo_list, (void *)sWolfComboItem);
646     combo_list = g_list_append (combo_list, (void *)sWolfModComboItem);
647   }
648   else if (g_pGameDescription->mGameFile == "et.game")
649   {
650     combo_list = g_list_append (combo_list, (void *)sETComboItem);
651     combo_list = g_list_append (combo_list, (void *)sETModComboItem);
652   }
653   else if (g_pGameDescription->mGameFile == "hl.game")
654   {
655     combo_list = g_list_append (combo_list, (void *)sHLComboItem);
656     combo_list = g_list_append (combo_list, (void *)sHLModComboItem);
657   }
658   // RIANT
659   // JK2 HACK
660   else if (g_pGameDescription->mGameFile == "jk2.game")
661   {
662     combo_list = g_list_append (combo_list, (void *)sJK2ComboItem);
663     combo_list = g_list_append (combo_list, (void *)sJK2ModComboItem);
664   }
665   // TTimo
666   // JA HACK
667   else if (g_pGameDescription->mGameFile == "ja.game")
668   {
669     combo_list = g_list_append (combo_list, (void *)sJAComboItem);
670     combo_list = g_list_append (combo_list, (void *)sJAModComboItem);
671   }
672   // RIANT
673   // STVEF HACK
674   else if (g_pGameDescription->mGameFile == "stvef.game")
675   {
676     combo_list = g_list_append (combo_list, (void *)sSTVEFComboItem);
677     combo_list = g_list_append (combo_list, (void *)sSTVEFModComboItem);
678   }
679   // RIANT
680   // SOF2 HACK A LA JK2 A LA WOLF
681   else if (g_pGameDescription->mGameFile == "sof2.game")
682   {
683     combo_list = g_list_append (combo_list, (void *)sSOF2ComboItem);
684     combo_list = g_list_append (combo_list, (void *)sSOF2ModComboItem);
685   }
686   else
687   {
688     // Q3 or default
689     combo_list = g_list_append (combo_list, (void *)sQ3ComboItem);
690     combo_list = g_list_append (combo_list, (void *)sTAComboItem);
691     combo_list = g_list_append (combo_list, (void *)sModComboItem);
692   }
693
694   game_select = gtk_combo_new ();
695   gtk_combo_set_popdown_strings (GTK_COMBO (game_select), combo_list);
696   gtk_widget_show (game_select);
697   gtk_table_attach (GTK_TABLE (table2), game_select, 1, 2, 6, 7,
698                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
699                     (GtkAttachOptions) (0), 0, 0);
700
701   gtk_signal_connect (GTK_OBJECT(GTK_COMBO (game_select)->entry), "changed",
702     GTK_SIGNAL_FUNC (OnSelchangeComboWhatgame), NULL);
703
704   g_list_free (combo_list);
705   gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (game_select)->entry), FALSE);
706
707   game = gtk_entry_new();
708   fsgame_entry = GTK_ENTRY(game);
709   gtk_widget_show(game);
710   gtk_table_attach(GTK_TABLE(table2), game, 1, 2, 7, 8,
711                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
712                     (GtkAttachOptions) (0), 0, 0);
713
714   /*
715   wolf specific: select MP or SP mode
716   */
717   if (g_pGameDescription->mGameFile == "wolf.game")
718   {
719     combo_list = NULL;
720     combo_list = g_list_append (combo_list, (void *)sWolfSPCombo);
721     combo_list = g_list_append (combo_list, (void *)sWolfMPCombo);
722
723     gamemode_combo = gtk_combo_new ();
724     gtk_combo_set_popdown_strings (GTK_COMBO (gamemode_combo), combo_list);
725     gtk_widget_show(gamemode_combo);
726     gtk_table_attach (GTK_TABLE (table2), gamemode_combo, 1, 2, 8, 9,
727       (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
728       (GtkAttachOptions) (0), 0, 0);
729
730     g_list_free (combo_list);
731     combo_list = NULL;
732
733     label = gtk_label_new ("Mapping mode");
734     gtk_widget_show (label);
735     gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 8, 9,
736       (GtkAttachOptions) (GTK_FILL),
737       (GtkAttachOptions) (0), 0, 0);
738     gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
739   }
740
741   // RIANT
742   // JK2 HACK
743   if (g_pGameDescription->mGameFile == "jk2.game")
744   {
745     combo_list = NULL;
746     combo_list = g_list_append (combo_list, (void *)sJK2SPCombo);
747     combo_list = g_list_append (combo_list, (void *)sJK2MPCombo);
748
749     gamemode_combo = gtk_combo_new ();
750     gtk_combo_set_popdown_strings (GTK_COMBO (gamemode_combo), combo_list);
751     gtk_widget_show(gamemode_combo);
752     gtk_table_attach (GTK_TABLE (table2), gamemode_combo, 1, 2, 8, 9,
753       (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
754       (GtkAttachOptions) (0), 0, 0);
755
756     g_list_free (combo_list);
757     combo_list = NULL;
758
759     label = gtk_label_new ("Mapping mode");
760     gtk_widget_show (label);
761     gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 8, 9,
762       (GtkAttachOptions) (GTK_FILL),
763       (GtkAttachOptions) (0), 0, 0);
764     gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
765   }
766   // TTimo
767   // JA HACK
768   if (g_pGameDescription->mGameFile == "ja.game")
769   {
770     combo_list = NULL;
771     combo_list = g_list_append (combo_list, (void *)sJASPCombo);
772     combo_list = g_list_append (combo_list, (void *)sJAMPCombo);
773
774     gamemode_combo = gtk_combo_new ();
775     gtk_combo_set_popdown_strings (GTK_COMBO (gamemode_combo), combo_list);
776     gtk_widget_show(gamemode_combo);
777     gtk_table_attach (GTK_TABLE (table2), gamemode_combo, 1, 2, 8, 9,
778       (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
779       (GtkAttachOptions) (0), 0, 0);
780
781     g_list_free (combo_list);
782     combo_list = NULL;
783
784     label = gtk_label_new ("Mapping mode");
785     gtk_widget_show (label);
786     gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 8, 9,
787       (GtkAttachOptions) (GTK_FILL),
788       (GtkAttachOptions) (0), 0, 0);
789     gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
790   }
791   // RIANT
792   // STVEF HACK
793   if (g_pGameDescription->mGameFile == "stvef.game")
794   {
795     combo_list = NULL;
796     combo_list = g_list_append (combo_list, (void *)sSTVEFSPCombo);
797     combo_list = g_list_append (combo_list, (void *)sSTVEFMPCombo);
798
799     gamemode_combo = gtk_combo_new ();
800     gtk_combo_set_popdown_strings (GTK_COMBO (gamemode_combo), combo_list);
801     gtk_widget_show(gamemode_combo);
802     gtk_table_attach (GTK_TABLE (table2), gamemode_combo, 1, 2, 8, 9,
803       (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
804       (GtkAttachOptions) (0), 0, 0);
805
806     g_list_free (combo_list);
807     combo_list = NULL;
808
809     label = gtk_label_new ("Mapping mode");
810     gtk_widget_show (label);
811     gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 8, 9,
812       (GtkAttachOptions) (GTK_FILL),
813       (GtkAttachOptions) (0), 0, 0);
814     gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
815   }
816   // RIANT
817   // SOF2 HACK
818   if (g_pGameDescription->mGameFile == "sof2.game")
819   {
820     combo_list = NULL;
821     combo_list = g_list_append (combo_list, (void *)sSOF2SPCombo);
822     combo_list = g_list_append (combo_list, (void *)sSOF2MPCombo);
823
824     gamemode_combo = gtk_combo_new ();
825     gtk_combo_set_popdown_strings (GTK_COMBO (gamemode_combo), combo_list);
826     gtk_widget_show(gamemode_combo);
827     gtk_table_attach (GTK_TABLE (table2), gamemode_combo, 1, 2, 8, 9,
828       (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
829       (GtkAttachOptions) (0), 0, 0);
830
831     g_list_free (combo_list);
832     combo_list = NULL;
833
834     label = gtk_label_new ("Mapping mode");
835     gtk_widget_show (label);
836     gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 8, 9,
837       (GtkAttachOptions) (GTK_FILL),
838       (GtkAttachOptions) (0), 0, 0);
839     gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
840   }
841
842   /*
843   the usual stuff
844   */
845
846   base = gtk_entry_new ();
847   g_object_set_data (G_OBJECT (project), "base", base);
848   gtk_widget_show (base);
849   gtk_table_attach (GTK_TABLE (table2), base, 1, 2, 0, 1,
850                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
851                     (GtkAttachOptions) (0), 0, 0);
852
853
854   label = gtk_label_new ("basepath");
855   gtk_widget_show (label);
856   gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 0, 1,
857                     (GtkAttachOptions) (GTK_FILL),
858                     (GtkAttachOptions) (0), 0, 0);
859   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
860
861
862   label = gtk_label_new ("Select mod");
863   gtk_widget_show (label);
864   gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 6, 7,
865                     (GtkAttachOptions) (GTK_FILL),
866                     (GtkAttachOptions) (0), 0, 0);
867   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
868
869   label = gtk_label_new ("fs_game");
870   gtk_widget_show (label);
871   gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 7, 8,
872                     (GtkAttachOptions) (GTK_FILL),
873                     (GtkAttachOptions) (0), 0, 0);
874   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
875
876   // Initialize fields
877   gtk_entry_set_text (GTK_ENTRY (base), ValueForKey (g_qeglobals.d_project_entity, "basepath"));
878   UpdateBSPCommandList (project);
879   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (brush), (g_qeglobals.m_bBrushPrimitMode) ? TRUE : FALSE);
880
881   // initialise the fs_game selection from the project settings into the dialog
882   const char *dir = ValueForKey (g_qeglobals.d_project_entity, "gamename");
883   // HACK: hardcoded wolf stuff
884   if (g_pGameDescription->mGameFile == "wolf.game")
885   {
886     if ((strlen(dir) == 0) || !stricmp(dir,"main"))
887     {
888       // no fs_game set, we are running stock Quake III Arena editing
889       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sWolfComboItem);
890       gtk_entry_set_text (GTK_ENTRY (game), "");
891       gtk_widget_set_sensitive(game, false);
892     }
893     else
894     {
895       // this is a custom mod
896       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sWolfModComboItem);
897       gtk_entry_set_text (GTK_ENTRY (game), dir);
898       gtk_widget_set_sensitive(game, true);
899     }
900   }
901   // HACK: hardcoded et stuff
902   if (g_pGameDescription->mGameFile == "et.game")
903   {
904     if ((strlen(dir) == 0) || !stricmp(dir,"etmain"))
905     {
906       // no fs_game set, we are running stock Quake III Arena editing
907       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sETComboItem);
908       gtk_entry_set_text (GTK_ENTRY (game), "");
909       gtk_widget_set_sensitive(game, false);
910     }
911     else
912     {
913       // this is a custom mod
914       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sETModComboItem);
915       gtk_entry_set_text (GTK_ENTRY (game), dir);
916       gtk_widget_set_sensitive(game, true);
917     }
918   }
919   // HACK: hardcoded half-life stuff
920   else if (g_pGameDescription->mGameFile == "hl.game")
921   {
922     if ((strlen(dir) == 0) || !stricmp(dir,"valve"))
923     {
924       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sHLComboItem);
925       gtk_entry_set_text (GTK_ENTRY (game), "");
926       gtk_widget_set_sensitive(game, false);
927     }
928     else
929     {
930       // this is a custom mod
931       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sHLModComboItem);
932       gtk_entry_set_text (GTK_ENTRY (game), dir);
933       gtk_widget_set_sensitive(game, true);
934     }
935   }
936   // RIANT
937   // JK2 HACK
938   else if (g_pGameDescription->mGameFile == "jk2.game")
939   {
940     if ((strlen(dir) == 0) || !stricmp(dir,"base"))
941     {
942       // no fs_game set, we are running stock Quake III Arena editing
943       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sJK2ComboItem);
944       gtk_entry_set_text (GTK_ENTRY (game), "");
945       gtk_widget_set_sensitive(game, false);
946     }
947     else
948     {
949       // this is a custom mod
950       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sJK2ModComboItem);
951       gtk_entry_set_text (GTK_ENTRY (game), dir);
952       gtk_widget_set_sensitive(game, true);
953     }
954   }
955   // TTimo
956   // JA HACK
957   else if (g_pGameDescription->mGameFile == "ja.game")
958   {
959     if ((strlen(dir) == 0) || !stricmp(dir,"base"))
960     {
961       // no fs_game set, we are running stock editing
962       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sJAComboItem);
963       gtk_entry_set_text (GTK_ENTRY (game), "");
964       gtk_widget_set_sensitive(game, false);
965     }
966     else
967     {
968       // this is a custom mod
969       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sJAModComboItem);
970       gtk_entry_set_text (GTK_ENTRY (game), dir);
971       gtk_widget_set_sensitive(game, true);
972     }
973   }
974   // RIANT
975   // STVEF2 HACK
976   else if (g_pGameDescription->mGameFile == "stvef.game")
977   {
978     if ((strlen(dir) == 0) || !stricmp(dir,"baseEf"))
979     {
980       // no fs_game set, we are running stock Quake III Arena editing
981       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sSTVEFComboItem);
982       gtk_entry_set_text (GTK_ENTRY (game), "");
983       gtk_widget_set_sensitive(game, false);
984     }
985     else
986     {
987       // this is a custom mod
988       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sSTVEFModComboItem);
989       gtk_entry_set_text (GTK_ENTRY (game), dir);
990       gtk_widget_set_sensitive(game, true);
991     }
992   }
993   // RIANT
994   // SOF2 HACK
995   else if (g_pGameDescription->mGameFile == "sof2.game")
996   {
997     if ((strlen(dir) == 0) || !stricmp(dir,"base"))
998     {
999       // no fs_game set, we are running stock Quake III Arena editing
1000       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sSOF2ComboItem);
1001       gtk_entry_set_text (GTK_ENTRY (game), "");
1002       gtk_widget_set_sensitive(game, false);
1003     }
1004     else
1005     {
1006       // this is a custom mod
1007       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sSOF2ModComboItem);
1008       gtk_entry_set_text (GTK_ENTRY (game), dir);
1009       gtk_widget_set_sensitive(game, true);
1010     }
1011   }
1012   else
1013   {
1014     if ((strlen(dir) == 0) || !strcmp(dir,"baseq3"))
1015     {
1016       // no fs_game set, we are running stock Quake III Arena editing
1017       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sQ3ComboItem);
1018       gtk_entry_set_text (GTK_ENTRY (game), "");
1019       gtk_widget_set_sensitive(game, false);
1020     }
1021     else if (!strcmp(dir,"missionpack"))
1022     {
1023       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sTAComboItem);
1024       gtk_entry_set_text (GTK_ENTRY (game), "missionpack");
1025       gtk_widget_set_sensitive(game, false);
1026     }
1027     else
1028     {
1029       // this is a custom mod
1030       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (game_select)->entry), sModComboItem);
1031       gtk_entry_set_text (GTK_ENTRY (game), dir);
1032       gtk_widget_set_sensitive(game, true);
1033     }
1034   }
1035
1036   // HACK: hardcoded wolf stuff
1037   if (g_pGameDescription->mGameFile == "wolf.game")
1038   {
1039     const char *gamemode = ValueForKey (g_qeglobals.d_project_entity, "gamemode");
1040     if ((strlen(gamemode) == 0) || !strcmp(gamemode,"sp"))
1041     {
1042       // nothing set yet, or single player
1043       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sWolfSPCombo);
1044     }
1045     else
1046     {
1047       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sWolfMPCombo);
1048     }
1049   }
1050
1051   // JK2 HACK
1052   else if (g_pGameDescription->mGameFile == "jk2.game")
1053   {
1054     const char *gamemode = ValueForKey (g_qeglobals.d_project_entity, "gamemode");
1055     if ((strlen(gamemode) == 0) || !strcmp(gamemode,"sp"))
1056     {
1057       // nothing set yet, or single player
1058       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sJK2SPCombo);
1059     }
1060     else
1061     {
1062       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sJK2MPCombo);
1063     }
1064   }
1065   // JA HACK
1066   else if (g_pGameDescription->mGameFile == "ja.game")
1067   {
1068     const char *gamemode = ValueForKey (g_qeglobals.d_project_entity, "gamemode");
1069     if ((strlen(gamemode) == 0) || !strcmp(gamemode,"sp"))
1070     {
1071       // nothing set yet, or single player
1072       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sJASPCombo);
1073     }
1074     else
1075     {
1076       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sJAMPCombo);
1077     }
1078   }
1079   // STVEF HACK
1080   else if (g_pGameDescription->mGameFile == "stvef.game")
1081   {
1082     const char *gamemode = ValueForKey (g_qeglobals.d_project_entity, "gamemode");
1083     if ((strlen(gamemode) == 0) || !strcmp(gamemode,"sp"))
1084     {
1085       // nothing set yet, or single player
1086       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sSTVEFSPCombo);
1087     }
1088     else
1089     {
1090       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sSTVEFMPCombo);
1091     }
1092   }
1093   // SOF2 HACK
1094   else if (g_pGameDescription->mGameFile == "sof2.game")
1095   {
1096     const char *gamemode = ValueForKey (g_qeglobals.d_project_entity, "gamemode");
1097     if ((strlen(gamemode) == 0) || !strcmp(gamemode,"sp"))
1098     {
1099       // nothing set yet, or single player
1100       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sSOF2SPCombo);
1101     }
1102     else
1103     {
1104       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gamemode_combo)->entry), sSOF2MPCombo);
1105     }
1106   }
1107
1108   gtk_grab_add (project);
1109   gtk_widget_show (project);
1110
1111   g_pGameDescription->Dump();
1112
1113   while (loop)
1114     gtk_main_iteration ();
1115
1116   if (ret == IDOK)
1117   {
1118     char buf[1024];
1119     const char *r;
1120     char *w;
1121
1122     // convert path to unix format
1123     for(r = gtk_entry_get_text (GTK_ENTRY (base)), w=buf; *r != '\0'; r++, w++)
1124       *w = (*r == '\\') ? '/' : *r;
1125     // add last slash
1126     if(w != buf && *(w-1) != '/') *(w++) = '/';
1127     // terminate string
1128     *w = '\0';
1129     SetKeyValue (g_qeglobals.d_project_entity, "basepath", buf);
1130
1131     dir = gtk_entry_get_text (GTK_ENTRY (game));
1132     // Hack: hard coded wolf stuff
1133     if (g_pGameDescription->mGameFile == "wolf.game")
1134     {
1135       if (!strlen(dir) || !stricmp(dir,"main"))
1136       {
1137         DeleteKey (g_qeglobals.d_project_entity, "gamename");
1138       }
1139       else
1140       {
1141         SetKeyValue (g_qeglobals.d_project_entity, "gamename", dir);
1142       }
1143     }
1144     // Hack: hard coded ET stuff
1145     else if (g_pGameDescription->mGameFile == "et.game")
1146     {
1147       if (!strlen(dir) || !stricmp(dir,"etmain"))
1148       {
1149         DeleteKey (g_qeglobals.d_project_entity, "gamename");
1150       }
1151       else
1152       {
1153         SetKeyValue (g_qeglobals.d_project_entity, "gamename", dir);
1154       }
1155     }
1156     // Hack: hard coded Half-life stuff
1157     else if (g_pGameDescription->mGameFile == "hl.game")
1158     {
1159       if (!strlen(dir) || !stricmp(dir,"valve"))
1160       {
1161         DeleteKey (g_qeglobals.d_project_entity, "gamename");
1162       }
1163       else
1164       {
1165         SetKeyValue (g_qeglobals.d_project_entity, "gamename", dir);
1166       }
1167     }
1168     else if (g_pGameDescription->mGameFile == "jk2.game" || g_pGameDescription->mGameFile == "ja.game")
1169     {
1170       if (!strlen(dir) || !stricmp(dir,"base"))
1171       {
1172         DeleteKey (g_qeglobals.d_project_entity, "gamename");
1173       }
1174       else
1175       {
1176         SetKeyValue (g_qeglobals.d_project_entity, "gamename", dir);
1177       }
1178     }
1179     // RIANT
1180     // STVEF HACK
1181     else if (g_pGameDescription->mGameFile == "stvef.game")
1182     {
1183       if (!strlen(dir) || !stricmp(dir,"baseEf"))
1184       {
1185         DeleteKey (g_qeglobals.d_project_entity, "gamename");
1186       }
1187       else
1188       {
1189         SetKeyValue (g_qeglobals.d_project_entity, "gamename", dir);
1190       }
1191     }
1192     else
1193     {
1194       if (!strlen(dir) || !strcmp(dir,"baseq3"))
1195       {
1196         DeleteKey (g_qeglobals.d_project_entity, "gamename");
1197       }
1198       else
1199       {
1200         SetKeyValue (g_qeglobals.d_project_entity, "gamename", dir);
1201       }
1202     }
1203
1204     // HACK: hardcoded wolf stuff
1205     if (g_pGameDescription->mGameFile == "wolf.game")
1206     {
1207       // read from gamemode_combo
1208       const char *gamemode = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(gamemode_combo)->entry));
1209       if (!strlen(gamemode) || !strcmp(gamemode, sWolfSPCombo))
1210       {
1211         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "sp");
1212       }
1213       else
1214       {
1215         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "mp");
1216       }
1217     }
1218
1219     // RIANT
1220     // JK2 HACK
1221     if (g_pGameDescription->mGameFile == "jk2.game")
1222     {
1223       // read from gamemode_combo
1224       const char *gamemode = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(gamemode_combo)->entry));
1225       if (!strlen(gamemode) || !strcmp(gamemode, sJK2SPCombo))
1226       {
1227         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "sp");
1228       }
1229       else
1230       {
1231         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "mp");
1232       }
1233     }
1234     // TTimo
1235     // JA HACK
1236     if (g_pGameDescription->mGameFile == "ja.game")
1237     {
1238       // read from gamemode_combo
1239       const char *gamemode = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(gamemode_combo)->entry));
1240       if (!strlen(gamemode) || !strcmp(gamemode, sJASPCombo))
1241       {
1242         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "sp");
1243       }
1244       else
1245       {
1246         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "mp");
1247       }
1248     }
1249
1250     // RIANT
1251     // STVEF HACK
1252     if (g_pGameDescription->mGameFile == "stvef.game")
1253     {
1254       // read from gamemode_combo
1255       const char *gamemode = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(gamemode_combo)->entry));
1256       if (!strlen(gamemode) || !strcmp(gamemode, sSTVEFSPCombo))
1257       {
1258         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "sp");
1259       }
1260       else
1261       {
1262         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "mp");
1263       }
1264     }
1265
1266     g_qeglobals.m_strHomeMaps = g_qeglobals.m_strHomeGame;
1267     const char* str = ValueForKey(g_qeglobals.d_project_entity, "gamename");
1268     if(str[0] == '\0') str = g_pGameDescription->mBaseGame.GetBuffer();
1269     g_qeglobals.m_strHomeMaps += str;
1270     g_qeglobals.m_strHomeMaps += '/';
1271
1272     // RIANT
1273     // SOF2 HACK
1274     if (g_pGameDescription->mGameFile == "sof2.game")
1275     {
1276       // read from gamemode_combo
1277       const char *gamemode = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(gamemode_combo)->entry));
1278       if (!strlen(gamemode) || !strcmp(gamemode, sSOF2SPCombo))
1279       {
1280         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "sp");
1281       }
1282       else
1283       {
1284         SetKeyValue (g_qeglobals.d_project_entity, "gamemode", "mp");
1285       }
1286     }
1287
1288     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (brush)))
1289       g_qeglobals.m_bBrushPrimitMode = TRUE;
1290     else
1291       g_qeglobals.m_bBrushPrimitMode = FALSE;
1292
1293     SetKeyValue(g_qeglobals.d_project_entity, "brush_primit", (g_qeglobals.m_bBrushPrimitMode ? "1" : "0" ));
1294
1295     QE_SaveProject( g_PrefsDlg.m_strLastProject.GetBuffer() );
1296   }
1297
1298   gtk_grab_remove (project);
1299   gtk_widget_destroy (project);
1300 }
1301
1302 // =============================================================================
1303 // MapInfo dialog
1304
1305 void DoMapInfo ()
1306 {
1307   static GtkWidget *dlg;
1308   GtkWidget *vbox, *vbox2, *hbox, *table, *button, *label, *scr;
1309   GtkWidget *brushes_entry, *entities_entry, *net_entry;
1310   int loop = 1, ret = IDCANCEL;
1311
1312   if (dlg != NULL)
1313     return;
1314
1315   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1316
1317   load_window_pos(dlg, g_PrefsDlg.mWindowInfo.posMapInfoWnd);
1318
1319   gtk_window_set_title (GTK_WINDOW (dlg), "Map Info");
1320   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
1321                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
1322   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
1323                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
1324   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
1325   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
1326
1327   vbox = gtk_vbox_new (FALSE, 5);
1328   gtk_widget_show (vbox);
1329   gtk_container_add (GTK_CONTAINER (dlg), vbox);
1330   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
1331
1332   hbox = gtk_hbox_new (FALSE, 5);
1333   gtk_widget_show (hbox);
1334   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1335
1336   table = gtk_table_new (3, 2, FALSE);
1337   gtk_widget_show (table);
1338   gtk_box_pack_start (GTK_BOX (hbox), table, TRUE, TRUE, 0);
1339   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1340   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1341
1342   brushes_entry = gtk_entry_new ();
1343   gtk_widget_show (brushes_entry);
1344   gtk_table_attach (GTK_TABLE (table), brushes_entry, 1, 2, 0, 1,
1345                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1346                     (GtkAttachOptions) (0), 0, 0);
1347   gtk_entry_set_editable (GTK_ENTRY (brushes_entry), FALSE);
1348
1349   entities_entry = gtk_entry_new ();
1350   gtk_widget_show (entities_entry);
1351   gtk_table_attach (GTK_TABLE (table), entities_entry, 1, 2, 1, 2,
1352                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1353                     (GtkAttachOptions) (0), 0, 0);
1354   gtk_entry_set_editable (GTK_ENTRY (entities_entry), FALSE);
1355
1356   net_entry = gtk_entry_new ();
1357   gtk_widget_show (net_entry);
1358   gtk_table_attach (GTK_TABLE (table), net_entry, 1, 2, 2, 3,
1359                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1360                     (GtkAttachOptions) (0), 0, 0);
1361   gtk_entry_set_editable (GTK_ENTRY (net_entry), FALSE);
1362
1363   label = gtk_label_new ("Total Brushes");
1364   gtk_widget_show (label);
1365   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
1366                     (GtkAttachOptions) (GTK_FILL),
1367                     (GtkAttachOptions) (0), 0, 0);
1368   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1369
1370   label = gtk_label_new ("Total Entities");
1371   gtk_widget_show (label);
1372   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
1373                     (GtkAttachOptions) (GTK_FILL),
1374                     (GtkAttachOptions) (0), 0, 0);
1375   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1376
1377   label = gtk_label_new ("Net brush count\n(non entity)");
1378   gtk_widget_show (label);
1379   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
1380                     (GtkAttachOptions) (GTK_FILL),
1381                     (GtkAttachOptions) (0), 0, 0);
1382   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1383
1384   vbox2 = gtk_vbox_new (FALSE, 5);
1385   gtk_widget_show (vbox2);
1386   gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
1387
1388   button = gtk_button_new_with_label ("Close");
1389   gtk_widget_show (button);
1390   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1391   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1392                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
1393   gtk_widget_set_usize (button, 60, -2);
1394
1395   label = gtk_label_new ("Entity breakdown");
1396   gtk_widget_show (label);
1397   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
1398   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1399
1400   scr = gtk_scrolled_window_new ((GtkAdjustment*)NULL, (GtkAdjustment*)NULL);
1401   gtk_widget_show (scr);
1402   gtk_box_pack_start (GTK_BOX (vbox), scr, TRUE, TRUE, 0);
1403   gtk_container_set_border_width (GTK_CONTAINER (scr), 5);
1404   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1405
1406   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scr), GTK_SHADOW_IN);
1407
1408   GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
1409
1410   {
1411     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1412     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(view), TRUE);
1413
1414     {
1415       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1416       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Entity", renderer, "text", 0, NULL);
1417       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1418       gtk_tree_view_column_set_sort_column_id(column, 0);
1419     }
1420
1421     {
1422       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1423       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Count", renderer, "text", 1, NULL);
1424       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1425       gtk_tree_view_column_set_sort_column_id(column, 1);
1426     }
1427
1428     gtk_widget_show(view);
1429
1430     gtk_container_add(GTK_CONTAINER (scr), view);
1431   }
1432
1433   // Initialize fields
1434   int TotalBrushes = 0, TotalEntities = 0, Net = 0;
1435
1436   for (brush_t* pBrush = active_brushes.next; pBrush != &active_brushes; pBrush = pBrush->next)
1437   {
1438     TotalBrushes++;
1439     if (pBrush->owner == world_entity)
1440       Net++;
1441   }
1442
1443   typedef struct
1444   {
1445     const char *name;
1446     int count;
1447   } map_t;
1448
1449   GSList *l, *entitymap = NULL;
1450   map_t *entry;
1451
1452   for (entity_t* pEntity = entities.next; pEntity != &entities; pEntity=pEntity->next)
1453   {
1454     TotalEntities++;
1455     bool add = true;
1456
1457     for (l = entitymap; l; l = g_slist_next (l))
1458     {
1459       entry = (map_t*)l->data;
1460
1461       if (strcmp (entry->name, pEntity->eclass->name) == 0)
1462       {
1463               entry->count++;
1464               add = false;
1465               break;
1466       }
1467     }
1468
1469     if (add)
1470     {
1471       entry = (map_t*)qmalloc (sizeof (map_t));
1472       entry->name = pEntity->eclass->name;
1473       entry->count = 1;
1474       entitymap = g_slist_append (entitymap, entry);
1475     }
1476   }
1477
1478   while (entitymap)
1479   {
1480     entry = (map_t*)entitymap->data;
1481     char tmp[16];
1482     sprintf (tmp, "%d", entry->count);
1483     GtkTreeIter iter;
1484     gtk_list_store_append(GTK_LIST_STORE(store), &iter);
1485     gtk_list_store_set(GTK_LIST_STORE(store), &iter, 0, entry->name, 1, tmp, -1);
1486     free (entry);
1487     entitymap = g_slist_remove (entitymap, entry);
1488   }
1489
1490   g_object_unref(G_OBJECT(store));
1491
1492   char tmp[16];
1493   sprintf (tmp, "%d", TotalBrushes);
1494   gtk_entry_set_text (GTK_ENTRY (brushes_entry), tmp);
1495   sprintf (tmp, "%d", TotalEntities);
1496   gtk_entry_set_text (GTK_ENTRY (entities_entry), tmp);
1497   sprintf (tmp, "%d", Net);
1498   gtk_entry_set_text (GTK_ENTRY (net_entry), tmp);
1499
1500   gtk_grab_add (dlg);
1501   gtk_widget_show (dlg);
1502
1503   while (loop)
1504     gtk_main_iteration ();
1505
1506   // save before exit
1507   save_window_pos(dlg, g_PrefsDlg.mWindowInfo.posMapInfoWnd);
1508
1509   gtk_grab_remove (dlg);
1510   gtk_widget_destroy (dlg);
1511   dlg = NULL;
1512 }
1513
1514 // =============================================================================
1515 // Entity List dialog
1516
1517 static void entitylist_select (GtkWidget *widget, gpointer data)
1518 {
1519   GtkTreeView* view = GTK_TREE_VIEW(g_object_get_data (G_OBJECT (data), "entities"));
1520
1521   GtkTreeSelection* selection = gtk_tree_view_get_selection(view);
1522
1523   GtkTreeModel* model;
1524   GtkTreeIter selected;
1525   if(gtk_tree_selection_get_selected(selection, &model, &selected))
1526   {
1527     entity_t* pEntity;
1528     gtk_tree_model_get(model, &selected, 1, &pEntity, -1);
1529
1530     if (pEntity)
1531     {
1532       for (epair_t* pEpair = pEntity->epairs; pEpair; pEpair = pEpair->next)
1533       {
1534               Select_Deselect ();
1535               Select_Brush (pEntity->brushes.onext);
1536               Sys_UpdateWindows(W_ALL);
1537       }
1538     }
1539   }
1540 }
1541
1542 static gint entitylist_click (GtkWidget *widget, GdkEventButton *event, gpointer data)
1543 {
1544   if (event->type == GDK_2BUTTON_PRESS)
1545   {
1546     entitylist_select (NULL, data);
1547     return TRUE;
1548   }
1549   return FALSE;
1550 }
1551
1552 static void entitylist_selection_changed(GtkTreeSelection* selection, gpointer data)
1553 {
1554   GtkListStore* store = GTK_LIST_STORE (g_object_get_data (G_OBJECT (data), "keyvalues"));
1555
1556   gtk_list_store_clear(store);
1557
1558   GtkTreeModel* model;
1559   GtkTreeIter selected;
1560   if(gtk_tree_selection_get_selected(selection, &model, &selected))
1561   {
1562     entity_t* pEntity;
1563     gtk_tree_model_get(model, &selected, 1, &pEntity, -1);
1564
1565     if (pEntity)
1566     {
1567       for (epair_t* pEpair = pEntity->epairs; pEpair; pEpair = pEpair->next)
1568       {
1569         GtkTreeIter appended;
1570         gtk_list_store_append(store, &appended);
1571         gtk_list_store_set(store, &appended, 0, pEpair->key, 1, pEpair->value, -1);
1572       }
1573     }
1574   }
1575 }
1576
1577 void DoEntityList ()
1578 {
1579   static GtkWidget *dlg;
1580   GtkWidget *vbox, *hbox, *hbox2, *button, *scr;
1581   int loop = 1, ret = IDCANCEL;
1582
1583   if (dlg != NULL)
1584     return;
1585
1586   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1587
1588   load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posEntityInfoWnd);
1589
1590   gtk_window_set_title (GTK_WINDOW (dlg), "Entities");
1591   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
1592                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
1593   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
1594                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
1595   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
1596   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
1597
1598   hbox = gtk_hbox_new (TRUE, 5);
1599   gtk_widget_show (hbox);
1600   gtk_container_add (GTK_CONTAINER (dlg), hbox);
1601   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
1602
1603   scr = gtk_scrolled_window_new ((GtkAdjustment*)NULL, (GtkAdjustment*)NULL);
1604   gtk_widget_show (scr);
1605   gtk_box_pack_start (GTK_BOX (hbox), scr, TRUE, TRUE, 0);
1606   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1607   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
1608
1609   {
1610     GtkTreeStore* store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
1611
1612     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1613     g_signal_connect(G_OBJECT(view), "button_press_event", G_CALLBACK(entitylist_click), dlg);
1614     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
1615
1616     {
1617       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1618       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
1619       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1620     }
1621
1622     {
1623       GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
1624       g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(entitylist_selection_changed), dlg);
1625     }
1626
1627     gtk_widget_show(view);
1628
1629     gtk_container_add(GTK_CONTAINER (scr), view);
1630     g_object_set_data (G_OBJECT (dlg), "entities", view);
1631
1632     {
1633       {
1634         GtkTreeIter child;
1635         gtk_tree_store_append(store, &child, NULL);
1636         gtk_tree_store_set(store, &child, 0, world_entity->eclass->name, 1, world_entity, -1);
1637       }
1638
1639       GSList *l, *entitymap = NULL;
1640       typedef struct
1641       {
1642         GtkTreeIter node;
1643         const char *name;
1644       } map_t;
1645       map_t *entry;
1646
1647       for (entity_t* pEntity=entities.next; pEntity != &entities; pEntity=pEntity->next)
1648       {
1649         GtkTreeIter parent;
1650         bool found = false;
1651
1652         for (l = entitymap; l; l = g_slist_next (l))
1653         {
1654           entry = (map_t*)l->data;
1655
1656           if (strcmp (entry->name, pEntity->eclass->name) == 0)
1657           {
1658                   parent = entry->node;
1659                   found = true;
1660                   break;
1661           }
1662         }
1663
1664         if (!found)
1665         {
1666           gtk_tree_store_append(store, &parent, NULL);
1667           gtk_tree_store_set(store, &parent, 0, pEntity->eclass->name, 1, NULL, -1);
1668
1669           entry = (map_t*)malloc (sizeof(map_t));
1670           entitymap = g_slist_append (entitymap, entry);
1671           entry->name = pEntity->eclass->name;
1672           entry->node = parent;
1673         }
1674
1675         GtkTreeIter child;
1676         gtk_tree_store_append(store, &child, &parent);
1677         gtk_tree_store_set(store, &child, 0, pEntity->eclass->name, 1, pEntity, -1);
1678       }
1679
1680       while (entitymap)
1681       {
1682         free (entitymap->data);
1683         entitymap = g_slist_remove (entitymap, entitymap->data);
1684       }
1685     }
1686
1687     g_object_unref(G_OBJECT(store));
1688   }
1689
1690   vbox = gtk_vbox_new (FALSE, 5);
1691   gtk_widget_show (vbox);
1692   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
1693
1694   scr = gtk_scrolled_window_new ((GtkAdjustment*)NULL, (GtkAdjustment*)NULL);
1695   gtk_widget_show (scr);
1696   gtk_box_pack_start (GTK_BOX (vbox), scr, TRUE, TRUE, 0);
1697   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1698   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
1699
1700   {
1701     GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
1702
1703     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1704
1705     {
1706       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1707       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Key", renderer, "text", 0, NULL);
1708       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1709     }
1710
1711     {
1712       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
1713       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Value", renderer, "text", 1, NULL);
1714       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
1715     }
1716
1717     gtk_widget_show(view);
1718
1719     g_object_set_data(G_OBJECT(dlg), "keyvalues", store);
1720     gtk_container_add(GTK_CONTAINER (scr), view);
1721
1722     g_object_unref(G_OBJECT(store));
1723   }
1724
1725   hbox2 = gtk_hbox_new (FALSE, 5);
1726   gtk_widget_show (hbox2);
1727   gtk_box_pack_start (GTK_BOX (vbox), hbox2, TRUE, TRUE, 0);
1728
1729   button = gtk_button_new_with_label ("Select");
1730   gtk_widget_show (button);
1731   gtk_box_pack_start (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
1732   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1733                       GTK_SIGNAL_FUNC (entitylist_select), dlg);
1734   gtk_widget_set_usize (button, 60, -2);
1735
1736   button = gtk_button_new_with_label ("Close");
1737   gtk_widget_show (button);
1738   gtk_box_pack_end (GTK_BOX (hbox2), button, FALSE, FALSE, 0);
1739   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1740                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
1741   gtk_widget_set_usize (button, 60, -2);
1742
1743   gtk_grab_add (dlg);
1744   gtk_widget_show (dlg);
1745
1746   while (loop)
1747     gtk_main_iteration ();
1748
1749   save_window_pos (dlg, g_PrefsDlg.mWindowInfo.posMapInfoWnd);
1750
1751   gtk_grab_remove (dlg);
1752   gtk_widget_destroy (dlg);
1753
1754   dlg = NULL;
1755 }
1756
1757 // =============================================================================
1758 // Rotate dialog
1759
1760 static void rotatedlg_apply (GtkWidget *widget, gpointer data)
1761 {
1762   GtkSpinButton *spin;
1763   float f;
1764
1765   spin = GTK_SPIN_BUTTON (g_object_get_data (G_OBJECT (data), "x"));
1766   f = gtk_spin_button_get_value_as_float (spin);
1767   if (f != 0.0)
1768     Select_RotateAxis(0,f);
1769   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0.0f); // reset to 0 on Apply
1770
1771   spin = GTK_SPIN_BUTTON (g_object_get_data (G_OBJECT (data), "y"));
1772   f = gtk_spin_button_get_value_as_float (spin);
1773   if (f != 0.0)
1774     Select_RotateAxis(1,f);
1775   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0.0f);
1776
1777   spin = GTK_SPIN_BUTTON (g_object_get_data (G_OBJECT (data), "z"));
1778   f = gtk_spin_button_get_value_as_float (spin);
1779   if (f != 0.0)
1780     Select_RotateAxis(2,f);
1781   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0.0f);
1782 }
1783
1784 void DoRotateDlg ()
1785 {
1786   GtkWidget *dlg, *hbox, *vbox, *table, *label, *button;
1787   GtkWidget *x, *y, *z;
1788   GtkObject *adj;
1789   int loop = 1, ret = IDCANCEL;
1790
1791   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1792   gtk_window_set_title (GTK_WINDOW (dlg), "Arbitrary rotation");
1793   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
1794                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
1795   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
1796                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
1797   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
1798   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
1799
1800   hbox = gtk_hbox_new (FALSE, 5);
1801   gtk_widget_show (hbox);
1802   gtk_container_add (GTK_CONTAINER (dlg), hbox);
1803   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
1804
1805   table = gtk_table_new (3, 2, FALSE);
1806   gtk_widget_show (table);
1807   gtk_box_pack_start (GTK_BOX (hbox), table, TRUE, TRUE, 0);
1808   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
1809   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
1810
1811   label = gtk_label_new ("  X  ");
1812   gtk_widget_show (label);
1813   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
1814                     (GtkAttachOptions) (0),
1815                     (GtkAttachOptions) (0), 0, 0);
1816
1817   label = gtk_label_new ("  Y  ");
1818   gtk_widget_show (label);
1819   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
1820                     (GtkAttachOptions) (0),
1821                     (GtkAttachOptions) (0), 0, 0);
1822
1823   label = gtk_label_new ("  Z  ");
1824
1825   gtk_widget_show (label);
1826   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
1827                     (GtkAttachOptions) (0),
1828                     (GtkAttachOptions) (0), 0, 0);
1829
1830   adj = gtk_adjustment_new (0, -359, 359, 1, 10, 10);
1831   x = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
1832   g_object_set_data (G_OBJECT (dlg), "x", x);
1833   gtk_widget_show (x);
1834   gtk_table_attach (GTK_TABLE (table), x, 1, 2, 0, 1,
1835                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1836                     (GtkAttachOptions) (0), 0, 0);
1837   gtk_widget_set_usize (x, 60, -2);
1838   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (x), TRUE);
1839
1840   adj = gtk_adjustment_new (0, -359, 359, 1, 10, 10);
1841   y = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
1842   g_object_set_data (G_OBJECT (dlg), "y", y);
1843   gtk_widget_show (y);
1844   gtk_table_attach (GTK_TABLE (table), y, 1, 2, 1, 2,
1845                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1846                     (GtkAttachOptions) (0), 0, 0);
1847   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (y), TRUE);
1848
1849   adj = gtk_adjustment_new (0, -359, 359, 1, 10, 10);
1850   z = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
1851   g_object_set_data (G_OBJECT (dlg), "z", z);
1852   gtk_widget_show (z);
1853   gtk_table_attach (GTK_TABLE (table), z, 1, 2, 2, 3,
1854                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1855                     (GtkAttachOptions) (0), 0, 0);
1856   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (z), TRUE);
1857
1858   vbox = gtk_vbox_new (FALSE, 5);
1859   gtk_widget_show (vbox);
1860   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
1861
1862   button = gtk_button_new_with_label ("OK");
1863   gtk_widget_show (button);
1864   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1865   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1866                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
1867   gtk_widget_set_usize (button, 60, -2);
1868
1869   button = gtk_button_new_with_label ("Cancel");
1870   gtk_widget_show (button);
1871   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1872   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1873                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
1874
1875   button = gtk_button_new_with_label ("Apply");
1876   gtk_widget_show (button);
1877   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1878   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1879                       GTK_SIGNAL_FUNC (rotatedlg_apply), dlg);
1880
1881   gtk_grab_add (dlg);
1882   gtk_widget_show (dlg);
1883
1884   while (loop)
1885     gtk_main_iteration ();
1886
1887   if (ret == IDOK)
1888     rotatedlg_apply (button, dlg);
1889
1890   gtk_grab_remove (dlg);
1891   gtk_widget_destroy (dlg);
1892 }
1893
1894 // =============================================================================
1895 // Gamma dialog
1896
1897 void DoGamma ()
1898 {
1899   GtkWidget *dlg, *vbox, *hbox, *label, *button, *entry;
1900   int loop = 1, ret = IDCANCEL;
1901
1902   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1903   gtk_window_set_title (GTK_WINDOW (dlg), "Gamma");
1904   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
1905                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
1906   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
1907                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
1908   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
1909   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
1910
1911   hbox = gtk_hbox_new (FALSE, 5);
1912   gtk_widget_show (hbox);
1913   gtk_container_add (GTK_CONTAINER (dlg), hbox);
1914   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
1915
1916   vbox = gtk_vbox_new (FALSE, 5);
1917   gtk_widget_show (vbox);
1918   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
1919
1920   entry = gtk_entry_new ();
1921   gtk_widget_show (entry);
1922   gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
1923
1924   label = gtk_label_new ("0.0 is brightest\n1.0 is darkest");
1925   gtk_widget_show (label);
1926   gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
1927
1928   label = gtk_label_new ("You must restart for the\nsettings to take effect");
1929   gtk_widget_show (label);
1930   gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
1931
1932   vbox = gtk_vbox_new (FALSE, 5);
1933   gtk_widget_show (vbox);
1934   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
1935
1936   button = gtk_button_new_with_label ("OK");
1937   gtk_widget_show (button);
1938   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1939   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1940                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
1941   gtk_widget_set_usize (button, 60, -2);
1942
1943   button = gtk_button_new_with_label ("Cancel");
1944   gtk_widget_show (button);
1945   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1946   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1947                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
1948
1949   // Initialize dialog
1950   char buf[16];
1951   sprintf (buf, "%1.1f", g_qeglobals.d_savedinfo.fGamma);
1952   gtk_entry_set_text (GTK_ENTRY (entry), buf);
1953
1954   gtk_grab_add (dlg);
1955   gtk_widget_show (dlg);
1956
1957   while (loop)
1958     gtk_main_iteration ();
1959
1960   if (ret == IDOK)
1961     g_qeglobals.d_savedinfo.fGamma = g_strtod (gtk_entry_get_text (GTK_ENTRY (entry)), NULL);
1962
1963   gtk_grab_remove (dlg);
1964   gtk_widget_destroy (dlg);
1965 }
1966
1967 // =============================================================================
1968 // Find Brush Dialog
1969
1970 // helper function to walk through the active brushes only and drop the regioned out ones
1971 bool WalkRegionBrush (brush_t **b, entity_t *e)
1972 {
1973   brush_t *b2;
1974   do
1975   {
1976     for(b2=active_brushes.next ; b2 != &active_brushes ; b2=b2->next)
1977     {
1978       if (b2==*b)
1979         break; // this is an active brush
1980     }
1981     if (b2==&active_brushes)
1982     {
1983       // this is a regioned out brush
1984       *b = (*b)->onext;
1985       if (*b == &e->brushes)
1986       {
1987         Sys_Status ("No such brush", 0);
1988         return false;
1989       }
1990     }
1991   } while (b2==&active_brushes);
1992   return true;
1993 }
1994
1995 void SelectBrush (int entitynum, int brushnum)
1996 {
1997   entity_t *e;
1998   brush_t *b;
1999   int i;
2000
2001   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=503
2002   // making this work when regioning is on too
2003
2004   if (entitynum == 0)
2005     e = world_entity;
2006   else
2007   {
2008     e = entities.next;
2009     while (--entitynum)
2010     {
2011       e = e->next;
2012       if (e == &entities)
2013       {
2014         Sys_Status ("No such entity", 0);
2015         return;
2016       }
2017       if (region_active)
2018       {
2019         // we need to make sure we walk to the next 'active' entity to have a valid --entitynum
2020         // that is, find a brush that belongs to this entity in the active brushes
2021         do
2022         {
2023           for (b = active_brushes.next ; b != &active_brushes ; b=b->next)
2024           {
2025             if (b->owner == e)
2026               break; // this is an active entity
2027           }
2028           if (b==&active_brushes)
2029           {
2030             // this is a regioned out entity
2031             e = e->next;
2032             // don't walk past the end either
2033             if (e == &entities)
2034             {
2035               Sys_Status ("No such entity", 0);
2036               return;
2037             }
2038           }
2039         } while(b==&active_brushes);
2040       }
2041     }
2042   }
2043
2044   b = e->brushes.onext;
2045   if (b == &e->brushes)
2046   {
2047     Sys_Status ("No such brush", 0);
2048     return;
2049   }
2050   if (region_active)
2051   {
2052     if (!WalkRegionBrush(&b, e))
2053       return;
2054   }
2055
2056   while (brushnum--)
2057   {
2058     b = b->onext;
2059     if (b == &e->brushes)
2060     {
2061       Sys_Status ("No such brush", 0);
2062       return;
2063     }
2064     if (region_active)
2065     {
2066       if (!WalkRegionBrush(&b, e))
2067         return;
2068     }
2069   }
2070
2071   Brush_RemoveFromList (b);
2072   Brush_AddToList (b, &selected_brushes);
2073
2074   Sys_UpdateWindows (W_ALL);
2075   for (i = 0; i < 3; i++)
2076   {
2077     if (g_pParentWnd->GetXYWnd())
2078       g_pParentWnd->GetXYWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2;
2079
2080     if (g_pParentWnd->GetXZWnd())
2081       g_pParentWnd->GetXZWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2;
2082
2083     if (g_pParentWnd->GetYZWnd())
2084       g_pParentWnd->GetYZWnd()->GetOrigin()[i] = (b->mins[i] + b->maxs[i])/2;
2085   }
2086
2087   Sys_Status ("Selected", 0);
2088 }
2089
2090 static void GetSelectionIndex (int *ent, int *brush)
2091 {
2092   brush_t *b, *b2;
2093   entity_t *entity;
2094
2095   *ent = *brush = 0;
2096
2097   b = selected_brushes.next;
2098   if (b == &selected_brushes)
2099     return;
2100
2101   // find entity
2102   if (b->owner != world_entity)
2103   {
2104     (*ent)++;
2105     for (entity = entities.next; entity != &entities; entity=entity->next, (*ent)++)
2106       ;
2107   }
2108
2109   // find brush
2110   for (b2=b->owner->brushes.onext; b2 != b && b2 != &b->owner->brushes; b2=b2->onext, (*brush)++)
2111     ;
2112 }
2113
2114 void DoFind ()
2115 {
2116   GtkWidget *dlg, *vbox, *hbox, *table, *label, *button, *entity, *brush;
2117   int loop = 1, ret = IDCANCEL;
2118
2119   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2120   gtk_window_set_title (GTK_WINDOW (dlg), "Find Brush");
2121   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
2122                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
2123   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
2124                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2125   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
2126   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
2127
2128   vbox = gtk_vbox_new (FALSE, 5);
2129   gtk_widget_show (vbox);
2130   gtk_container_add (GTK_CONTAINER (dlg), vbox);
2131   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
2132
2133   table = gtk_table_new (2, 2, FALSE);
2134   gtk_widget_show (table);
2135   gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
2136   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2137   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2138
2139   label = gtk_label_new ("Entity number");
2140   gtk_widget_show (label);
2141   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2142                     (GtkAttachOptions) (0),
2143                     (GtkAttachOptions) (0), 0, 0);
2144
2145   label = gtk_label_new ("Brush number");
2146   gtk_widget_show (label);
2147   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2148                     (GtkAttachOptions) (0),
2149                     (GtkAttachOptions) (0), 0, 0);
2150
2151   entity = gtk_entry_new ();
2152   gtk_widget_show (entity);
2153   gtk_table_attach (GTK_TABLE (table), entity, 1, 2, 0, 1,
2154                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
2155                     (GtkAttachOptions) (0), 0, 0);
2156
2157   brush = gtk_entry_new ();
2158   gtk_widget_show (brush);
2159   gtk_table_attach (GTK_TABLE (table), brush, 1, 2, 1, 2,
2160                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
2161                     (GtkAttachOptions) (0), 0, 0);
2162
2163   hbox = gtk_hbox_new (FALSE, 5);
2164   gtk_widget_show (hbox);
2165   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2166
2167   button = gtk_button_new_with_label ("OK");
2168   gtk_widget_show (button);
2169   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
2170   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2171                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
2172   gtk_widget_set_usize (button, 60, -2);
2173
2174   button = gtk_button_new_with_label ("Cancel");
2175   gtk_widget_show (button);
2176   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
2177   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2178                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
2179
2180   // Initialize dialog
2181   char buf[16];
2182   int ent, br;
2183
2184   GetSelectionIndex (&ent, &br);
2185   sprintf (buf, "%i", ent);
2186   gtk_entry_set_text (GTK_ENTRY (entity), buf);
2187   sprintf (buf, "%i", br);
2188   gtk_entry_set_text (GTK_ENTRY (brush), buf);
2189
2190   gtk_grab_add (dlg);
2191   gtk_widget_show (dlg);
2192
2193   while (loop)
2194     gtk_main_iteration ();
2195
2196   if (ret == IDOK)
2197   {
2198     const char *entstr = gtk_entry_get_text (GTK_ENTRY (entity));
2199     const char *brushstr = gtk_entry_get_text (GTK_ENTRY (brush));
2200     SelectBrush (atoi(entstr), atoi(brushstr));
2201   }
2202
2203   gtk_grab_remove (dlg);
2204   gtk_widget_destroy (dlg);
2205 }
2206
2207 // =============================================================================
2208 // Arbitrary Sides dialog
2209
2210 void DoSides (bool bCone, bool bSphere, bool bTorus)
2211 {
2212   GtkWidget *dlg, *vbox, *hbox, *button, *label, *entry;
2213   int loop = 1, ret = IDCANCEL;
2214
2215   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2216   gtk_window_set_title (GTK_WINDOW (dlg), "Arbitrary sides");
2217   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
2218                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
2219   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
2220                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2221   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
2222   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
2223
2224   hbox = gtk_hbox_new (FALSE, 5);
2225   gtk_widget_show (hbox);
2226   gtk_container_add (GTK_CONTAINER (dlg), hbox);
2227   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2228
2229   label = gtk_label_new ("Sides:");
2230   gtk_widget_show (label);
2231   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2232
2233   entry = gtk_entry_new ();
2234   gtk_widget_show (entry);
2235   gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
2236
2237   vbox = gtk_vbox_new (FALSE, 5);
2238   gtk_widget_show (vbox);
2239   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, TRUE, 0);
2240
2241   button = gtk_button_new_with_label ("OK");
2242   gtk_widget_show (button);
2243   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2244   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2245                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
2246   gtk_widget_set_usize (button, 60, -2);
2247
2248   button = gtk_button_new_with_label ("Cancel");
2249   gtk_widget_show (button);
2250   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2251   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2252                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
2253
2254   gtk_grab_add (dlg);
2255   gtk_widget_show (dlg);
2256
2257   while (loop)
2258     gtk_main_iteration ();
2259
2260   if (ret == IDOK)
2261   {
2262     const char *str = gtk_entry_get_text (GTK_ENTRY (entry));
2263
2264     if (bCone)
2265       Brush_MakeSidedCone(atoi(str));
2266     else if (bSphere)
2267       Brush_MakeSidedSphere(atoi(str));
2268     else
2269       Brush_MakeSided (atoi(str));
2270   }
2271
2272   gtk_grab_remove (dlg);
2273   gtk_widget_destroy (dlg);
2274 }
2275
2276 // =============================================================================
2277 // New Patch dialog
2278
2279 void DoNewPatchDlg ()
2280 {
2281   GtkWidget *dlg, *hbox, *table, *vbox, *label, *button, *combo;
2282   GtkWidget *width, *height;
2283   GList *combo_list = (GList*)NULL;
2284   int loop = 1, ret = IDCANCEL;
2285
2286   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2287   gtk_window_set_title (GTK_WINDOW (dlg), "Patch density");
2288   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
2289                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
2290   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
2291                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2292   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
2293   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
2294
2295   hbox = gtk_hbox_new (FALSE, 5);
2296   gtk_widget_show (hbox);
2297   gtk_container_add (GTK_CONTAINER (dlg), hbox);
2298   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2299
2300   table = gtk_table_new (2, 2, FALSE);
2301   gtk_widget_show (table);
2302   gtk_box_pack_start (GTK_BOX (hbox), table, TRUE, TRUE, 0);
2303   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2304   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2305
2306   label = gtk_label_new ("Width:");
2307   gtk_widget_show (label);
2308   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2309                     (GtkAttachOptions) (GTK_FILL),
2310                     (GtkAttachOptions) (0), 0, 0);
2311   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2312
2313   label = gtk_label_new ("Height:");
2314   gtk_widget_show (label);
2315   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2316                     (GtkAttachOptions) (GTK_FILL),
2317                     (GtkAttachOptions) (0), 0, 0);
2318   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2319
2320   combo_list = g_list_append (combo_list, (void *)"3");
2321   combo_list = g_list_append (combo_list, (void *)"5");
2322   combo_list = g_list_append (combo_list, (void *)"7");
2323   combo_list = g_list_append (combo_list, (void *)"9");
2324   combo_list = g_list_append (combo_list, (void *)"11");
2325   combo_list = g_list_append (combo_list, (void *)"13");
2326   combo_list = g_list_append (combo_list, (void *)"15");
2327
2328   combo = gtk_combo_new ();
2329   width = GTK_COMBO (combo)->entry;
2330   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2331   gtk_widget_show (combo);
2332   gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 0, 1,
2333                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
2334                     (GtkAttachOptions) (0), 0, 0);
2335
2336   combo = gtk_combo_new ();
2337   height = GTK_COMBO (combo)->entry;
2338   gtk_combo_set_popdown_strings (GTK_COMBO (combo), combo_list);
2339   gtk_widget_show (combo);
2340   gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 1, 2,
2341                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
2342                     (GtkAttachOptions) (0), 0, 0);
2343
2344   vbox = gtk_vbox_new (FALSE, 5);
2345   gtk_widget_show (vbox);
2346   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
2347
2348   button = gtk_button_new_with_label ("OK");
2349   gtk_widget_show (button);
2350   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2351   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2352                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
2353   gtk_widget_set_usize (button, 60, -2);
2354
2355   button = gtk_button_new_with_label ("Cancel");
2356   gtk_widget_show (button);
2357   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2358   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2359                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
2360
2361   // Initialize dialog
2362   g_list_free (combo_list);
2363   gtk_entry_set_text (GTK_ENTRY (width), "3");
2364   gtk_entry_set_editable (GTK_ENTRY (width), FALSE);
2365   gtk_entry_set_text (GTK_ENTRY (height), "3");
2366   gtk_entry_set_editable (GTK_ENTRY (height), FALSE);
2367
2368   gtk_grab_add (dlg);
2369   gtk_widget_show (dlg);
2370
2371   while (loop)
2372     gtk_main_iteration ();
2373
2374   if (ret == IDOK)
2375   {
2376     const char* w = gtk_entry_get_text (GTK_ENTRY (width));
2377     const char* h = gtk_entry_get_text (GTK_ENTRY (height));
2378
2379     Patch_GenericMesh(atoi (w), atoi (h), g_pParentWnd->ActiveXY ()->GetViewType ());
2380     Sys_UpdateWindows (W_ALL);
2381   }
2382
2383   gtk_grab_remove (dlg);
2384   gtk_widget_destroy (dlg);
2385 }
2386
2387 // =============================================================================
2388 // New Patch dialog
2389
2390 void DoScaleDlg ()
2391 {
2392   GtkWidget *dlg, *hbox, *table, *vbox, *label, *button;
2393   GtkWidget *x, *y, *z;
2394   int loop = 1, ret = IDCANCEL;
2395
2396   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2397   gtk_window_set_title (GTK_WINDOW (dlg), "Scale");
2398   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
2399                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
2400   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
2401                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2402   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
2403   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
2404
2405   hbox = gtk_hbox_new (FALSE, 5);
2406   gtk_widget_show (hbox);
2407   gtk_container_add (GTK_CONTAINER (dlg), hbox);
2408   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2409
2410   table = gtk_table_new (3, 2, FALSE);
2411   gtk_widget_show (table);
2412   gtk_box_pack_start (GTK_BOX (hbox), table, TRUE, TRUE, 0);
2413   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2414   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2415
2416   label = gtk_label_new ("X:");
2417   gtk_widget_show (label);
2418   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2419                     (GtkAttachOptions) (GTK_FILL),
2420                     (GtkAttachOptions) (0), 0, 0);
2421   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2422
2423   label = gtk_label_new ("Y:");
2424   gtk_widget_show (label);
2425   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2426                     (GtkAttachOptions) (GTK_FILL),
2427                     (GtkAttachOptions) (0), 0, 0);
2428   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2429
2430   label = gtk_label_new ("Z:");
2431   gtk_widget_show (label);
2432   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
2433                     (GtkAttachOptions) (GTK_FILL),
2434                     (GtkAttachOptions) (0), 0, 0);
2435   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2436
2437   x = gtk_entry_new ();
2438   gtk_widget_show (x);
2439   gtk_table_attach (GTK_TABLE (table), x, 1, 2, 0, 1,
2440                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
2441                     (GtkAttachOptions) (0), 0, 0);
2442
2443   y = gtk_entry_new ();
2444   gtk_widget_show (y);
2445   gtk_table_attach (GTK_TABLE (table), y, 1, 2, 1, 2,
2446                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
2447                     (GtkAttachOptions) (0), 0, 0);
2448
2449   z = gtk_entry_new ();
2450   gtk_widget_show (z);
2451   gtk_table_attach (GTK_TABLE (table), z, 1, 2, 2, 3,
2452                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
2453                     (GtkAttachOptions) (0), 0, 0);
2454
2455   vbox = gtk_vbox_new (FALSE, 5);
2456   gtk_widget_show (vbox);
2457   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
2458
2459   button = gtk_button_new_with_label ("OK");
2460   gtk_widget_show (button);
2461   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2462   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2463                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
2464   gtk_widget_set_usize (button, 60, -2);
2465
2466   button = gtk_button_new_with_label ("Cancel");
2467   gtk_widget_show (button);
2468   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2469   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2470                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
2471
2472   // Initialize dialog
2473   gtk_entry_set_text (GTK_ENTRY (x), "1.0");
2474   gtk_entry_set_text (GTK_ENTRY (y), "1.0");
2475   gtk_entry_set_text (GTK_ENTRY (z), "1.0");
2476
2477   gtk_grab_add (dlg);
2478   gtk_widget_show (dlg);
2479
2480   while (loop)
2481     gtk_main_iteration ();
2482
2483   if (ret == IDOK)
2484   {
2485     float sx, sy, sz;
2486     sx = atof (gtk_entry_get_text (GTK_ENTRY (x)));
2487     sy = atof (gtk_entry_get_text (GTK_ENTRY (y)));
2488     sz = atof (gtk_entry_get_text (GTK_ENTRY (z)));
2489
2490     if (sx > 0 && sy > 0 && sz > 0)
2491     {
2492       Select_Scale(sx, sy, sz);
2493       Sys_UpdateWindows (W_ALL);
2494     }
2495     else
2496       Sys_Printf("Warning.. Tried to scale by a zero value.");
2497   }
2498
2499   gtk_grab_remove (dlg);
2500   gtk_widget_destroy (dlg);
2501 }
2502
2503 // =============================================================================
2504 // Thicken Patch dialog
2505
2506 void DoThickenDlg ()
2507 {
2508   GtkWidget *dlg, *vbox, *hbox, *vbox2, *button, *label;
2509   GtkWidget *amount, *seams, *group;
2510   int loop = 1, ret = IDCANCEL;
2511   static qboolean bGroupResult = true;
2512
2513   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2514   gtk_window_set_title (GTK_WINDOW (dlg), "Thicken Patch");
2515   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
2516                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
2517   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
2518                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2519   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
2520   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
2521
2522   vbox = gtk_vbox_new (FALSE, 5);
2523   gtk_widget_show (vbox);
2524   gtk_container_add (GTK_CONTAINER (dlg), vbox);
2525   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
2526
2527   hbox = gtk_hbox_new (FALSE, 5);
2528   gtk_widget_show (hbox);
2529   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2530
2531   label = gtk_label_new ("This produces a set of patches\n"
2532                          "that contains the original patch along with the\n"
2533                          "'thick' patch and an optimal set of seam patches.");
2534   gtk_widget_show (label);
2535   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2536
2537   vbox2 = gtk_vbox_new (FALSE, 5);
2538   gtk_widget_show (vbox2);
2539   gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
2540
2541   button = gtk_button_new_with_label ("OK");
2542   gtk_widget_show (button);
2543   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
2544   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2545                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
2546   gtk_widget_set_usize (button, 60, -2);
2547
2548   button = gtk_button_new_with_label ("Cancel");
2549   gtk_widget_show (button);
2550   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
2551   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2552                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
2553
2554   hbox = gtk_hbox_new (FALSE, 5);
2555   gtk_widget_show (hbox);
2556   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2557
2558   label = gtk_label_new ("Amount:");
2559   gtk_widget_show (label);
2560   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2561
2562   amount = gtk_entry_new ();
2563   gtk_widget_show (amount);
2564   gtk_box_pack_start (GTK_BOX (hbox), amount, FALSE, FALSE, 0);
2565
2566   seams = gtk_check_button_new_with_label ("Seams");
2567   gtk_widget_show (seams);
2568   gtk_box_pack_start (GTK_BOX (hbox), seams, FALSE, FALSE, 0);
2569
2570   // bGroupResult
2571   group = gtk_check_button_new_with_label("Result to func_group");
2572   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(group), bGroupResult);
2573   gtk_box_pack_start(GTK_BOX(vbox), group, FALSE, FALSE, 0);
2574   gtk_widget_show(group);
2575
2576
2577   // Initialize dialog
2578   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (seams), TRUE);
2579   gtk_entry_set_text (GTK_ENTRY (amount), "8");
2580
2581   gtk_grab_add (dlg);
2582   gtk_widget_show (dlg);
2583
2584   while (loop)
2585     gtk_main_iteration ();
2586
2587   if (ret == IDOK)
2588   {
2589     if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(group)))
2590       bGroupResult = true;
2591     else
2592       bGroupResult = false;
2593     Patch_Thicken (atoi (gtk_entry_get_text (GTK_ENTRY (amount))),
2594                    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (seams)), bGroupResult);
2595     Sys_UpdateWindows (W_ALL);
2596   }
2597
2598   gtk_grab_remove (dlg);
2599   gtk_widget_destroy (dlg);
2600 }
2601
2602 // =============================================================================
2603 // About dialog (no program is complete without one)
2604
2605 void about_button_changelog (GtkWidget *widget, gpointer data)
2606 {
2607   Str log;
2608   log = g_strAppPath;
2609   log += "changelog.txt";
2610   OpenURL(log.GetBuffer());
2611 }
2612
2613 void about_button_credits (GtkWidget *widget, gpointer data)
2614 {
2615   Str cred;
2616   cred = g_strAppPath;
2617   cred += "credits.html";
2618   OpenURL(cred.GetBuffer());
2619 }
2620
2621 void DoAbout ()
2622 {
2623   GtkWidget *dlg, *vbox, *vbox2, *hbox, *frame, *table, *label, *pixmap, *button, *sc_extensions, *text_extensions;
2624   int loop = 1, ret = IDCANCEL;
2625
2626   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2627   gtk_window_set_title (GTK_WINDOW (dlg), "About GtkRadiant");
2628   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
2629                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
2630   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
2631                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2632   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
2633   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
2634
2635   vbox = gtk_vbox_new (FALSE, 10);
2636   gtk_widget_show (vbox);
2637   gtk_container_add (GTK_CONTAINER (dlg), vbox);
2638   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
2639
2640   hbox = gtk_hbox_new (FALSE, 5);
2641   gtk_widget_show (hbox);
2642   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2643
2644   vbox2 = gtk_vbox_new (FALSE, 5);
2645   gtk_widget_show (vbox2);
2646   gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, FALSE, 0);
2647
2648   frame = gtk_frame_new ((char*)NULL);
2649   gtk_widget_show (frame);
2650   gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0);
2651   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
2652
2653   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "logo.bmp");
2654   gtk_widget_show (pixmap);
2655   gtk_container_add (GTK_CONTAINER (frame), pixmap);
2656
2657   label = gtk_label_new ("GtkRadiant " RADIANT_VERSION "\n"
2658     __DATE__ "\n\n"
2659     RADIANT_ABOUTMSG "\n\n"
2660     "By qeradiant.com\n\n"
2661     "This product contains software technology\n"
2662     "from id Software, Inc. ('id Technology').\n"
2663     "id Technology 2000 id Software,Inc.\n\n"
2664     "GtkRadiant is unsupported, however\n"
2665     "you may report your problems at\n"
2666     "http://zerowing.idsoftware.com/bugzilla"
2667   );
2668
2669   gtk_widget_show (label);
2670   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2671   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
2672   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2673
2674   vbox2 = gtk_vbox_new (FALSE, 5);
2675   gtk_widget_show (vbox2);
2676   gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, TRUE, 0);
2677
2678   button = gtk_button_new_with_label ("OK");
2679   gtk_widget_show (button);
2680   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
2681   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2682                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
2683
2684   button = gtk_button_new_with_label ("Credits");
2685   gtk_widget_show (button);
2686   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
2687   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2688                       GTK_SIGNAL_FUNC (about_button_credits), NULL);
2689
2690   button = gtk_button_new_with_label ("Changelog");
2691   gtk_widget_show (button);
2692   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
2693   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2694                       GTK_SIGNAL_FUNC (about_button_changelog), NULL);
2695
2696   frame = gtk_frame_new ("OpenGL Properties");
2697   gtk_widget_show (frame);
2698   gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2699
2700   table = gtk_table_new (3, 2, FALSE);
2701   gtk_widget_show (table);
2702   gtk_container_add (GTK_CONTAINER (frame), table);
2703   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
2704   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
2705   gtk_container_set_border_width (GTK_CONTAINER (table), 5);
2706
2707   label = gtk_label_new ("Vendor:");
2708   gtk_widget_show (label);
2709   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
2710                     (GtkAttachOptions) (GTK_FILL),
2711                     (GtkAttachOptions) (0), 0, 0);
2712   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2713
2714   label = gtk_label_new ("Version:");
2715   gtk_widget_show (label);
2716   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
2717                     (GtkAttachOptions) (GTK_FILL),
2718                     (GtkAttachOptions) (0), 0, 0);
2719   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2720
2721   label = gtk_label_new ("Renderer:");
2722   gtk_widget_show (label);
2723   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
2724                     (GtkAttachOptions) (GTK_FILL),
2725                     (GtkAttachOptions) (0), 0, 0);
2726   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2727
2728   label = gtk_label_new ((char*)qglGetString (GL_VENDOR));
2729   gtk_widget_show (label);
2730   gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
2731                     (GtkAttachOptions) (GTK_FILL),
2732                     (GtkAttachOptions) (0), 0, 0);
2733   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2734
2735   label = gtk_label_new ((char*)qglGetString (GL_VERSION));
2736   gtk_widget_show (label);
2737   gtk_table_attach (GTK_TABLE (table), label, 1, 2, 1, 2,
2738                     (GtkAttachOptions) (GTK_FILL),
2739                     (GtkAttachOptions) (0), 0, 0);
2740   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2741
2742   label = gtk_label_new ((char*)qglGetString (GL_RENDERER));
2743   gtk_widget_show (label);
2744   gtk_table_attach (GTK_TABLE (table), label, 1, 2, 2, 3,
2745                     (GtkAttachOptions) (GTK_FILL),
2746                     (GtkAttachOptions) (0), 0, 0);
2747   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2748
2749   frame = gtk_frame_new ("OpenGL Extensions");
2750   gtk_widget_show (frame);
2751   gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
2752
2753   hbox = gtk_hbox_new (FALSE, 5);
2754   gtk_widget_show (hbox);
2755   gtk_container_add (GTK_CONTAINER (frame), hbox);
2756   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2757
2758   sc_extensions = gtk_scrolled_window_new(NULL, NULL);
2759   gtk_box_pack_start(GTK_BOX(hbox), sc_extensions, TRUE, TRUE, 0);
2760   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_extensions), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2761   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sc_extensions), GTK_SHADOW_IN);
2762   gtk_widget_show(sc_extensions);
2763
2764   text_extensions = gtk_text_view_new();
2765   gtk_text_view_set_editable(GTK_TEXT_VIEW(text_extensions), FALSE);
2766   gtk_container_add (GTK_CONTAINER (sc_extensions), text_extensions);
2767   GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_extensions));
2768   gtk_text_buffer_set_text(buffer, (char *)qglGetString(GL_EXTENSIONS), -1);
2769   gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_extensions), GTK_WRAP_WORD);;
2770   gtk_widget_show(text_extensions);
2771
2772   gtk_grab_add (dlg);
2773   gtk_widget_show (dlg);
2774
2775   while (loop)
2776     gtk_main_iteration ();
2777
2778   gtk_grab_remove (dlg);
2779   gtk_widget_destroy (dlg);
2780 }
2781
2782 // =============================================================================
2783 // Command List dialog
2784
2785 void DoCommandListDlg ()
2786 {
2787   GtkWidget *dlg, *vbox, *hbox, *scr, *button;
2788   int loop = 1, ret = IDCANCEL;
2789
2790   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2791   gtk_window_set_title (GTK_WINDOW (dlg), "Mapped Commands");
2792   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
2793                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
2794   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
2795                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2796   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
2797   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
2798   gtk_window_set_default_size (GTK_WINDOW (dlg), 400, 400);
2799
2800   hbox = gtk_hbox_new (FALSE, 5);
2801   gtk_widget_show (hbox);
2802   gtk_container_add (GTK_CONTAINER (dlg), hbox);
2803   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2804
2805   scr = gtk_scrolled_window_new ((GtkAdjustment*)NULL, (GtkAdjustment*)NULL);
2806   gtk_widget_show (scr);
2807   gtk_box_pack_start (GTK_BOX (hbox), scr, TRUE, TRUE, 0);
2808   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2809   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scr), GTK_SHADOW_IN);
2810
2811   {
2812     GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
2813
2814     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
2815
2816     {
2817       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
2818       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Command", renderer, "text", 0, NULL);
2819       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2820     }
2821
2822     {
2823       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
2824       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Key", renderer, "text", 1, NULL);
2825       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2826     }
2827
2828     gtk_widget_show(view);
2829     gtk_container_add(GTK_CONTAINER (scr), view);
2830
2831     {
2832       // Initialize dialog
2833       CString path;
2834       path = g_strTempPath;
2835       path += "commandlist.txt";
2836
2837       GSList *cmds = NULL;
2838       int n;
2839
2840       for (n = 0; n < g_nCommandCount; n++)
2841         cmds = g_slist_append (cmds, g_Commands[n].m_strCommand);
2842       cmds = g_slist_sort (cmds, (gint (*)(const void *, const void *))strcmp);
2843
2844       Sys_Printf("Writing the command list to %s", path.GetBuffer() );
2845       FILE* fileout = fopen (path.GetBuffer (), "wt");
2846
2847       while (cmds)
2848       {
2849         for (n = 0; n < g_nCommandCount; n++)
2850           if (cmds->data == g_Commands[n].m_strCommand)
2851             break;
2852
2853         char c = g_Commands[n].m_nKey;
2854         CString strLine, strMod(""), strKeys (c);
2855
2856         for (int k = 0; k < g_nKeyCount; k++)
2857         {
2858           if (g_Keys[k].m_nVKKey == g_Commands[n].m_nKey)
2859           {
2860             strKeys = g_Keys[k].m_strName;
2861             break;
2862           }
2863         }
2864
2865         if (g_Commands[n].m_nModifiers & RAD_SHIFT)
2866           strMod = "Shift";
2867         if (g_Commands[n].m_nModifiers & RAD_ALT)
2868           strMod += (strMod.GetLength() > 0) ? " + Alt" : "Alt";
2869         if (g_Commands[n].m_nModifiers & RAD_CONTROL)
2870           strMod += (strMod.GetLength() > 0) ? " + Control" : "Control";
2871         if (strMod.GetLength() > 0)
2872           strMod += " + ";
2873         strMod += strKeys;
2874
2875         {
2876           GtkTreeIter iter;
2877           gtk_list_store_append(store, &iter);
2878           gtk_list_store_set(store, &iter, 0, g_Commands[n].m_strCommand, 1, strMod.GetBuffer (), -1);
2879         }
2880
2881         if (fileout != NULL)
2882         {
2883           strLine.Format("%-25s %s\r\n", g_Commands[n].m_strCommand, strMod.GetBuffer ());
2884           fputs (strLine.GetBuffer (), fileout);
2885         }
2886
2887         cmds = g_slist_remove (cmds, cmds->data);
2888       }
2889
2890       if (fileout != NULL)
2891         fclose (fileout);
2892     }
2893
2894     g_object_unref(G_OBJECT(store));
2895   }
2896
2897   vbox = gtk_vbox_new (FALSE, 5);
2898   gtk_widget_show (vbox);
2899   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2900
2901   button = gtk_button_new_with_label ("Close");
2902   gtk_widget_show (button);
2903   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2904   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2905                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
2906   gtk_widget_set_usize (button, 60, -2);
2907
2908   gtk_grab_add (dlg);
2909   gtk_widget_show (dlg);
2910
2911   while (loop)
2912     gtk_main_iteration ();
2913
2914   gtk_grab_remove (dlg);
2915   gtk_widget_destroy (dlg);
2916 }
2917
2918 // =============================================================================
2919 // Texture List dialog
2920
2921 void DoTextureListDlg ()
2922 {
2923   GtkWidget *dlg, *vbox, *hbox, *scr, *button;
2924   int loop = 1, ret = IDCANCEL;
2925
2926   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2927   gtk_window_set_title (GTK_WINDOW (dlg), "Textures");
2928   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
2929                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
2930   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
2931                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2932   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
2933   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
2934   gtk_window_set_default_size (GTK_WINDOW (dlg), 400, 400);
2935
2936   hbox = gtk_hbox_new (FALSE, 5);
2937   gtk_widget_show (hbox);
2938   gtk_container_add (GTK_CONTAINER (dlg), hbox);
2939   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2940
2941   scr = gtk_scrolled_window_new ((GtkAdjustment*)NULL, (GtkAdjustment*)NULL);
2942   gtk_widget_show (scr);
2943   gtk_box_pack_start (GTK_BOX (hbox), scr, TRUE, TRUE, 0);
2944   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2945   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scr), GTK_SHADOW_IN);
2946
2947   GtkWidget* texture_list;
2948
2949   {
2950     GtkListStore* store = gtk_list_store_new(1, G_TYPE_STRING);
2951
2952     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
2953     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
2954
2955     {
2956       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
2957       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
2958       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
2959     }
2960
2961     gtk_widget_show(view);
2962     gtk_container_add(GTK_CONTAINER (scr), view);
2963
2964     {
2965       // Initialize dialog
2966       GSList *textures = (GSList*)NULL;
2967       FillTextureMenu(&textures);
2968       while (textures != NULL)
2969       {
2970         {
2971           GtkTreeIter iter;
2972           gtk_list_store_append(store, &iter);
2973           gtk_list_store_set(store, &iter, 0, (gchar*)textures->data, -1);
2974         }
2975         free (textures->data);
2976         textures = g_slist_remove (textures, textures->data);
2977       }
2978     }
2979
2980     g_object_unref(G_OBJECT(store));
2981
2982     texture_list = view;
2983   }
2984
2985   vbox = gtk_vbox_new (FALSE, 5);
2986   gtk_widget_show (vbox);
2987   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2988
2989   button = gtk_button_new_with_label ("Load");
2990   gtk_widget_show (button);
2991   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2992   gtk_signal_connect (GTK_OBJECT (button), "clicked",
2993                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
2994   gtk_widget_set_usize (button, 60, -2);
2995
2996   button = gtk_button_new_with_label ("Close");
2997   gtk_widget_show (button);
2998   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2999   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3000                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
3001   gtk_widget_set_usize (button, 60, -2);
3002
3003   gtk_grab_add (dlg);
3004   gtk_widget_show (dlg);
3005
3006   while (loop)
3007     gtk_main_iteration ();
3008
3009   if (ret == IDOK)
3010   {
3011     GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(texture_list));
3012
3013     GtkTreeModel* model;
3014     GtkTreeIter iter;
3015     if(gtk_tree_selection_get_selected(selection, &model, &iter))
3016     {
3017       GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
3018       if(gtk_tree_path_get_depth(path) == 1)
3019         Texture_ShowDirectory(gtk_tree_path_get_indices(path)[0] + CMD_TEXTUREWAD);
3020       gtk_tree_path_free(path);
3021     }
3022   }
3023
3024   gtk_grab_remove (dlg);
3025   gtk_widget_destroy (dlg);
3026 }
3027
3028 // =============================================================================
3029 // Cap dialog
3030
3031 int DoCapDlg (int *type, bool *b_GroupResult)
3032 {
3033   GtkWidget *dlg, *vbox, *hbox, *table, *pixmap, *button, *group_toggle, *radio_vbox;
3034   GtkWidget *bevel, *endcap, *ibevel, *iendcap;
3035   GSList *group = (GSList*)NULL;
3036         int loop = 1, ret = IDCANCEL;
3037
3038   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3039   gtk_window_set_title (GTK_WINDOW (dlg), "Cap");
3040   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
3041                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
3042   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
3043                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
3044   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
3045   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
3046
3047         hbox = gtk_hbox_new (FALSE, 5);
3048   gtk_widget_show (hbox);
3049   gtk_container_add (GTK_CONTAINER (dlg), hbox);
3050   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3051
3052   // Gef: Added a vbox to contain the toggle buttons
3053   radio_vbox = gtk_vbox_new(FALSE, 4);
3054   gtk_container_add(GTK_CONTAINER(hbox), radio_vbox);
3055   gtk_widget_show(radio_vbox);
3056
3057   table = gtk_table_new (4, 2, FALSE);
3058   gtk_widget_show (table);
3059   gtk_box_pack_start (GTK_BOX (radio_vbox), table, TRUE, TRUE, 0);
3060   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
3061   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
3062
3063   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "cap_bevel.bmp");
3064   gtk_widget_show (pixmap);
3065   gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 0, 1,
3066                     (GtkAttachOptions) (GTK_FILL),
3067                     (GtkAttachOptions) (0), 0, 0);
3068
3069   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "cap_endcap.bmp");
3070   gtk_widget_show (pixmap);
3071   gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 1, 2,
3072                     (GtkAttachOptions) (GTK_FILL),
3073                     (GtkAttachOptions) (0), 0, 0);
3074
3075   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "cap_ibevel.bmp");
3076   gtk_widget_show (pixmap);
3077   gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 2, 3,
3078                     (GtkAttachOptions) (GTK_FILL),
3079                     (GtkAttachOptions) (0), 0, 0);
3080
3081   pixmap = new_pixmap (g_pParentWnd->m_pWidget, "cap_iendcap.bmp");
3082   gtk_widget_show (pixmap);
3083   gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 3, 4,
3084                     (GtkAttachOptions) (GTK_FILL),
3085                     (GtkAttachOptions) (0), 0, 0);
3086
3087   bevel = gtk_radio_button_new_with_label (group, "Bevel");
3088   gtk_widget_show (bevel);
3089   gtk_table_attach (GTK_TABLE (table), bevel, 1, 2, 0, 1,
3090                     (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
3091                     (GtkAttachOptions) (0), 0, 0);
3092   group = gtk_radio_button_group (GTK_RADIO_BUTTON (bevel));
3093
3094   endcap = gtk_radio_button_new_with_label (group, "Endcap");
3095   gtk_widget_show (endcap);
3096   gtk_table_attach (GTK_TABLE (table), endcap, 1, 2, 1, 2,
3097                     (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
3098                     (GtkAttachOptions) (0), 0, 0);
3099   group = gtk_radio_button_group (GTK_RADIO_BUTTON (endcap));
3100
3101   ibevel = gtk_radio_button_new_with_label (group, "Inverted Bevel");
3102   gtk_widget_show (ibevel);
3103   gtk_table_attach (GTK_TABLE (table), ibevel, 1, 2, 2, 3,
3104                     (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
3105                     (GtkAttachOptions) (0), 0, 0);
3106   group = gtk_radio_button_group (GTK_RADIO_BUTTON (ibevel));
3107
3108   iendcap = gtk_radio_button_new_with_label (group, "Inverted Endcap");
3109   gtk_widget_show (iendcap);
3110   gtk_table_attach (GTK_TABLE (table), iendcap, 1, 2, 3, 4,
3111                     (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
3112                     (GtkAttachOptions) (0), 0, 0);
3113   group = gtk_radio_button_group (GTK_RADIO_BUTTON (iendcap));
3114
3115   // Gef: added radio toggle for func_grouping capped patches
3116   group_toggle = gtk_check_button_new_with_label("Result to func_group");
3117   gtk_container_add(GTK_CONTAINER(radio_vbox), group_toggle);
3118   gtk_widget_show(group_toggle);
3119
3120   vbox = gtk_vbox_new (FALSE, 5);
3121   gtk_widget_show (vbox);
3122   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
3123
3124   button = gtk_button_new_with_label ("OK");
3125   gtk_widget_show (button);
3126   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3127   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3128                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
3129   gtk_widget_set_usize (button, 60, -2);
3130
3131   button = gtk_button_new_with_label ("Cancel");
3132   gtk_widget_show (button);
3133   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3134   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3135                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
3136   gtk_widget_set_usize (button, 60, -2);
3137
3138   // Gef: Set the state of the func_group toggle
3139   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (group_toggle), *b_GroupResult);
3140
3141   // Initialize dialog
3142   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bevel), TRUE);
3143
3144   gtk_grab_add (dlg);
3145   gtk_widget_show (dlg);
3146
3147   while (loop)
3148     gtk_main_iteration ();
3149
3150   if (ret == IDOK)
3151   {
3152     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (bevel)))
3153       *type = BEVEL; //*type = CapDialog::BEVEL;
3154     else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (endcap)))
3155       *type = ENDCAP; //*type = CapDialog::ENDCAP;
3156     else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ibevel)))
3157       *type = IBEVEL; // *type = CapDialog::IBEVEL;
3158     else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (iendcap)))
3159       *type = IENDCAP; // *type = CapDialog::IENDCAP;
3160
3161     // Gef: Added toggle for optional cap func_grouping
3162     *b_GroupResult = (bool *)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(group_toggle));
3163   }
3164
3165   gtk_grab_remove (dlg);
3166   gtk_widget_destroy (dlg);
3167
3168   return ret;
3169 }
3170
3171 // =============================================================================
3172 // Scripts dialog
3173
3174 void DoScriptsDlg ()
3175 {
3176   GtkWidget *dlg, *vbox, *vbox2, *hbox, *label, *button, *scr;
3177   int loop = 1, ret = IDCANCEL;
3178
3179   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3180   gtk_window_set_title (GTK_WINDOW (dlg), "Available Scripts - Not Implemented Yet");
3181   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
3182                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
3183   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
3184                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
3185   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
3186   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
3187
3188   vbox = gtk_vbox_new (FALSE, 5);
3189   gtk_widget_show (vbox);
3190   gtk_container_add (GTK_CONTAINER (dlg), vbox);
3191   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
3192
3193   label = gtk_label_new ("WARNING: BrushScripting is in a highly experimental state and is\n"
3194                          "far from complete. If you attempt to use them it is VERY LIKELY\n"
3195                          "that Radiant will crash. Save your work before attempting to\n"
3196                          "make use of any scripting features.");
3197   gtk_widget_show (label);
3198   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
3199   gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
3200   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
3201
3202   hbox = gtk_hbox_new (FALSE, 5);
3203   gtk_widget_show (hbox);
3204   gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
3205
3206   scr = gtk_scrolled_window_new ((GtkAdjustment*)NULL, (GtkAdjustment*)NULL);
3207   gtk_widget_show (scr);
3208   gtk_box_pack_start (GTK_BOX (hbox), scr, TRUE, TRUE, 0);
3209   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
3210   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scr), GTK_SHADOW_IN);
3211
3212   GtkWidget* scripts_list;
3213
3214   {
3215     GtkListStore* store = gtk_list_store_new(1, G_TYPE_STRING);
3216
3217     GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
3218     gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
3219
3220     {
3221       GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
3222       GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
3223       gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
3224     }
3225
3226     gtk_widget_show(view);
3227     gtk_container_add(GTK_CONTAINER (scr), view);
3228
3229     {
3230       // Initialize dialog
3231       CString strINI;
3232       strINI = g_strGameToolsPath;
3233       strINI += "/scripts.ini";
3234       FILE *f;
3235
3236       f = fopen (strINI.GetBuffer(), "rt");
3237       if (f != NULL)
3238       {
3239         char line[1024], *ptr;
3240
3241         // read section names
3242         while (fgets (line, 1024, f) != 0)
3243         {
3244           if (line[0] != '[')
3245             continue;
3246
3247           ptr = strchr (line, ']');
3248           *ptr = '\0';
3249
3250           {
3251             GtkTreeIter iter;
3252             gtk_list_store_append(store, &iter);
3253             gtk_list_store_set(store, &iter, 0, line, -1);
3254           }
3255         }
3256         fclose (f);
3257       }
3258     }
3259
3260     g_object_unref(G_OBJECT(store));
3261
3262     scripts_list = view;
3263   }
3264
3265   vbox2 = gtk_vbox_new (FALSE, 5);
3266   gtk_widget_show (vbox2);
3267   gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
3268
3269   button = gtk_button_new_with_label ("Run");
3270   gtk_widget_show (button);
3271   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
3272   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3273                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
3274   gtk_widget_set_usize (button, 60, -2);
3275
3276   button = gtk_button_new_with_label ("New...");
3277   gtk_widget_show (button);
3278   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
3279   gtk_widget_set_sensitive (button, FALSE);
3280   gtk_widget_set_usize (button, 60, -2);
3281
3282   button = gtk_button_new_with_label ("Edit...");
3283   gtk_widget_show (button);
3284   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
3285   gtk_widget_set_sensitive (button, FALSE);
3286   gtk_widget_set_usize (button, 60, -2);
3287
3288   button = gtk_button_new_with_label ("Close");
3289   gtk_widget_show (button);
3290   gtk_box_pack_end (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
3291   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3292                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
3293   gtk_widget_set_usize (button, 60, -2);
3294
3295   gtk_grab_add (dlg);
3296   gtk_widget_show (dlg);
3297
3298   while (loop)
3299     gtk_main_iteration ();
3300
3301   if (ret == IDOK)
3302   {
3303     GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(scripts_list));
3304
3305     GtkTreeModel* model;
3306     GtkTreeIter iter;
3307     if(gtk_tree_selection_get_selected(selection, &model, &iter))
3308     {
3309       char* script;
3310       gtk_tree_model_get(model, &iter, 0, &script, -1);
3311       RunScriptByName(script, true);
3312       g_free(script);
3313     }
3314   }
3315
3316   gtk_grab_remove (dlg);
3317   gtk_widget_destroy (dlg);
3318 }
3319
3320 // =============================================================================
3321 //  dialog
3322
3323 int DoBSInputDlg (const char *fields[5], float values[5])
3324 {
3325   GtkWidget *dlg, *vbox, *hbox, *label, *button;
3326   GtkWidget *entries[5];
3327   int i, loop = 1, ret = IDCANCEL;
3328
3329   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3330   gtk_window_set_title (GTK_WINDOW (dlg), "BrushScript Input");
3331   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
3332                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
3333   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
3334                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
3335   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
3336   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
3337
3338   hbox = gtk_hbox_new (FALSE, 5);
3339   gtk_widget_show (hbox);
3340   gtk_container_add (GTK_CONTAINER (dlg), hbox);
3341   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3342
3343   vbox = gtk_vbox_new (FALSE, 5);
3344   gtk_widget_show (vbox);
3345   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
3346
3347   // Create entries and initialize them
3348   for (i = 0; i < 5; i++)
3349   {
3350     if (strlen (fields[i]) == 0)
3351       continue;
3352
3353     label = gtk_label_new (fields[i]);
3354     gtk_widget_show (label);
3355     gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
3356     gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
3357     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
3358
3359     entries[i] = gtk_entry_new ();
3360     gtk_widget_show (entries[i]);
3361     gtk_box_pack_start (GTK_BOX (vbox), entries[i], TRUE, TRUE, 0);
3362
3363     char buf[32];
3364     sprintf (buf, "%f", values[i]);
3365     gtk_entry_set_text (GTK_ENTRY (entries[i]), buf);
3366   }
3367
3368   vbox = gtk_vbox_new (FALSE, 5);
3369   gtk_widget_show (vbox);
3370   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
3371
3372   button = gtk_button_new_with_label ("OK");
3373   gtk_widget_show (button);
3374   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3375   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3376                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
3377   gtk_widget_set_usize (button, 60, -2);
3378
3379   button = gtk_button_new_with_label ("Cancel");
3380   gtk_widget_show (button);
3381   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3382   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3383                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
3384   gtk_widget_set_usize (button, 60, -2);
3385
3386   gtk_grab_add (dlg);
3387   gtk_widget_show (dlg);
3388
3389   while (loop)
3390     gtk_main_iteration ();
3391
3392   for (i = 0; i < 5; i++)
3393   {
3394     if (strlen (fields[i]) == 0)
3395       continue;
3396
3397     values[i] = atof (gtk_entry_get_text (GTK_ENTRY (entries[i])));
3398   }
3399
3400   gtk_grab_remove (dlg);
3401   gtk_widget_destroy (dlg);
3402
3403   return ret;
3404 }
3405
3406 // =============================================================================
3407 // TextureLayout dialog
3408
3409 int DoTextureLayout (float *fx, float *fy)
3410 {
3411   GtkWidget *dlg, *vbox, *hbox, *table, *label, *button;
3412   GtkWidget *x, *y;
3413   int loop = 1, ret = IDCANCEL;
3414
3415   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3416   gtk_window_set_title (GTK_WINDOW (dlg), "Patch texture layout");
3417   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
3418                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
3419   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
3420                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
3421   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
3422   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
3423
3424   hbox = gtk_hbox_new (FALSE, 5);
3425   gtk_widget_show (hbox);
3426   gtk_container_add (GTK_CONTAINER (dlg), hbox);
3427   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3428
3429   vbox = gtk_vbox_new (FALSE, 5);
3430   gtk_widget_show (vbox);
3431   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
3432
3433   label = gtk_label_new ("Texture will be fit across the patch based\n"
3434                          "on the x and y values given. Values of 1x1\n"
3435                          "will \"fit\" the texture. 2x2 will repeat\n"
3436                          "it twice, etc.");
3437   gtk_widget_show (label);
3438   gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
3439   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
3440
3441   table = gtk_table_new (2, 2, FALSE);
3442   gtk_widget_show (table);
3443   gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
3444   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
3445   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
3446
3447   label = gtk_label_new ("Texture x:");
3448   gtk_widget_show (label);
3449   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
3450                     (GtkAttachOptions) (GTK_FILL),
3451                     (GtkAttachOptions) (0), 0, 0);
3452   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3453
3454   label = gtk_label_new ("Texture y:");
3455   gtk_widget_show (label);
3456   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
3457                     (GtkAttachOptions) (GTK_FILL),
3458                     (GtkAttachOptions) (0), 0, 0);
3459   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3460
3461   x = gtk_entry_new ();
3462   gtk_widget_show (x);
3463   gtk_table_attach (GTK_TABLE (table), x, 1, 2, 0, 1,
3464                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
3465                     (GtkAttachOptions) (0), 0, 0);
3466
3467   y = gtk_entry_new ();
3468   gtk_widget_show (y);
3469   gtk_table_attach (GTK_TABLE (table), y, 1, 2, 1, 2,
3470                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
3471                     (GtkAttachOptions) (0), 0, 0);
3472
3473   vbox = gtk_vbox_new (FALSE, 5);
3474   gtk_widget_show (vbox);
3475   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
3476
3477   button = gtk_button_new_with_label ("OK");
3478   gtk_widget_show (button);
3479   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3480   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3481                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
3482   gtk_widget_set_usize (button, 60, -2);
3483
3484   button = gtk_button_new_with_label ("Cancel");
3485   gtk_widget_show (button);
3486   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3487   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3488                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
3489   gtk_widget_set_usize (button, 60, -2);
3490
3491   // Initialize
3492   gtk_entry_set_text (GTK_ENTRY (x), "4.0");
3493   gtk_entry_set_text (GTK_ENTRY (y), "4.0");
3494
3495   gtk_grab_add (dlg);
3496   gtk_widget_show (dlg);
3497
3498   while (loop)
3499     gtk_main_iteration ();
3500
3501   if (ret == IDOK)
3502   {
3503     *fx = atof (gtk_entry_get_text (GTK_ENTRY (x)));
3504     *fy = atof (gtk_entry_get_text (GTK_ENTRY (y)));
3505   }
3506
3507   gtk_grab_remove (dlg);
3508   gtk_widget_destroy (dlg);
3509
3510   return ret;
3511 }
3512
3513 // =============================================================================
3514 // Name dialog
3515
3516 char* DoNameDlg (const char* title)
3517 {
3518   GtkWidget *dlg, *vbox, *hbox, *label, *button, *entry;
3519   int loop = 1, ret = IDCANCEL;
3520   char *str;
3521
3522   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3523   gtk_window_set_title (GTK_WINDOW (dlg), title);
3524   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
3525                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
3526   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
3527                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
3528   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
3529   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
3530
3531   hbox = gtk_hbox_new (FALSE, 5);
3532   gtk_widget_show (hbox);
3533   gtk_container_add (GTK_CONTAINER (dlg), hbox);
3534   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3535
3536   label = gtk_label_new ("Name:");
3537   gtk_widget_show (label);
3538   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
3539
3540   entry = gtk_entry_new ();
3541   gtk_widget_show (entry);
3542   gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
3543
3544   vbox = gtk_vbox_new (FALSE, 5);
3545   gtk_widget_show (vbox);
3546   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
3547
3548   button = gtk_button_new_with_label ("OK");
3549   gtk_widget_show (button);
3550   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3551   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3552                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
3553   gtk_widget_set_usize (button, 60, -2);
3554
3555   button = gtk_button_new_with_label ("Cancel");
3556   gtk_widget_show (button);
3557   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3558   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3559                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
3560   gtk_widget_set_usize (button, 60, -2);
3561
3562   gtk_grab_add (dlg);
3563   gtk_widget_show (dlg);
3564
3565   while (loop)
3566     gtk_main_iteration ();
3567
3568   if (ret == IDOK)
3569     str = strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
3570   else
3571     str = NULL;
3572
3573   gtk_grab_remove (dlg);
3574   gtk_widget_destroy (dlg);
3575
3576   return str;
3577 }
3578
3579 // =============================================================================
3580 // NewProject dialog
3581
3582 char* DoNewProjectDlg ()
3583 {
3584   GtkWidget *dlg, *vbox, *hbox, *label, *button, *entry, *check;
3585   int loop = 1, ret = IDCANCEL;
3586   char *str;
3587
3588   // start by a warning message
3589   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=459
3590   CString msg;
3591   msg = "Are you sure you want a new project?\n";
3592   msg += "Please note that creating a new project is not the prefered way to setup GtkRadiant for mod editing.\n";
3593   msg += "Check http://www.qeradiant.com/faq/index.cgi?file=220 for more information";
3594   if (gtk_MessageBox(NULL, msg.GetBuffer(), "Confirm", MB_YESNO, "http://www.qeradiant.com/faq/index.cgi?file=220" ) == IDNO)
3595   {
3596     return NULL;
3597   }
3598
3599   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3600   gtk_window_set_title (GTK_WINDOW (dlg), "New Project");
3601   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
3602                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
3603   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
3604                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
3605   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
3606   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
3607
3608   hbox = gtk_hbox_new (FALSE, 10);
3609   gtk_widget_show (hbox);
3610   gtk_container_add (GTK_CONTAINER (dlg), hbox);
3611   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3612
3613   vbox = gtk_vbox_new (FALSE, 5);
3614   gtk_widget_show (vbox);
3615   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
3616
3617   label = gtk_label_new ("This will create a new directory beneath your\n"
3618                          "game path based on the project name you give.");
3619   gtk_widget_show (label);
3620   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
3621   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
3622
3623   label = gtk_label_new ("Project name:");
3624   gtk_widget_show (label);
3625   gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
3626   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
3627   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3628
3629   entry = gtk_entry_new ();
3630   gtk_widget_show (entry);
3631   gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
3632
3633   check = gtk_check_button_new_with_label ("Include game dll files");
3634   gtk_widget_show (check);
3635   gtk_box_pack_start (GTK_BOX (vbox), check, TRUE, TRUE, 0);
3636   gtk_widget_set_sensitive (check, FALSE);
3637
3638   vbox = gtk_vbox_new (FALSE, 5);
3639   gtk_widget_show (vbox);
3640   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
3641
3642   button = gtk_button_new_with_label ("OK");
3643   gtk_widget_show (button);
3644   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3645   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3646                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
3647   gtk_widget_set_usize (button, 60, -2);
3648
3649   button = gtk_button_new_with_label ("Cancel");
3650   gtk_widget_show (button);
3651   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
3652   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3653                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
3654   gtk_widget_set_usize (button, 60, -2);
3655
3656   gtk_grab_add (dlg);
3657   gtk_widget_show (dlg);
3658
3659   while (loop)
3660     gtk_main_iteration ();
3661
3662   if (ret == IDOK)
3663     str = strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
3664   else
3665     str = NULL;
3666
3667   gtk_grab_remove (dlg);
3668   gtk_widget_destroy (dlg);
3669
3670   return str;
3671 }
3672
3673 // =============================================================================
3674 // Text Editor dialog
3675
3676 // master window widget
3677 static GtkWidget *text_editor = NULL;
3678 static GtkWidget *text_widget; // slave, text widget from the gtk editor
3679
3680 static gint editor_delete (GtkWidget *widget, gpointer data)
3681 {
3682   if (gtk_MessageBox (widget, "Close the shader editor ?", "Radiant", MB_YESNO) == IDNO)
3683     return TRUE;
3684
3685   gtk_widget_hide (text_editor);
3686
3687   return TRUE;
3688 }
3689
3690 static void editor_save (GtkWidget *widget, gpointer data)
3691 {
3692   FILE *f = fopen ((char*)g_object_get_data (G_OBJECT (data), "filename"), "w");
3693   gpointer text = g_object_get_data (G_OBJECT (data), "text");
3694
3695   if (f == NULL)
3696   {
3697     gtk_MessageBox (GTK_WIDGET(data), "Error saving file !");
3698     return;
3699   }
3700
3701   char *str = gtk_editable_get_chars (GTK_EDITABLE (text), 0, -1);
3702   fwrite (str, 1, strlen (str), f);
3703   fclose (f);
3704 }
3705
3706 static void editor_close (GtkWidget *widget, gpointer data)
3707 {
3708   if (gtk_MessageBox (text_editor, "Close the shader editor ?", "Radiant", MB_YESNO) == IDNO)
3709     return;
3710
3711   gtk_widget_hide (text_editor);
3712 }
3713
3714 // several attempts
3715 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=355
3716 #if 0
3717 #ifdef _WIN32
3718
3719 HWND FindEditWindow()
3720 {
3721   return FindWindow("TFormEditPadLite", NULL);
3722 }
3723
3724 HWND FindEditWindow()
3725 {
3726   HWND hwnd = FindWindow("TFormEditPadLite", NULL);
3727   if (hwnd)
3728   {
3729     hwnd = FindWindowEx(hwnd, NULL, "TPanel", NULL);
3730     if (hwnd)
3731     {
3732       hwnd = FindWindowEx(hwnd, NULL, "TPanel", NULL);
3733       if (hwnd)
3734       {
3735         hwnd = FindWindowEx(hwnd, NULL, "TEditPadEditor", NULL);
3736         if (hwnd)
3737         {
3738           hwnd = FindWindowEx(hwnd, NULL, "TWinControlProxy", NULL);
3739           return hwnd;
3740         }
3741       }
3742     }
3743   }
3744   return NULL;
3745 }
3746
3747 HWND FindEditWindow()
3748 {
3749   HWND hwnd = FindWindow("TFormEditPadLite", NULL);
3750   if (hwnd)
3751   {
3752     hwnd = FindWindowEx(hwnd, NULL, "TPanel", NULL);
3753     if (hwnd)
3754     {
3755       hwnd = FindWindowEx(hwnd, NULL, "TPanel", NULL);
3756       if (hwnd)
3757       {
3758         hwnd = FindWindowEx(hwnd, NULL, "TPanel", NULL);
3759         if (hwnd)
3760         {
3761           hwnd = FindWindowEx(hwnd, NULL, "TFrameSearchReplace", NULL);
3762           if (hwnd)
3763           {
3764             hwnd = FindWindowEx(hwnd, NULL, "TJGStringEditorControl", NULL);
3765             return hwnd;
3766           }
3767         }
3768       }
3769     }
3770   }
3771   return NULL;
3772 }
3773
3774 HWND FindEditWindow()
3775 {
3776   HWND hwnd = FindWindow("TEditPadForm", NULL);
3777   HWND hwndEdit = NULL;
3778   if (hwnd != NULL)
3779   {
3780     HWND hwndTab = FindWindowEx(hwnd, NULL, "TTabControl", NULL);
3781     if (hwndTab != NULL)
3782     {
3783       hwndEdit = FindWindowEx(hwndTab, NULL, "TRicherEdit", NULL);
3784     }
3785   }
3786   return hwndEdit;
3787 }
3788 #endif
3789 #endif // #if 0
3790
3791 static void CreateGtkTextEditor ()
3792 {
3793   GtkWidget *dlg;
3794   GtkWidget *vbox, *hbox, *button, *scr, *text;
3795
3796   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3797
3798   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
3799                       GTK_SIGNAL_FUNC (editor_delete), NULL);
3800   gtk_window_set_default_size (GTK_WINDOW (dlg), 600, 300);
3801
3802   vbox = gtk_vbox_new (FALSE, 5);
3803   gtk_widget_show (vbox);
3804   gtk_container_add (GTK_CONTAINER (dlg), vbox);
3805   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
3806
3807   scr = gtk_scrolled_window_new (NULL, NULL);
3808   gtk_widget_show (scr);
3809   gtk_box_pack_start (GTK_BOX (vbox), scr, TRUE, TRUE, 0);
3810   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3811   gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
3812
3813   text = gtk_text_view_new();
3814   gtk_container_add (GTK_CONTAINER (scr), text);
3815   gtk_widget_show (text);
3816   g_object_set_data (G_OBJECT (dlg), "text", text);
3817   gtk_text_view_set_editable (GTK_TEXT_VIEW(text), TRUE);
3818
3819   hbox = gtk_hbox_new (FALSE, 5);
3820   gtk_widget_show (hbox);
3821   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
3822
3823   button = gtk_button_new_with_label ("Close");
3824   gtk_widget_show (button);
3825   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
3826   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3827                       GTK_SIGNAL_FUNC (editor_close), dlg);
3828   gtk_widget_set_usize (button, 60, -2);
3829
3830   button = gtk_button_new_with_label ("Save");
3831   gtk_widget_show (button);
3832   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
3833   gtk_signal_connect (GTK_OBJECT (button), "clicked",
3834                       GTK_SIGNAL_FUNC (editor_save), dlg);
3835   gtk_widget_set_usize (button, 60, -2);
3836
3837   text_editor = dlg;
3838   text_widget = text;
3839 }
3840
3841 static void DoGtkTextEditor (const char* filename, guint cursorpos)
3842 {
3843   if (!text_editor)
3844     CreateGtkTextEditor(); // build it the first time we need it
3845
3846   // Load file
3847   FILE *f = fopen (filename, "r");
3848
3849   if (f == NULL)
3850   {
3851     Sys_Printf("Unable to load file %s in shader editor.\n", filename);
3852     gtk_widget_hide (text_editor);
3853   }
3854   else
3855   {
3856     fseek (f, 0, SEEK_END);
3857     int len = ftell (f);
3858     void *buf = qmalloc (len);
3859     void *old_filename;
3860
3861     rewind (f);
3862     fread (buf, 1, len, f);
3863
3864     gtk_window_set_title (GTK_WINDOW (text_editor), filename);
3865
3866     GtkTextBuffer* text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_widget));
3867     gtk_text_buffer_set_text(text_buffer, (char*)buf, len);
3868
3869     old_filename = g_object_get_data (G_OBJECT (text_editor), "filename");
3870     if (old_filename)
3871       free(old_filename);
3872     g_object_set_data (G_OBJECT (text_editor), "filename", strdup (filename));
3873
3874     // trying to show later
3875     gtk_widget_show (text_editor);
3876
3877 #ifdef _WIN32
3878     while (gtk_events_pending ())
3879       gtk_main_iteration ();
3880 #endif
3881
3882     // only move the cursor if it's not exceeding the size..
3883     // NOTE: this is erroneous, cursorpos is the offset in bytes, not in characters
3884     // len is the max size in bytes, not in characters either, but the character count is below that limit..
3885     // thinking .. the difference between character count and byte count would be only because of CR/LF?
3886     {
3887       GtkTextIter text_iter;
3888       // character offset, not byte offset
3889       gtk_text_buffer_get_iter_at_offset(text_buffer, &text_iter, cursorpos);
3890       gtk_text_buffer_place_cursor(text_buffer, &text_iter);
3891     }
3892
3893 #ifdef _WIN32
3894     gtk_widget_queue_draw(text_widget);
3895 #endif
3896
3897     free (buf);
3898     fclose (f);
3899   }
3900 }
3901
3902 void DoTextEditor (const char* filename, int cursorpos)
3903 {
3904   CString strEditCommand;
3905 #ifdef _WIN32
3906   if (g_PrefsDlg.m_bUseWin32Editor)
3907   {
3908     Sys_Printf("opening file '%s' (line %d info ignored)\n", filename);
3909     ShellExecute((HWND)GDK_WINDOW_HWND (g_pParentWnd->m_pWidget->window), "open", filename, NULL, NULL, SW_SHOW );
3910     return;
3911   }
3912 #else
3913   // check if a custom editor is set
3914   if((g_PrefsDlg.m_bUseCustomEditor) && (g_PrefsDlg.m_strEditorCommand.GetLength() > 0))
3915   {
3916     strEditCommand = g_PrefsDlg.m_strEditorCommand;
3917     strEditCommand += " \"";
3918     strEditCommand += filename;
3919     strEditCommand += "\"";
3920
3921     Sys_Printf("Launching: %s\n", strEditCommand.GetBuffer());
3922     // note: linux does not return false if the command failed so it will assume success
3923     if (Q_Exec(NULL, (char *)strEditCommand.GetBuffer(), NULL, true) == false)
3924     {
3925       Sys_FPrintf(SYS_WRN, "Warning: Failed to execute %s, using default\n", strEditCommand.GetBuffer());
3926     }
3927     else
3928     {
3929       // the command (appeared) to run successfully, no need to do anything more
3930       return;
3931     }
3932   }
3933 #endif
3934
3935   DoGtkTextEditor (filename, cursorpos);
3936
3937   // old win32 code with EditPad bindings, broken
3938   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=355
3939 #if 0
3940   strEditCommand = g_strAppPath.GetBuffer();
3941   strEditCommand += "editpad.exe";
3942   strEditCommand += " \"";
3943   strEditCommand += filename;
3944   strEditCommand += "\"";
3945   if (Q_Exec(NULL, (char *)strEditCommand.GetBuffer(), NULL, true) == false)
3946   {
3947     Sys_FPrintf(SYS_WRN, "WARNING: Gtk shader editor is not fully functional on windows in general and unstable on win98 in particular.\n");
3948     Sys_FPrintf(SYS_WRN, "  you can use EditPad instead (install it in Radiant's directory): http://www.qeradiant.com/?data=files&files_dir=18\n");
3949     DoGtkTextEditor (filename, cursorpos);
3950   }
3951   else
3952   {
3953     // TTimo: we used to call Delay here, to continue processing messages. But it seems to induce a lot of instabilities.
3954     // so now the user will simply have to wait.
3955     Sleep( 1500 );
3956
3957         // now grab the edit window and scroll to the shader we want to edit
3958     HWND hwndEdit = FindEditWindow();
3959
3960     if (hwndEdit != NULL)
3961       PostMessage(hwndEdit, EM_SETSEL, cursorpos, cursorpos);
3962     else
3963       Sys_Printf("Unable to load shader editor.\n");
3964   }
3965 #endif
3966 }
3967
3968 // =============================================================================
3969 // Light Intensity dialog
3970
3971 int DoLightIntensityDlg (int *intensity)
3972 {
3973   GtkWidget *dlg, *vbox, *hbox, *label, *button, *entry;
3974   int loop = 1, ret = IDCANCEL;
3975
3976   dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3977   gtk_window_set_title (GTK_WINDOW (dlg), "Light intensity");
3978   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
3979                       GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
3980   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
3981                       GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
3982   g_object_set_data (G_OBJECT (dlg), "loop", &loop);
3983   g_object_set_data (G_OBJECT (dlg), "ret", &ret);
3984
3985   GtkAccelGroup *accel_group = gtk_accel_group_new ();
3986   gtk_window_add_accel_group (GTK_WINDOW (dlg), accel_group);
3987
3988   hbox = gtk_hbox_new (FALSE, 5);
3989   gtk_widget_show (hbox);
3990   gtk_container_add (GTK_CONTAINER (dlg), hbox);
3991   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3992
3993   vbox = gtk_vbox_new (FALSE, 5);
3994   gtk_widget_show (vbox);
3995   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
3996
3997   label = gtk_label_new ("ESC for default, ENTER to validate");
3998   gtk_widget_show (label);
3999   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
4000
4001   entry = gtk_entry_new ();
4002   gtk_widget_show (entry);
4003   gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
4004
4005   vbox = gtk_vbox_new (FALSE, 5);
4006   gtk_widget_show (vbox);
4007   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
4008
4009   button = gtk_button_new_with_label ("OK");
4010   gtk_widget_show (button);
4011   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
4012   gtk_signal_connect (GTK_OBJECT (button), "clicked",
4013                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
4014   gtk_widget_add_accelerator (button, "clicked", accel_group,
4015                               GDK_Return, (GdkModifierType)0, GTK_ACCEL_VISIBLE);
4016   gtk_widget_set_usize (button, 60, -2);
4017
4018   button = gtk_button_new_with_label ("Cancel");
4019   gtk_widget_show (button);
4020   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
4021   gtk_signal_connect (GTK_OBJECT (button), "clicked",
4022                       GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
4023   gtk_widget_add_accelerator (button, "clicked", accel_group,
4024                               GDK_Escape, (GdkModifierType)0, GTK_ACCEL_VISIBLE);
4025   gtk_widget_set_usize (button, 60, -2);
4026
4027   char buf[16];
4028   sprintf (buf, "%d", *intensity);
4029   gtk_entry_set_text (GTK_ENTRY (entry), buf);
4030
4031   gtk_grab_add (dlg);
4032   gtk_widget_show (dlg);
4033
4034   while (loop)
4035     gtk_main_iteration ();
4036
4037   if (ret == IDOK)
4038     *intensity = atoi (gtk_entry_get_text (GTK_ENTRY (entry)));
4039
4040   gtk_grab_remove (dlg);
4041   gtk_widget_destroy (dlg);
4042
4043   return ret;
4044 }