transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / radiant / groupdialog.cpp
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 //\r
23 // Floating dialog that contains a notebook with at least Entities and Group tabs\r
24 // I merged the 2 MS Windows dialogs in a single class\r
25 //\r
26 // Leonardo Zide (leo@lokigames.com)\r
27 //\r
28 \r
29 #ifndef _WIN32\r
30   #include <unistd.h>\r
31 #endif\r
32 #include <gdk/gdkkeysyms.h>\r
33 #include "stdafx.h"\r
34 #include "groupdialog.h"\r
35 \r
36 GtkWidget*      EntWidgets[EntLast];\r
37 GtkListStore* g_entlist_store;\r
38 GtkListStore* g_entprops_store;\r
39 int                                     inspector_mode;         // W_TEXTURE, W_ENTITY, or W_CONSOLE\r
40 qboolean                multiple_entities;\r
41 // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=17\r
42 qboolean                disable_spawn_get = false;\r
43 entity_t                *edit_entity;\r
44 /*\r
45 static GdkPixmap *tree_pixmaps[7];\r
46 static GdkBitmap *tree_masks[7];\r
47 */\r
48 #define IMG_PATCH 0\r
49 #define IMG_BRUSH 1\r
50 #define IMG_GROUP 2\r
51 #define IMG_ENTITY 3\r
52 #define IMG_ENTITYGROUP 4\r
53 #define IMG_MODEL 5\r
54 #define IMG_SCRIPT 6\r
55 \r
56 // misc group support\r
57 #define MAX_GROUPS 4096\r
58 #define GROUP_DELIMETER '@'\r
59 #define GROUPNAME "QER_Group_%i"\r
60 \r
61 GroupDlg g_wndGroup;\r
62 GroupDlg *g_pGroupDlg = &g_wndGroup;\r
63 \r
64 // group_t are loaded / saved through "group_info" entities\r
65 // they hold epairs for group settings and additionnal access info (tree nodes)\r
66 group_t *g_pGroups = NULL;\r
67 \r
68 // the number of active spawnflags\r
69 static int spawnflag_count;\r
70 // table: index, match spawnflag item to the spawnflag index (i.e. which bit)\r
71 static int spawn_table[MAX_FLAGS];\r
72 // we change the layout depending on how many spawn flags we need to display\r
73 // the table is a 4x4 in which we need to put the comment box EntWidgets[EntComment] and the spawn flags..\r
74 static GtkWidget *LayoutTable;\r
75 // 0: none of them are hooked\r
76 // 1: only the text, 2: text and four checks, 3: text and 8 checks\r
77 static int widget_state = 0;\r
78 \r
79 static void entity_check (GtkWidget *widget, gpointer data);\r
80 \r
81 // =============================================================================\r
82 // Global functions\r
83 \r
84 /*\r
85 ===============================================================\r
86 \r
87 ENTITY WINDOW\r
88 \r
89 ===============================================================\r
90 */\r
91 \r
92 void FillClassList ()\r
93 {\r
94   GtkListStore* store = g_entlist_store;\r
95 \r
96   gtk_list_store_clear(store);\r
97 \r
98   for (eclass_t* e = eclass ; e ; e = e->next)\r
99   {\r
100     GtkTreeIter iter;\r
101     gtk_list_store_append(store, &iter);\r
102     gtk_list_store_set(store, &iter, 0, e->name, 1, e, -1);\r
103   }     \r
104 }\r
105 \r
106 // SetKeyValuePairs\r
107 //\r
108 // Reset the key/value (aka property) listbox and fill it with the \r
109 // k/v pairs from the entity being edited.\r
110 //\r
111 \r
112 void SetKeyValuePairs (bool bClearMD3)\r
113 {\r
114   GtkListStore* store = g_entprops_store;\r
115 \r
116   gtk_list_store_clear(store);\r
117 \r
118   if (edit_entity == NULL)\r
119   {\r
120     // if there's no entity, then display no key/values\r
121     return;\r
122   }\r
123 \r
124   // save current key/val pair around filling epair box\r
125   // row_select wipes it and sets to first in list\r
126   Str strKey = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));\r
127   Str strVal = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));\r
128 \r
129 \r
130   // Walk through list and add pairs\r
131   for(epair_t* epair = edit_entity->epairs ; epair ; epair = epair->next)\r
132   {\r
133     GtkTreeIter iter;\r
134     gtk_list_store_append(store, &iter);\r
135     gtk_list_store_set(store, &iter, 0, epair->key, 1, epair->value, -1);\r
136   }\r
137 \r
138   gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), strKey.GetBuffer());\r
139   gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), strVal.GetBuffer());\r
140 \r
141   Sys_UpdateWindows(W_CAMERA | W_XY);\r
142 }\r
143 \r
144 // SetSpawnFlags\r
145 // \r
146 // Update the checkboxes to reflect the flag state of the entity\r
147 //\r
148 void SetSpawnFlags(void)\r
149 {\r
150   int f, i, v;\r
151 \r
152         disable_spawn_get = true;\r
153 \r
154   f = atoi(ValueForKey (edit_entity, "spawnflags"));\r
155   for (i=0 ; i<spawnflag_count ; i++)\r
156   {\r
157     v = !!(f&(1<<spawn_table[i]));\r
158     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]), v);\r
159   }\r
160   // take care of the remaining ones\r
161   for (i=spawnflag_count ; i<MAX_FLAGS ; i++)\r
162   {\r
163     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]), FALSE);\r
164   }\r
165 \r
166         disable_spawn_get = false;\r
167 }\r
168 \r
169 // GetSpawnFlags\r
170 // \r
171 // Update the entity flags to reflect the state of the checkboxes\r
172 //\r
173 // NOTE: this function had a tendency to add "spawnflags" "0" on most entities\r
174 //   if this wants to set spawnflags to zero, remove the key\r
175 \r
176 void GetSpawnFlags(void)\r
177 {\r
178   int f, i, v;\r
179   char sz[32];\r
180 \r
181   f = 0;\r
182   for (i=0 ; i<spawnflag_count ; i++)\r
183   {\r
184     v = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (EntWidgets[EntCheck1+i]));\r
185     f |= v<<spawn_table[i];\r
186   }\r
187 \r
188   if (f==0)\r
189   {\r
190     // remove all "spawnflags" keys\r
191     if (multiple_entities)\r
192     {\r
193       brush_t   *b;\r
194       \r
195       for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)\r
196         DeleteKey (b->owner, "spawnflags");\r
197     }\r
198     else\r
199       DeleteKey (edit_entity, "spawnflags");\r
200   }\r
201   else\r
202   {    \r
203     sprintf (sz, "%i", f);    \r
204     if (multiple_entities)\r
205     {\r
206       brush_t   *b;\r
207       \r
208       for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)\r
209         SetKeyValue(b->owner, "spawnflags", sz);\r
210     }\r
211     else\r
212       SetKeyValue (edit_entity, "spawnflags", sz);\r
213   }\r
214   SetKeyValuePairs ();\r
215 }\r
216 \r
217 //#define DBG_UPDATESEL\r
218 \r
219 // UpdateSel\r
220 //\r
221 // Update the listbox, checkboxes and k/v pairs to reflect the new selection\r
222 // iIndex is the index in the list box with the class name, -1 if not found\r
223 bool UpdateSel(int iIndex, eclass_t *pec)\r
224 {\r
225   int i, next_state;\r
226   brush_t *b;\r
227 \r
228   // syndrom of crappy code, we may get into stack overflowing crap with this function and Gtk \r
229   // if we play with the list of entity classes\r
230   // using a static flag to prevent recursion\r
231   static bool bBlockUpdate = false;\r
232 \r
233   if (bBlockUpdate)\r
234     return FALSE; // NOTE TTimo wtf is the return value for anyway?\r
235 \r
236 #ifdef DBG_UPDATESEL\r
237   Sys_FPrintf(SYS_WRN, "UpdateSel\n");\r
238 #endif\r
239 \r
240   if (selected_brushes.next == &selected_brushes)\r
241   {\r
242     edit_entity = world_entity;\r
243     multiple_entities = false;\r
244   }\r
245   else\r
246   {\r
247     edit_entity = selected_brushes.next->owner;\r
248     for (b=selected_brushes.next->next ; b != &selected_brushes ; b=b->next)\r
249     {\r
250       if (b->owner != edit_entity)\r
251       {\r
252         multiple_entities = true;\r
253         break;\r
254       }\r
255     }\r
256   }\r
257 \r
258   if (iIndex != -1)\r
259   {\r
260 #ifdef DBG_UPDATESEL\r
261     Sys_FPrintf(SYS_WRN,"Setting focus_row to %d\n", iIndex);\r
262 #endif\r
263     bBlockUpdate = true;\r
264 \r
265     GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);\r
266     GtkTreePath* path = gtk_tree_path_new();\r
267     gtk_tree_path_append_index(path, iIndex);\r
268     gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path);\r
269     gtk_tree_view_scroll_to_cell(view, path, NULL, FALSE, 0, 0);\r
270     gtk_tree_path_free(path);\r
271 \r
272     bBlockUpdate = false;\r
273   }\r
274 \r
275   if (pec == NULL)\r
276     return TRUE;\r
277 \r
278   // Set up the description\r
279   {\r
280     GtkTextBuffer* buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(EntWidgets[EntComment]));\r
281     gtk_text_buffer_set_text (buffer, pec->comments, -1);\r
282   }\r
283 \r
284   spawnflag_count = 0;\r
285 \r
286   // do a first pass to count the spawn flags, don't touch the widgets, we don't know in what state they are\r
287   for (i=0 ; i<MAX_FLAGS ; i++)\r
288   {\r
289     if (pec->flagnames[i] && pec->flagnames[i][0] != 0 && strcmp(pec->flagnames[i],"-"))\r
290     {\r
291       spawn_table[spawnflag_count] = i;\r
292       spawnflag_count++;\r
293     }\r
294   }\r
295 \r
296   // what's new widget state\r
297   if (spawnflag_count==0)\r
298     next_state = 1;\r
299   else if (spawnflag_count<=4)\r
300     next_state = 2;\r
301   else if (spawnflag_count<=8)\r
302     next_state = 3;\r
303   else if (spawnflag_count<=12)\r
304     next_state = 4;\r
305   else\r
306     next_state = 5;\r
307   widget_state = next_state;\r
308   static int last_count = 0;\r
309 \r
310   // disable all remaining boxes\r
311   // NOTE: these boxes might not even be on display\r
312   for (i = 0; i < last_count; i++)\r
313   {\r
314     GtkWidget* widget = EntWidgets[EntCheck1+i];\r
315     gtk_label_set_text (GTK_LABEL (GTK_BIN (widget)->child), " ");\r
316     gtk_widget_hide (widget);\r
317     gtk_widget_ref (widget);\r
318     gtk_container_remove (GTK_CONTAINER (LayoutTable), widget);\r
319   }\r
320   last_count = spawnflag_count;\r
321 \r
322   for (i=0 ; i<spawnflag_count ; i++)\r
323   {\r
324     GtkWidget* widget = EntWidgets[EntCheck1+i];\r
325     gtk_widget_show (widget);\r
326 \r
327     Str str;\r
328     str = pec->flagnames[spawn_table[i]];\r
329     str.MakeLower ();\r
330 \r
331 //    gtk_table_attach (GTK_TABLE (LayoutTable), widget, i%4, i%4+1, i/4, i/4+1,\r
332     gtk_table_attach (GTK_TABLE (LayoutTable), widget, i%4, i%4+1, i/4, i/4+1,\r
333                       (GtkAttachOptions) (GTK_FILL),\r
334                       (GtkAttachOptions) (GTK_FILL), 0, 0);\r
335     gtk_widget_unref (widget);\r
336 \r
337     gtk_label_set_text (GTK_LABEL (GTK_BIN (widget)->child), str.GetBuffer ());\r
338   }\r
339 \r
340   SetSpawnFlags();\r
341 \r
342   SetKeyValuePairs();\r
343 \r
344   return TRUE;\r
345 }\r
346 \r
347 bool UpdateEntitySel(eclass_t *pec)\r
348 {\r
349 #ifdef DBG_UPDATESEL\r
350   Sys_FPrintf(SYS_WRN, "UpdateEntitySel\n");\r
351 #endif\r
352 \r
353   GtkTreeModel* model = GTK_TREE_MODEL(g_entlist_store);\r
354   GtkTreeIter iter;\r
355   unsigned int i = 0;\r
356   for(gboolean good = gtk_tree_model_get_iter_first(model, &iter); good != FALSE; good = gtk_tree_model_iter_next(model, &iter))\r
357   {\r
358     char* text;\r
359     gtk_tree_model_get(model, &iter, 0, &text, -1);\r
360     if (strcmp (text, pec->name) == 0)\r
361     {\r
362 #ifdef DBG_UPDATESEL\r
363       Sys_FPrintf(SYS_WRN, "found a match: %d %s\n", i, pec->name);\r
364 #endif\r
365       return UpdateSel (i, pec);\r
366     }\r
367     g_free(text);\r
368     ++i;\r
369   }\r
370   return UpdateSel (-1, pec);\r
371 }\r
372 \r
373 // CreateEntity\r
374 //\r
375 // Creates a new entity based on the currently selected brush and entity type.\r
376 //\r
377 \r
378 void CreateEntity(void)\r
379 {\r
380   GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);\r
381 \r
382   // check to make sure we have a brush\r
383   if (selected_brushes.next == &selected_brushes)\r
384   {\r
385     gtk_MessageBox(g_pParentWnd->m_pWidget, "You must have a selected brush to create an entity", "info");\r
386     return;\r
387   }\r
388 \r
389   // find out what type of entity we are trying to create\r
390   GtkTreeModel* model;\r
391   GtkTreeIter iter;\r
392   if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), &model, &iter) == FALSE)\r
393   {\r
394     gtk_MessageBox (g_pParentWnd->m_pWidget, "You must have a selected class to create an entity", "info");\r
395     return;\r
396   }\r
397 \r
398   char* text;\r
399   gtk_tree_model_get(model, &iter, 0, &text, -1);\r
400   CreateEntityFromName(text, vec3_origin);\r
401   g_free(text);\r
402 \r
403   if (selected_brushes.next == &selected_brushes)\r
404     edit_entity = world_entity;\r
405   else\r
406     edit_entity = selected_brushes.next->owner;\r
407 \r
408   SetKeyValuePairs();\r
409   Select_Deselect ();\r
410   Select_Brush (edit_entity->brushes.onext);\r
411   Sys_UpdateWindows(W_ALL);\r
412 }\r
413 \r
414 /*\r
415 ===============\r
416 AddProp\r
417 \r
418 ===============\r
419 */\r
420 void AddProp()\r
421 {\r
422   if (edit_entity == NULL)\r
423     return;\r
424 \r
425   // Get current selection text\r
426   const char* key = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));\r
427   const char* value = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));\r
428 \r
429 \r
430   // TTimo: if you change the classname to worldspawn you won't merge back in the structural brushes but create a parasite entity\r
431   if (!strcmp(key, "classname") && !strcmp(value, "worldspawn"))\r
432   {\r
433     gtk_MessageBox(g_pParentWnd->m_pWidget,  "Cannot change \"classname\" key back to worldspawn.", NULL, MB_OK );\r
434     return;\r
435   }\r
436 \r
437 \r
438         // RR2DO2: we don't want spaces in entity keys\r
439         if (strstr( key, " " ))\r
440         {\r
441     gtk_MessageBox(g_pParentWnd->m_pWidget, "No spaces are allowed in entity keys.", NULL, MB_OK );\r
442     return;\r
443         }\r
444 \r
445   if (multiple_entities)\r
446   {\r
447     brush_t *b;\r
448 \r
449     for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)\r
450       SetKeyValue(b->owner, key, value);\r
451   }\r
452   else\r
453     SetKeyValue(edit_entity, key, value);\r
454 \r
455   // refresh the prop listbox\r
456   SetKeyValuePairs();   \r
457 \r
458 \r
459 #ifdef USEPLUGINENTITIES\r
460   // if it's a plugin entity, perhaps we need to update some drawing parameters\r
461   // NOTE: perhaps moving this code to a seperate func would help if we need it in other places\r
462   // TODO: we need to call some update func in the IPluginEntity in case model name changes etc.\r
463   // ( for the moment only bounding brush is updated ), see UpdateModelBrush in Ritual's Q3Radiant\r
464   if (edit_entity->eclass->nShowFlags & ECLASS_PLUGINENTITY)\r
465   {\r
466     vec3_t mins, maxs;\r
467     edit_entity->pPlugEnt->GetBounds( mins, maxs );\r
468     // replace old bounding brush by newly computed one\r
469     // NOTE: this part is similar to Entity_BuildModelBrush in Ritual's Q3Radiant, it can be\r
470     // usefull moved into a seperate func\r
471     brush_t *b,*oldbrush;\r
472     if (edit_entity->brushes.onext != &edit_entity->brushes)\r
473       oldbrush = edit_entity->brushes.onext;\r
474     b = Brush_Create (mins, maxs, &edit_entity->eclass->texdef);\r
475     Entity_LinkBrush (edit_entity, b);\r
476     Brush_Build( b, true );\r
477     Select_Deselect();\r
478     Brush_AddToList (edit_entity->brushes.onext, &selected_brushes);\r
479     if (oldbrush)\r
480       Brush_Free( oldbrush );\r
481   }\r
482 #endif // USEPLUGINENTITIES\r
483 }\r
484 \r
485 /*\r
486 ===============\r
487 DelProp\r
488 \r
489 ===============\r
490 */\r
491 void DelProp(void)\r
492 {\r
493   if (edit_entity == NULL)\r
494     return;\r
495 \r
496   // Get current selection text\r
497   const char* key = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));\r
498 \r
499   if (multiple_entities)\r
500   {\r
501     brush_t *b;\r
502 \r
503     for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)\r
504       DeleteKey(b->owner, key);\r
505   }\r
506   else\r
507     DeleteKey(edit_entity, key);\r
508 \r
509   // refresh the prop listbox\r
510   SetKeyValuePairs();\r
511 }\r
512 \r
513 void ResetEntity ()\r
514 {\r
515   epair_t *pep;\r
516   int i;\r
517 \r
518   if (edit_entity == NULL)\r
519     return;\r
520 \r
521   if (multiple_entities)\r
522   {\r
523     brush_t *b;\r
524 \r
525     for (b=selected_brushes.next; b != &selected_brushes; b=b->next)\r
526       for (pep = b->owner->epairs; pep; )\r
527       {\r
528         if (strcmp (pep->key, "classname") != 0)\r
529         {\r
530           DeleteKey (b->owner, pep->key);\r
531           pep = b->owner->epairs;\r
532         }\r
533         else\r
534           pep = pep->next;\r
535       }\r
536   }\r
537   else\r
538     for (pep = edit_entity->epairs; pep; )\r
539     {\r
540       if (strcmp (pep->key, "classname") != 0)\r
541       {\r
542         DeleteKey (edit_entity, pep->key);\r
543         pep = edit_entity->epairs;\r
544       }\r
545       else\r
546         pep = pep->next;\r
547     }\r
548 \r
549   // refresh the dialog\r
550   SetKeyValuePairs ();\r
551   for (i = EntCheck1; i <= EntCheck16; i++)\r
552     gtk_signal_handler_block_by_func (GTK_OBJECT (EntWidgets[i]), GTK_SIGNAL_FUNC (entity_check), NULL);\r
553   SetSpawnFlags ();\r
554   for (i = EntCheck1; i <= EntCheck16; i++)\r
555     gtk_signal_handler_unblock_by_func (GTK_OBJECT (EntWidgets[i]), GTK_SIGNAL_FUNC (entity_check), NULL);\r
556 }\r
557 \r
558 bool GetSelectAllCriteria(CString &strKey, CString &strVal)\r
559 {\r
560   GtkTreeModel* model;\r
561   GtkTreeIter iter;\r
562   if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(EntWidgets[EntProps])), &model, &iter)\r
563     && (inspector_mode == W_ENTITY)\r
564     && GTK_WIDGET_VISIBLE (g_pGroupDlg->m_pWidget))\r
565   {\r
566     strKey = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntKeyField]));\r
567     strVal = gtk_entry_get_text (GTK_ENTRY (EntWidgets[EntValueField]));\r
568     return TRUE;\r
569   }\r
570   return FALSE;\r
571 }\r
572 \r
573 \r
574 void AssignSound()\r
575 {\r
576   char buffer[NAME_MAX];\r
577 \r
578   strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());\r
579   strcat (buffer, "sound/");\r
580 \r
581   if( access(buffer, R_OK) != 0 )\r
582   {\r
583     // just go to fsmain\r
584     strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());\r
585     strcat (buffer, "/");\r
586   }\r
587 \r
588   const char *filename = file_dialog (g_pGroupDlg->m_pWidget, TRUE, "Open Wav File", buffer, "sound");\r
589   if (filename != NULL)\r
590   {\r
591     gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), "noise");\r
592     char *aux = vfsExtractRelativePath (filename);\r
593     CString str;\r
594     if (aux)\r
595       str = aux;\r
596     else\r
597     {\r
598       Sys_FPrintf (SYS_WRN, "WARNING: could not extract the relative path, using full path instead\n");\r
599       str = filename;\r
600     }\r
601 \r
602     gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), str.GetBuffer());        \r
603     AddProp();\r
604   }\r
605 }\r
606 \r
607 void AssignModel()\r
608 {\r
609   char buffer[NAME_MAX];\r
610 \r
611   strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());\r
612   strcat (buffer, "models/");\r
613 \r
614   if( access(buffer, R_OK) != 0 )\r
615   {\r
616     // just go to fsmain\r
617     strcpy (buffer, g_qeglobals.m_strHomeMaps.GetBuffer());\r
618     strcat (buffer, "/");\r
619   }\r
620 \r
621   const char *filename = file_dialog (g_pGroupDlg->m_pWidget, TRUE, "Open Model", buffer, MODEL_MAJOR);\r
622   if (filename != NULL)\r
623   {\r
624     gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), "model");\r
625     // use VFS to get the correct relative path\r
626     char *aux = vfsExtractRelativePath (filename);\r
627     CString str;\r
628     if (aux)\r
629       str = aux;\r
630     else\r
631     {\r
632       Sys_FPrintf (SYS_WRN, "WARNING: could not extract the relative path, using full path instead\n");\r
633       str = filename;\r
634     }\r
635 \r
636     gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), str.GetBuffer());        \r
637     AddProp();\r
638     edit_entity->brushes.onext->bModelFailed = false;\r
639   }\r
640 }\r
641 \r
642 /*\r
643 ==============\r
644 SetInspectorMode\r
645 ==============\r
646 */\r
647 void SetInspectorMode(int iType)\r
648 {\r
649   if (iType == W_GROUP)\r
650     gtk_MessageBox(g_pParentWnd->m_pWidget, "Brush grouping is not functional yet", NULL, MB_OK | MB_ICONWARNING );\r
651 \r
652   if (!g_pParentWnd->FloatingGroupDialog() &&\r
653       (iType == W_TEXTURE || iType == W_CONSOLE))\r
654     return;\r
655 \r
656   // Is the caller asking us to cycle to the next window?\r
657   if (iType == -1)\r
658   {\r
659     if (inspector_mode == W_ENTITY)\r
660       iType = W_TEXTURE;\r
661     else if (inspector_mode == W_TEXTURE)\r
662       iType = W_CONSOLE;\r
663     else if (inspector_mode == W_CONSOLE)\r
664       iType = W_GROUP;\r
665     else\r
666       iType = W_ENTITY;\r
667   }             \r
668 \r
669   switch(iType)\r
670   {\r
671   case W_ENTITY:\r
672     // entity is always first in the inspector\r
673     gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Entities");\r
674     gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 0);\r
675     break;\r
676 \r
677   case W_TEXTURE:\r
678     g_pParentWnd->GetTexWnd()->FocusEdit();\r
679     gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Textures");\r
680     if (g_pParentWnd->FloatingGroupDialog())\r
681       gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 1);\r
682     break;\r
683 \r
684   case W_CONSOLE:\r
685     gtk_window_set_title (GTK_WINDOW (g_qeglobals_gui.d_entity), "Console");\r
686     if (g_pParentWnd->FloatingGroupDialog())\r
687       gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 2);\r
688     break;\r
689 \r
690   case W_GROUP:\r
691     if (g_pParentWnd->FloatingGroupDialog())\r
692       gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 3);\r
693     else\r
694       gtk_notebook_set_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), 1);\r
695     break;\r
696 \r
697   default:\r
698     break;\r
699   }\r
700 }\r
701 \r
702 void Group_Add(entity_t *e)\r
703 {\r
704   /*\r
705   group_t *g = (group_t*)qmalloc(sizeof(group_t));\r
706   g->epairs = e->epairs;\r
707   g->next = NULL;\r
708   e->epairs = NULL;\r
709 \r
710   // create a new group node\r
711   char *text = ValueForKey(g->epairs, "group");\r
712   g->itemOwner = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), g_wndGroup.m_hWorld, NULL, &text, 0,\r
713                                         tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP],\r
714                                         tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], TRUE, TRUE);\r
715   g->next = g_pGroups;\r
716   g_pGroups = g;\r
717   */\r
718 }\r
719 /*\r
720 group_t* Group_Alloc(char *name)\r
721 {\r
722   group_t *g = (group_t*)qmalloc(sizeof(group_t));\r
723   SetKeyValue( g->epairs, "group", name );\r
724   return g;\r
725 }\r
726 \r
727 group_t* Group_ForName(const char * name)\r
728 {\r
729   group_t *g = g_pGroups;\r
730   while (g != NULL)\r
731   {\r
732     if (strcmp( ValueForKey(g->epairs,"group"), name ) == 0)\r
733       break;\r
734     g = g->next;\r
735   }\r
736   return g;\r
737 }\r
738 \r
739 void Group_AddToItem(brush_t *b, GtkCTreeNode* item)\r
740 {\r
741   int nImage = IMG_BRUSH;\r
742   if (!g_qeglobals.m_bBrushPrimitMode)\r
743   {\r
744     return;\r
745   }\r
746   const char *pName = NULL;\r
747   //  const char *pNamed = Brush_GetKeyValue(b, "name");\r
748  \r
749   if (!b->owner || (b->owner == world_entity))\r
750   {\r
751     if (b->patchBrush) \r
752     {\r
753       pName = "Generic Patch";\r
754       nImage = IMG_PATCH;\r
755     } \r
756     else \r
757     {\r
758       pName = "Generic Brush";\r
759       nImage = IMG_BRUSH;\r
760     }\r
761   } \r
762   else \r
763   {\r
764     pName = b->owner->eclass->name;\r
765     if (b->owner->eclass->fixedsize) \r
766     {\r
767       nImage = IMG_ENTITY;\r
768     } \r
769     else \r
770     {\r
771       nImage = IMG_ENTITYGROUP;\r
772     }\r
773   }\r
774 \r
775   GtkCTreeNode *newItem;\r
776   int i = (b->patchBrush) ? IMG_PATCH : IMG_BRUSH;\r
777   newItem = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), item, NULL, (gchar**)&pName, 0,\r
778                                    tree_pixmaps[i], tree_masks[i], tree_pixmaps[i],\r
779                                    tree_masks[i], TRUE, TRUE);\r
780   gtk_ctree_node_set_row_data (GTK_CTREE (g_wndGroup.m_pTree), newItem, b);\r
781   b->itemOwner = newItem;\r
782 }\r
783 */\r
784 void Group_RemoveBrush(brush_t *b)\r
785 {\r
786   /*\r
787   if (!g_qeglobals.m_bBrushPrimitMode)\r
788   {\r
789     return;\r
790   }\r
791   if (b->itemOwner)\r
792   {\r
793     gtk_ctree_remove_node (GTK_CTREE (g_pGroupDlg->m_pTree), b->itemOwner);\r
794     b->itemOwner = NULL;\r
795   }\r
796   DeleteKey(b->epairs, "group");\r
797   */\r
798 }\r
799 /*\r
800 void Group_AddToWorld(brush_t *b)\r
801 {\r
802   if (!g_qeglobals.m_bBrushPrimitMode)\r
803   {\r
804     return;\r
805   }\r
806   GtkCTreeNode *parent = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), 0);\r
807   Group_AddToItem(b, parent);\r
808 }\r
809 */\r
810 void Group_AddToProperGroup(brush_t *b)\r
811 {\r
812   /*\r
813   if (!g_qeglobals.m_bBrushPrimitMode)\r
814   {\r
815     return;\r
816   }\r
817 \r
818   // NOTE: we do a local copy of the "group" key because it gets erased by Group_RemoveBrush\r
819   const char *pGroup = Brush_GetKeyValue(b, "group");\r
820   // remove the entry in the tree if there's one\r
821   if (b->itemOwner)\r
822   {\r
823     gtk_ctree_remove_node (GTK_CTREE (g_pGroupDlg->m_pTree), b->itemOwner);\r
824     b->itemOwner = NULL;\r
825   }\r
826 \r
827   if (*pGroup != 0)\r
828   {\r
829     // find the item\r
830     group_t *g = Group_ForName(pGroup);\r
831     if (g)\r
832       Group_AddToItem(b, g->itemOwner);\r
833 #ifdef _DEBUG\r
834     else\r
835       Sys_Printf("WARNING: unexpected Group_ForName not found in Group_AddToProperGroup\n");\r
836 #endif\r
837   }\r
838   else\r
839   {\r
840     Group_AddToWorld(b);\r
841   }\r
842   */\r
843 }\r
844 /*\r
845 void Group_AddToSelected(brush_t *b)\r
846 {\r
847   if (!g_qeglobals.m_bBrushPrimitMode)\r
848   {\r
849     return;\r
850   }\r
851   GtkCTreeNode *item;\r
852   item = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), GTK_CLIST (g_pGroupDlg->m_pTree)->focus_row);\r
853   if (item == NULL)\r
854   {\r
855     item = gtk_ctree_node_nth (GTK_CTREE (g_pGroupDlg->m_pTree), 0);\r
856   }\r
857   Group_AddToItem(b, item);\r
858 }\r
859 */\r
860 /*\r
861 void Group_Save(FILE *f)\r
862 {\r
863   group_t *g = g_pGroups;\r
864   while (g)\r
865   {\r
866     fprintf(f,"{\n\"classname\" \"group_info\"\n\"group\" \"%s\"\n}\n", ValueForKey( g->epairs, "group" ));\r
867     g = g->next;\r
868   }\r
869 }\r
870 */\r
871 \r
872 void Group_Init()\r
873 {\r
874   if (!g_qeglobals.m_bBrushPrimitMode)\r
875   {\r
876     return;\r
877   }\r
878   // start by cleaning everything\r
879   // clean the groups\r
880   //++timo FIXME: we leak, delete the groups on the way (I don't have time to do it now)\r
881 #ifdef _DEBUG\r
882   Sys_Printf("TODO: fix leak in Group_Init\n");\r
883 #endif\r
884   group_t *g = g_pGroups;\r
885   while (g)\r
886   {\r
887     epair_t *ep,*enext;\r
888     for (ep = g->epairs ; ep ; ep=enext )\r
889     {\r
890       enext = ep->next;\r
891       free (ep->key);\r
892       free (ep->value);\r
893       free (ep);\r
894     }\r
895     g = g->next;\r
896   }\r
897   /*\r
898   GtkCTreeNode *world;\r
899   char *text = "World";\r
900   g_pGroups = NULL;\r
901   gtk_clist_clear (GTK_CLIST (g_wndGroup.m_pTree));\r
902   world = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), NULL, NULL, &text, 0,\r
903                                  tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], tree_pixmaps[IMG_GROUP],\r
904                                  tree_masks[IMG_GROUP], FALSE, TRUE);\r
905   */\r
906   // walk through all the brushes, remove the itemOwner key and add them back where they belong\r
907   brush_t *b;\r
908   for (b = active_brushes.next; b != &active_brushes; b = b->next)\r
909   {\r
910     b->itemOwner = NULL;\r
911     Group_AddToProperGroup(b);\r
912   }\r
913   for (b = selected_brushes.next ; b != &selected_brushes ; b = b->next)\r
914   {\r
915     b->itemOwner = NULL;\r
916     Group_AddToProperGroup(b);\r
917   }\r
918 }\r
919 /*\r
920 // scan through world_entity for groups in this map?\r
921 // we use GROUPNAME "QER_group_%i" to look for existing groups and their naming\r
922 //++timo FIXME: is this actually needed for anything?\r
923 void Group_GetListFromWorld(GSList **pArray)\r
924 {\r
925   if (!g_qeglobals.m_bBrushPrimitMode)\r
926   {\r
927     return;\r
928   }\r
929 \r
930   if (world_entity == NULL)\r
931   {\r
932     return;\r
933   }\r
934 \r
935   char cBuff[1024];\r
936   for (int i =0; i < MAX_GROUPS; i++)\r
937   {\r
938     sprintf(cBuff, GROUPNAME, i);\r
939     char *pGroup = ValueForKey(world_entity, cBuff);\r
940     if (pGroup && strlen(pGroup) > 0)\r
941     {\r
942       *pArray = g_slist_append (*pArray, g_strdup (pGroup));\r
943     }\r
944     else\r
945     {\r
946       break;\r
947     }\r
948   }\r
949 }\r
950 \r
951 void Group_RemoveListFromWorld()\r
952 {\r
953   if (!g_qeglobals.m_bBrushPrimitMode)\r
954   {\r
955     return;\r
956   }\r
957   GSList* array = NULL;\r
958   Group_GetListFromWorld(&array);\r
959 \r
960   while (array)\r
961   {\r
962     DeleteKey(world_entity, (char*)array->data);\r
963     g_free (array->data);\r
964     array = g_slist_remove (array, array->data);\r
965   }\r
966 }\r
967 \r
968 int CountChar(const char *p, char c)\r
969 {\r
970   int nCount = 0;\r
971   int nLen = strlen(p)-1;\r
972   while (nLen-- >= 0)\r
973   {\r
974     if (p[nLen] == c)\r
975     {\r
976       nCount++;\r
977     }\r
978   }\r
979   return nCount;\r
980 }\r
981 */\r
982 // =============================================================================\r
983 // callbacks\r
984 \r
985 static void eclasslist_selection_changed(GtkTreeSelection* selection, gpointer data)\r
986 {\r
987   GtkTreeModel* model;\r
988   GtkTreeIter selected;\r
989   // no world entity, we are not ready yet\r
990   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=917\r
991   if( !world_entity ) {\r
992     return;  \r
993   }\r
994   if(gtk_tree_selection_get_selected(selection, &model, &selected))\r
995   {\r
996     eclass_t* eclass;\r
997     gtk_tree_model_get(model, &selected, 1, &eclass, -1);\r
998     if(eclass != NULL)\r
999     {\r
1000       GtkTreePath* path = gtk_tree_model_get_path(model, &selected);\r
1001       UpdateSel(gtk_tree_path_get_indices(path)[0], eclass);\r
1002       gtk_tree_path_free(path);\r
1003     }\r
1004   }\r
1005 }\r
1006 \r
1007 static gint eclasslist_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)\r
1008 {\r
1009   if (event->type == GDK_2BUTTON_PRESS)\r
1010   {\r
1011     CreateEntity ();\r
1012     return TRUE;\r
1013   }\r
1014   return FALSE;\r
1015 }\r
1016 \r
1017 static gint eclasslist_keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)\r
1018 {\r
1019   unsigned int code = gdk_keyval_to_upper (event->keyval);\r
1020 \r
1021   if (event->keyval == GDK_Return)\r
1022   {\r
1023     CreateEntity ();\r
1024     return TRUE;\r
1025   }\r
1026 \r
1027   // select the entity that starts with the key pressed\r
1028   if (code <= 'Z' && code >= 'A')\r
1029   {\r
1030     GtkTreeView* view = GTK_TREE_VIEW(EntWidgets[EntList]);\r
1031     GtkTreeModel* model;\r
1032     GtkTreeIter iter;\r
1033     if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), &model, &iter) == FALSE\r
1034       || gtk_tree_model_iter_next(model, &iter) == FALSE)\r
1035     {\r
1036       gtk_tree_model_get_iter_first(model, &iter);\r
1037     }\r
1038 \r
1039     for(unsigned int count = gtk_tree_model_iter_n_children(model, NULL); count > 0; --count)\r
1040     {\r
1041       char* text;\r
1042       gtk_tree_model_get(model, &iter, 0, &text, -1);\r
1043 \r
1044       if (toupper (text[0]) == (int)code)\r
1045       {\r
1046         GtkTreePath* path = gtk_tree_model_get_path(model, &iter);\r
1047         gtk_tree_selection_select_path(gtk_tree_view_get_selection(view), path);\r
1048         gtk_tree_view_scroll_to_cell(view, path, NULL, FALSE, 0, 0);\r
1049         gtk_tree_path_free(path);\r
1050         count = 1;\r
1051       }\r
1052 \r
1053       g_free(text);\r
1054 \r
1055       if(gtk_tree_model_iter_next(model, &iter) == FALSE)\r
1056         gtk_tree_model_get_iter_first(model, &iter);\r
1057     }\r
1058 \r
1059     return TRUE;\r
1060   }\r
1061   return FALSE;\r
1062 }\r
1063 \r
1064 \r
1065 static void proplist_selection_changed(GtkTreeSelection* selection, gpointer data)\r
1066 {\r
1067   // find out what type of entity we are trying to create\r
1068   GtkTreeModel* model;\r
1069   GtkTreeIter iter;\r
1070   if(gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)\r
1071   {\r
1072     return;\r
1073   }\r
1074 \r
1075   char* key;\r
1076   char* val;\r
1077   gtk_tree_model_get(model, &iter, 0, &key, 1, &val, -1);\r
1078 \r
1079   gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), key);\r
1080   gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), val);\r
1081 \r
1082   g_free(key);\r
1083   g_free(val);\r
1084 }\r
1085 \r
1086 static void entity_check (GtkWidget *widget, gpointer data)\r
1087 {\r
1088   if( !disable_spawn_get )\r
1089     GetSpawnFlags();\r
1090 }\r
1091 \r
1092 static void entitylist_angle (GtkWidget *widget, gpointer data)\r
1093 {\r
1094   SetKeyValue (edit_entity, "angle", (char*)data);\r
1095   SetKeyValuePairs ();\r
1096 }\r
1097 \r
1098 static gint entityentry_keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)\r
1099 {\r
1100   if (event->keyval == GDK_Tab)\r
1101   {\r
1102     if (widget == EntWidgets[EntKeyField])\r
1103     {\r
1104       //gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), "");\r
1105       gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntValueField]);\r
1106     }\r
1107     else\r
1108       gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntKeyField]);\r
1109 \r
1110     return TRUE;\r
1111   }\r
1112   else if (event->keyval == GDK_Return)\r
1113   {\r
1114     if (widget == EntWidgets[EntKeyField])\r
1115     {\r
1116       gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), "");\r
1117       gtk_window_set_focus (GTK_WINDOW (g_pGroupDlg->m_pWidget), EntWidgets[EntValueField]);\r
1118     }\r
1119     else\r
1120     {\r
1121       AddProp ();\r
1122     }\r
1123     return TRUE;\r
1124   }\r
1125 \r
1126   return FALSE;\r
1127 }\r
1128 /*\r
1129 // add a new group, put all selected brushes into the group\r
1130 static void groupdlg_add (GtkWidget *widget, gpointer data)\r
1131 {\r
1132   char* name = DoNameDlg ("New Group");\r
1133 \r
1134   if (name != NULL)\r
1135   {\r
1136     // create a new group node  \r
1137     GtkCTreeNode *item;\r
1138     item = gtk_ctree_insert_node (GTK_CTREE (g_wndGroup.m_pTree), g_pGroupDlg->m_hWorld, NULL, &name, 0,\r
1139                                   tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP],\r
1140                                   tree_pixmaps[IMG_GROUP], tree_masks[IMG_GROUP], FALSE, TRUE);\r
1141 \r
1142     // create a new group\r
1143     group_t *g = Group_Alloc (name);\r
1144     g->itemOwner = item;\r
1145     g->next = g_pGroups;\r
1146     g_pGroups = g;\r
1147 \r
1148     // now add the selected brushes\r
1149     // NOTE: it would be much faster to give the group_t for adding\r
1150     // but Select_AddToGroup is the standard way for all other cases\r
1151     Select_AddToGroup (name);\r
1152     g_free (name);\r
1153   }\r
1154 }\r
1155 */\r
1156 static void switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data)\r
1157 {\r
1158   char *text;\r
1159   gtk_label_get(GTK_LABEL(gtk_notebook_get_tab_label(notebook, gtk_notebook_get_nth_page(notebook, page_num))), &text);\r
1160   gtk_window_set_title (GTK_WINDOW (data), text);\r
1161 \r
1162   gpointer item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_misc_selectentitycolor");\r
1163 \r
1164   if (g_pParentWnd->FloatingGroupDialog())\r
1165   {\r
1166     switch (page_num)\r
1167     {\r
1168     case 0: inspector_mode = W_ENTITY; break;\r
1169     case 1: inspector_mode = W_TEXTURE; break;\r
1170     case 2: inspector_mode = W_CONSOLE; break;\r
1171     default: inspector_mode = W_GROUP; break;\r
1172     }\r
1173   }\r
1174   else\r
1175   {\r
1176     if (page_num == 0)\r
1177       inspector_mode = W_ENTITY;\r
1178     else\r
1179       inspector_mode = W_GROUP;\r
1180   }\r
1181   \r
1182   if (inspector_mode == W_ENTITY)\r
1183     gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);\r
1184   else\r
1185     gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);\r
1186 }\r
1187 \r
1188 // =============================================================================\r
1189 // GroupDlg class\r
1190 \r
1191 // NOTE: when a key is hit with group window focused, we catch in this handler but it gets propagated to mainframe too\r
1192 //   therefore the message will be intercepted and used as a ID_SELECTION_DESELECT\r
1193 static gint OnDialogKey (GtkWidget* widget, GdkEventKey* event, gpointer data)\r
1194 {\r
1195 #ifdef DBG_PI\r
1196   Sys_Printf("OnDialogKey\n");\r
1197 #endif\r
1198   if ((event->keyval == GDK_Escape) && (g_pParentWnd->CurrentStyle() != MainFrame::eFloating))\r
1199   {\r
1200     // toggle off the group view (whatever part of it is currently displayed)\r
1201     // this used to be done with a g_pParentWnd->OnViewEntity(); but it had bad consequences\r
1202     // http://fenris.lokigames.com/show_bug.cgi?id=2773\r
1203     widget_delete_hide (g_qeglobals_gui.d_entity);\r
1204     return TRUE;\r
1205   }\r
1206   return FALSE;\r
1207 }\r
1208 \r
1209 GroupDlg::GroupDlg ()\r
1210 {\r
1211   m_pWidget = NULL;\r
1212   m_hWorld = NULL;\r
1213 }\r
1214 \r
1215 #ifdef _WIN32\r
1216 extern void PositionWindowOnPrimaryScreen(window_position_t& position);\r
1217 #endif\r
1218 \r
1219 void GroupDlg::Create ()\r
1220 {\r
1221   if (m_pWidget != NULL)\r
1222     return;\r
1223 \r
1224   GtkWidget* dlg = gtk_window_new (GTK_WINDOW_TOPLEVEL);\r
1225 \r
1226 #ifdef _WIN32\r
1227   if( g_PrefsDlg.m_bStartOnPrimMon ) {\r
1228     PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posEntityWnd );\r
1229   }\r
1230 #endif\r
1231   load_window_pos (dlg, g_PrefsDlg.mWindowInfo.posEntityWnd);\r
1232 \r
1233   gtk_window_set_title (GTK_WINDOW (dlg), "Entities");\r
1234   gtk_signal_connect (GTK_OBJECT (dlg), "delete_event", GTK_SIGNAL_FUNC (widget_delete_hide), NULL);\r
1235   // catch 'Esc'\r
1236   gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event", GTK_SIGNAL_FUNC (OnDialogKey), NULL);\r
1237   gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (g_pParentWnd->m_pWidget));\r
1238   g_qeglobals_gui.d_entity = dlg;\r
1239 \r
1240   {\r
1241     GtkWidget* notebook = gtk_notebook_new ();\r
1242     gtk_widget_show (notebook);\r
1243     gtk_container_add (GTK_CONTAINER (dlg), notebook);\r
1244     gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_BOTTOM);\r
1245     m_pNotebook = notebook;\r
1246 \r
1247     {\r
1248       GtkWidget* vbox = gtk_vbox_new (FALSE, 2);\r
1249       gtk_widget_show (vbox);\r
1250       gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);\r
1251 \r
1252       {\r
1253         GtkWidget* label = gtk_label_new ("Entities");\r
1254         gtk_widget_show (label);\r
1255         gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);\r
1256       }\r
1257 \r
1258       {\r
1259         GtkWidget* split1 = gtk_vpaned_new ();\r
1260         gtk_box_pack_start (GTK_BOX (vbox), split1, TRUE, TRUE, 0);\r
1261         gtk_widget_show (split1);\r
1262   \r
1263         {\r
1264           GtkWidget* split2 = gtk_vpaned_new ();\r
1265           gtk_paned_add1 (GTK_PANED (split1), split2);\r
1266           gtk_widget_show (split2);\r
1267 \r
1268           g_object_set_data (G_OBJECT (dlg), "split1", split1);\r
1269           g_object_set_data (G_OBJECT (dlg), "split2", split2);\r
1270 \r
1271           {\r
1272             GtkWidget* vbox2 = gtk_vbox_new (FALSE, 2);\r
1273             gtk_widget_show (vbox2);\r
1274             gtk_paned_pack2 (GTK_PANED (split1), vbox2, FALSE, FALSE);\r
1275 \r
1276             {\r
1277               GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);\r
1278               gtk_widget_show (scr);\r
1279               gtk_paned_add1 (GTK_PANED (split2), scr);\r
1280               gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);\r
1281               gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);\r
1282 \r
1283               {\r
1284                 GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);\r
1285 \r
1286                 GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));\r
1287                 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);\r
1288                 g_signal_connect(G_OBJECT(view), "button_press_event", G_CALLBACK(eclasslist_button_press), NULL);\r
1289                 g_signal_connect(G_OBJECT(view), "key_press_event", G_CALLBACK(eclasslist_keypress), this);\r
1290 \r
1291                 {\r
1292                   GtkCellRenderer* renderer = gtk_cell_renderer_text_new();\r
1293                   GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Key", renderer, "text", 0, NULL);\r
1294                   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);\r
1295                 }\r
1296 \r
1297                 {\r
1298                   GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));\r
1299                   g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(eclasslist_selection_changed), dlg);\r
1300                 }\r
1301 \r
1302                 gtk_widget_show(view);\r
1303 \r
1304                 gtk_container_add(GTK_CONTAINER (scr), view);\r
1305     \r
1306                 g_object_unref(G_OBJECT(store));\r
1307                 EntWidgets[EntList] = view;\r
1308                 g_entlist_store = store;\r
1309               }\r
1310             }\r
1311 \r
1312             {\r
1313               GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);\r
1314               gtk_widget_show (scr);\r
1315               gtk_paned_add2 (GTK_PANED (split2), scr);\r
1316               gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);\r
1317               gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);\r
1318 \r
1319               {\r
1320                 GtkWidget* text = gtk_text_view_new();\r
1321                 gtk_widget_set_size_request(text, 0, -1); // allow shrinking\r
1322                 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);\r
1323                 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);\r
1324                 gtk_widget_show (text);\r
1325                 gtk_container_add (GTK_CONTAINER (scr), text);\r
1326                 EntWidgets[EntComment] = text;\r
1327               }\r
1328             }\r
1329 \r
1330             {\r
1331               // Spawnflags (4 colums wide max, or window gets too wide.)\r
1332               GtkWidget* table = LayoutTable = gtk_table_new (4, 4, FALSE);\r
1333               gtk_box_pack_start (GTK_BOX (vbox2), LayoutTable, FALSE, TRUE, 0);\r
1334               gtk_widget_show(LayoutTable);\r
1335 \r
1336               for (int i = 0; i < MAX_FLAGS; i++)\r
1337               {\r
1338                 GtkWidget* check = gtk_check_button_new_with_label ("");\r
1339                 gtk_widget_ref (check);\r
1340                 gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);\r
1341                 EntWidgets[EntCheck1+i] = check;\r
1342               }\r
1343 \r
1344               //++timo cleanme: these flags where Q2 stuff\r
1345             /*\r
1346               check = gtk_check_button_new_with_label ("!Easy");\r
1347               gtk_widget_show (check);\r
1348               gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);\r
1349               gtk_table_attach (GTK_TABLE (table), check, 2, 3, 0, 1,\r
1350                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
1351                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);\r
1352               EntWidgets[EntCheck17] = check;\r
1353 \r
1354               check = gtk_check_button_new_with_label ("!Medium");\r
1355               gtk_widget_show (check);\r
1356               gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);\r
1357               gtk_table_attach (GTK_TABLE (table), check, 2, 3, 1, 2,\r
1358                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
1359                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);\r
1360               EntWidgets[EntCheck18] = check;\r
1361 \r
1362               check = gtk_check_button_new_with_label ("!Hard");\r
1363               gtk_widget_show (check);\r
1364               gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);\r
1365               gtk_table_attach (GTK_TABLE (table), check, 2, 3, 2, 3,\r
1366                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
1367                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);\r
1368               EntWidgets[EntCheck19] = check;\r
1369 \r
1370               check = gtk_check_button_new_with_label ("!DeathMatch");\r
1371               gtk_widget_show (check);\r
1372               gtk_signal_connect (GTK_OBJECT (check), "toggled", GTK_SIGNAL_FUNC (entity_check), NULL);\r
1373               gtk_table_attach (GTK_TABLE (table), check, 2, 3, 3, 4,\r
1374                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
1375                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);\r
1376               EntWidgets[EntCheck20] = check;\r
1377             */\r
1378             }\r
1379 \r
1380             {\r
1381               GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);\r
1382               gtk_widget_show (scr);\r
1383               gtk_box_pack_start (GTK_BOX (vbox2), scr, TRUE, TRUE, 0);\r
1384               gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);\r
1385               gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);\r
1386 \r
1387               {\r
1388                 GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);\r
1389 \r
1390                 GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));\r
1391                 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);\r
1392 \r
1393                 {\r
1394                   GtkCellRenderer* renderer = gtk_cell_renderer_text_new();\r
1395                   GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);\r
1396                   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);\r
1397                 }\r
1398 \r
1399                 {\r
1400                   GtkCellRenderer* renderer = gtk_cell_renderer_text_new();\r
1401                   GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 1, NULL);\r
1402                   gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);\r
1403                 }\r
1404 \r
1405                 {\r
1406                   GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));\r
1407                   g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(proplist_selection_changed), dlg);\r
1408                 }\r
1409 \r
1410                 gtk_widget_show(view);\r
1411 \r
1412                 gtk_container_add(GTK_CONTAINER (scr), view);\r
1413     \r
1414                 g_object_unref(G_OBJECT(store));\r
1415 \r
1416                 EntWidgets[EntProps] = view;\r
1417                 g_entprops_store = store;\r
1418               }\r
1419             }\r
1420           }\r
1421 \r
1422           int x = g_PrefsDlg.mWindowInfo.nEntitySplit1;\r
1423           if (x != -1)\r
1424           {\r
1425             gtk_paned_set_position (GTK_PANED (split1), x);\r
1426 \r
1427             while (gtk_events_pending ())  gtk_main_iteration ();\r
1428             x = g_PrefsDlg.mWindowInfo.nEntitySplit2;\r
1429 \r
1430             if (x != -1)\r
1431               gtk_paned_set_position (GTK_PANED (split2), x);\r
1432           }\r
1433         }\r
1434       }\r
1435 \r
1436       {\r
1437         GtkWidget* table = gtk_table_new (2, 2, FALSE);\r
1438         gtk_widget_show (table);\r
1439         gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);\r
1440         gtk_table_set_row_spacings (GTK_TABLE (table), 3);\r
1441         gtk_table_set_col_spacings (GTK_TABLE (table), 5);\r
1442 \r
1443         {\r
1444           GtkWidget* entry = gtk_entry_new ();\r
1445           gtk_widget_show (entry);\r
1446           gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,\r
1447                             (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
1448                             (GtkAttachOptions) (0), 0, 0);\r
1449           gtk_widget_set_events (entry, GDK_KEY_PRESS_MASK);\r
1450           gtk_signal_connect (GTK_OBJECT (entry), "key_press_event",\r
1451                               GTK_SIGNAL_FUNC (entityentry_keypress), this);\r
1452           EntWidgets[EntKeyField] = entry;\r
1453         }\r
1454 \r
1455         {\r
1456           GtkWidget* entry = gtk_entry_new ();\r
1457           gtk_widget_show (entry);\r
1458           gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,\r
1459                             (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),\r
1460                             (GtkAttachOptions) (0), 0, 0);\r
1461           gtk_widget_set_events (entry, GDK_KEY_PRESS_MASK);\r
1462           gtk_signal_connect (GTK_OBJECT (entry), "key_press_event",\r
1463                               GTK_SIGNAL_FUNC (entityentry_keypress), this);\r
1464           EntWidgets[EntValueField] = entry;\r
1465         }\r
1466 \r
1467         {\r
1468           GtkWidget* label = gtk_label_new ("Value");\r
1469           gtk_widget_show (label);\r
1470           gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,\r
1471                             (GtkAttachOptions) (GTK_FILL),\r
1472                             (GtkAttachOptions) (0), 0, 0);\r
1473           gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);\r
1474         }\r
1475 \r
1476         {\r
1477           GtkWidget* label = gtk_label_new ("Key");\r
1478           gtk_widget_show (label);\r
1479           gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,\r
1480                             (GtkAttachOptions) (GTK_FILL),\r
1481                             (GtkAttachOptions) (0), 0, 0);\r
1482           gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);\r
1483         }\r
1484       }\r
1485 \r
1486       {\r
1487         GtkWidget* hbox = gtk_hbox_new (FALSE, 5);\r
1488         gtk_widget_show (hbox);\r
1489         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);\r
1490 \r
1491         {\r
1492           GtkWidget* table = gtk_table_new (3, 3, TRUE);\r
1493           gtk_widget_show (table);\r
1494           gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, TRUE, 0);\r
1495 \r
1496           {\r
1497             GtkWidget* button = gtk_button_new_with_label ("360");\r
1498             gtk_widget_show (button);\r
1499             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"360");\r
1500             gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,\r
1501                               (GtkAttachOptions) (GTK_FILL),\r
1502                               (GtkAttachOptions) (GTK_FILL), 0, 0);\r
1503           }\r
1504 \r
1505           {\r
1506             GtkWidget* button = gtk_button_new_with_label ("45");\r
1507             gtk_widget_show (button);\r
1508             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"45");\r
1509             gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,\r
1510                               (GtkAttachOptions) (GTK_FILL),\r
1511                               (GtkAttachOptions) (GTK_FILL), 0, 0);\r
1512           }\r
1513 \r
1514           {\r
1515             GtkWidget* button = gtk_button_new_with_label ("90");\r
1516             gtk_widget_show (button);\r
1517             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"90");\r
1518             gtk_table_attach (GTK_TABLE (table), button, 1, 2, 0, 1,\r
1519                               (GtkAttachOptions) (GTK_FILL),\r
1520                               (GtkAttachOptions) (GTK_FILL), 0, 0);\r
1521           }\r
1522 \r
1523 \r
1524           {\r
1525             GtkWidget* button = gtk_button_new_with_label ("135");\r
1526             gtk_widget_show (button);\r
1527             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"135");\r
1528             gtk_table_attach (GTK_TABLE (table), button, 0, 1, 0, 1,\r
1529                               (GtkAttachOptions) (GTK_FILL),\r
1530                               (GtkAttachOptions) (GTK_FILL), 0, 0);\r
1531           }\r
1532 \r
1533           {\r
1534             GtkWidget* button = gtk_button_new_with_label ("180");\r
1535             gtk_widget_show (button);\r
1536             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"180");\r
1537             gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2,\r
1538                               (GtkAttachOptions) (GTK_FILL),\r
1539                               (GtkAttachOptions) (GTK_FILL), 0, 0);\r
1540           }\r
1541 \r
1542           {\r
1543             GtkWidget* button = gtk_button_new_with_label ("225");\r
1544             gtk_widget_show (button);\r
1545             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"225");\r
1546             gtk_table_attach (GTK_TABLE (table), button, 0, 1, 2, 3,\r
1547                               (GtkAttachOptions) (GTK_FILL),\r
1548                               (GtkAttachOptions) (GTK_FILL), 0, 0);\r
1549           }\r
1550 \r
1551           {\r
1552             GtkWidget* button = gtk_button_new_with_label ("270");\r
1553             gtk_widget_show (button);\r
1554             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"270");\r
1555             gtk_table_attach (GTK_TABLE (table), button, 1, 2, 2, 3,\r
1556                               (GtkAttachOptions) (GTK_FILL),\r
1557                               (GtkAttachOptions) (GTK_FILL), 0, 0);\r
1558           }\r
1559 \r
1560           {\r
1561             GtkWidget* button = gtk_button_new_with_label ("315");\r
1562             gtk_widget_show (button);\r
1563             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"315");\r
1564             gtk_table_attach (GTK_TABLE (table), button, 2, 3, 2, 3,\r
1565                               (GtkAttachOptions) (GTK_FILL),\r
1566                               (GtkAttachOptions) (GTK_FILL), 0, 0);\r
1567           }\r
1568         }\r
1569 \r
1570         {\r
1571           GtkWidget* vbox2 = gtk_vbox_new (FALSE, 0);\r
1572           gtk_widget_show (vbox2);\r
1573           gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);\r
1574 \r
1575           {\r
1576             GtkWidget* button = gtk_button_new_with_label ("Reset");\r
1577             gtk_widget_show (button);\r
1578             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (ResetEntity), NULL);\r
1579             gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);\r
1580           }\r
1581 \r
1582           {\r
1583             GtkWidget* button = gtk_button_new_with_label ("Up");\r
1584             gtk_widget_show (button);\r
1585             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"-1");\r
1586             gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);\r
1587           }\r
1588 \r
1589           {\r
1590             GtkWidget* button = gtk_button_new_with_label ("Dn");\r
1591             gtk_widget_show (button);\r
1592             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (entitylist_angle), (void *)"-2");\r
1593             gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);\r
1594           }\r
1595         }\r
1596 \r
1597         {\r
1598           GtkWidget* vbox2 = gtk_vbox_new (FALSE, 0);\r
1599           gtk_widget_show (vbox2);\r
1600           gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);\r
1601 \r
1602           {\r
1603             GtkWidget* button = gtk_button_new_with_label ("Del Key/Pair");\r
1604             gtk_widget_show (button);\r
1605             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (DelProp), NULL);\r
1606             gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);\r
1607           }\r
1608 \r
1609           {\r
1610             GtkWidget* button = gtk_button_new_with_label ("Sound...");\r
1611             gtk_widget_show (button);\r
1612             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (AssignSound), NULL);\r
1613             gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);\r
1614           }\r
1615 \r
1616           {\r
1617             GtkWidget* button = gtk_button_new_with_label ("Model...");\r
1618             gtk_widget_show (button);\r
1619             gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (AssignModel), NULL);\r
1620             gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);\r
1621           }\r
1622         }\r
1623       }\r
1624     }\r
1625 \r
1626     if (g_pParentWnd->FloatingGroupDialog())\r
1627     {\r
1628       {\r
1629         GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);\r
1630         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);\r
1631         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);\r
1632         gtk_widget_show (scr);\r
1633         gtk_container_set_border_width (GTK_CONTAINER (scr), 3);\r
1634 \r
1635         {\r
1636           GtkWidget* text = gtk_text_view_new ();\r
1637           gtk_widget_set_size_request(text, 0, -1); // allow shrinking\r
1638           gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);\r
1639           gtk_text_view_set_editable (GTK_TEXT_VIEW(text), FALSE);\r
1640           gtk_container_add (GTK_CONTAINER (scr), text);\r
1641           gtk_widget_show (text);\r
1642           g_qeglobals_gui.d_edit = text;\r
1643         }\r
1644 \r
1645         {\r
1646           GtkWidget* label = gtk_label_new ("Console");\r
1647           gtk_widget_show (label);\r
1648           gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scr, label);\r
1649         }\r
1650       }\r
1651     }\r
1652 \r
1653 \r
1654   //++timo NOTE: this part for grouping code, don't remove! (we'll put it back in sometime soon)\r
1655 \r
1656   /*\r
1657   vbox = gtk_vbox_new (FALSE, 5);\r
1658   gtk_widget_show (vbox);\r
1659   gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);\r
1660 \r
1661   scr = gtk_scrolled_window_new (NULL, NULL);\r
1662   gtk_widget_show (scr);\r
1663   gtk_box_pack_start (GTK_BOX (vbox), scr, TRUE, TRUE, 0);\r
1664   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);\r
1665 \r
1666   ctree = gtk_ctree_new (1, 0);\r
1667   gtk_widget_show (ctree);\r
1668   gtk_container_add (GTK_CONTAINER (scr), ctree);\r
1669   gtk_clist_column_titles_hide (GTK_CLIST (ctree));\r
1670   m_pTree = ctree;\r
1671 \r
1672   hbox = gtk_hbox_new (FALSE, 5);\r
1673   gtk_widget_show (hbox);\r
1674   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);\r
1675 \r
1676   button = gtk_button_new_with_label ("Add...");\r
1677   gtk_widget_show (button);\r
1678   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (groupdlg_add), NULL);\r
1679   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);\r
1680   gtk_widget_set_usize (button, 60, -2);\r
1681 \r
1682   button = gtk_button_new_with_label ("Edit...");\r
1683   gtk_widget_show (button);\r
1684   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);\r
1685   gtk_widget_set_usize (button, 60, -2);\r
1686 \r
1687   button = gtk_button_new_with_label ("Delete");\r
1688   gtk_widget_show (button);\r
1689   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);\r
1690   gtk_widget_set_usize (button, 60, -2);\r
1691 \r
1692   label = gtk_label_new ("Groups");\r
1693   gtk_widget_show (label);\r
1694   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);\r
1695   */\r
1696   inspector_mode = W_ENTITY;\r
1697   //  gtk_window_set_title (GTK_WINDOW (dlg), "Entities");\r
1698   m_pWidget = dlg;\r
1699   /*\r
1700   load_pixmap ("grouptree1.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[0], &tree_masks[0]);\r
1701   load_pixmap ("grouptree2.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[1], &tree_masks[1]);\r
1702   load_pixmap ("grouptree3.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[2], &tree_masks[2]);\r
1703   load_pixmap ("grouptree4.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[3], &tree_masks[3]);\r
1704   load_pixmap ("grouptree5.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[4], &tree_masks[4]);\r
1705   load_pixmap ("grouptree6.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[5], &tree_masks[5]);\r
1706   load_pixmap ("grouptree7.bmp", g_pParentWnd->m_pWidget, &tree_pixmaps[6], &tree_masks[6]);\r
1707 \r
1708   Group_Init();\r
1709 */\r
1710     g_signal_connect (G_OBJECT (notebook), "switch_page", G_CALLBACK (switch_page), dlg);\r
1711   }\r
1712 }\r
1713 \r