]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/mainframe.cpp
* fixed a lot of compiler warnings (mostly const char * stuff and use of uninitialize...
[xonotic/netradiant.git] / radiant / mainframe.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 //
23 // Main Window for Q3Radiant
24 //
25 // Leonardo Zide (leo@lokigames.com)
26 //
27
28 #include "stdafx.h"
29 #ifdef _WIN32
30 extern "C" {
31 #include <gdk/gdkwin32.h>
32 #define COMPILE_MULTIMON_STUBS
33 #include <multimon.h>
34 }
35 #endif
36 #include <gtk/gtk.h>
37 #include <glib/gi18n.h>
38 #include <gdk/gdkkeysyms.h>
39 #include <gdk/gdkprivate.h>
40 #include <sys/stat.h>
41 #if defined (__linux__) || defined (__APPLE__)
42   #include <unistd.h>
43 #endif
44 #include "gtkmisc.h"
45 #include "groupdialog.h"
46 #include "patchdialog.h"
47 #include "filters.h"
48
49 // use this to verbose what happens with the beyboard
50 #ifdef _DEBUG
51 //  #define DBG_KBD
52 #endif
53
54 // globals
55 CString g_strAppPath;                   ///< holds the full path of the executable
56 CString g_strDTDPath;                   ///< path to the DTD files
57 /*!
58 see http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=297 for the two below
59 */
60 CString g_pidFile;                      ///< the global .pid file (only for global part of the startup)
61 CString g_pidGameFile;                  ///< the game-specific .pid file
62 CString g_strBitmapsPath;               // directory where the bitmaps are stored
63
64 /*!
65 points to the game tools directory, for instance
66 C:\Program Files\Quake III Arena\GtkRadiant
67 (or other games)
68 this is one of the main variables that are configured by the game selection on startup
69 <g_strGameToolsPath>/plugins
70 <g_strGameToolsPath>/modules
71 and also q3map, bspc
72 */
73 CString g_strGameToolsPath;             ///< this is set by g_PrefsDlg.mGamesDialog
74 CGameDescription *g_pGameDescription;   ///< shortcut to g_PrefsDlg.mGamesDialog.m_pCurrentDescription
75 CString g_strPluginsDir;                ///< name of plugins directory, always sub-directory of toolspath
76 CString g_strModulesDir;                ///< name of modules directory, always sub-directory of toolspath
77
78 /*!
79 directory for temp files
80 NOTE: on *nix this is were we check for .pid
81 */
82 CString g_strTempPath;
83 MainFrame* g_pParentWnd = NULL;         // used to precast to CMainFrame
84 PrefsDlg g_Preferences;                 // global prefs instance
85 PrefsDlg& g_PrefsDlg = g_Preferences;   // reference used throughout
86 int g_nUpdateBits = 0;                  // window update flags
87 bool g_bScreenUpdates = true;           // whether window painting is active, used in a few places
88                                         // to disable updates for speed reasons
89                                         // both of the above should be made members of CMainFrame
90 int g_bIgnoreCommands;                  // Used to ignore commands when checking menus/toolbars
91 GSList *g_BSPFrontendCommands;          // List of commands in the BSP menu
92
93 const int CMD_TEXTUREWAD_END = CMD_TEXTUREWAD + MAX_TEXTUREDIRS - 1;
94 const int CMD_BSPCOMMAND_END = CMD_BSPCOMMAND + 127;
95
96 extern bool g_bCrossHairs;
97 extern int g_argc;
98 extern char** g_argv;
99 extern PatchDialog g_PatchDialog;
100
101 GtkAccelGroup* global_accel;
102
103 void Select_Ungroup ();
104
105 // command mapping stuff
106 //
107 // m_strCommand is the command string
108 // m_nKey is the GDK_??? equivelant
109 // m_nModifiers are key states as follows
110 //  bit
111 //    1 - shift
112 //    2 - alt
113 //    4 - control
114 //    8 - press only
115 //
116 #define SPEED_MOVE      32
117 #define SPEED_TURN      22.5
118
119 // NOTE: the menu item field is REQUIRED, Gtk uses it to bind the keyboard shortcut
120 // - if you add a command here and you don't want a menu item, use the "hidden" menu
121 // - if you decide to add a menu item, check if it's not in the "hidden" menu already
122 SCommandInfo g_Commands[] =
123 {
124   {"CycleOutlineStyle", 'J', 0x00, ID_SELECTION_OUTLINESTYLE, "menu_selection_outlinestyle"},
125   {"CSGMerge", 'U', 0x04, ID_SELECTION_CSGMERGE, "menu_selection_csgmerge"},
126   {"CSGSubtract", 'U', 0x01, ID_SELECTION_CSGSUBTRACT, "menu_selection_csgsubstract"},
127   //  {"ViewGroups", 'G', 0x00, ID_VIEW_GROUPS, "menu_view_groups"}, (temporary disabled)
128   {"HideSelected", 'H', 0x00, ID_VIEW_HIDESHOW_HIDESELECTED, "menu_view_hideshow_hideselected"},
129   {"ShowHidden", 'H', 0x01, ID_VIEW_HIDESHOW_SHOWHIDDEN, "menu_view_hideshow_showhidden"},
130   {"BendMode", 'B', 0x00, ID_PATCH_BEND, "menu_patch_bend"},
131   {"FitTexture", 'B', 0x01, IDC_BTN_FACEFIT, "menu_idc_btn_facefit"},
132   {"ViewTextures", 'T', 0, ID_VIEW_TEXTURE, "menu_view_texture"},
133   {"ThickenPatch", 'T', 0x04, ID_CURVE_THICKEN, "menu_curve_thicken"},
134   {"MakeOverlayPatch", 'Y', 0, ID_CURVE_OVERLAY_SET, "menu_curve_overlay_set"},
135   {"ClearPatchOverlays", 'L', 0x04, ID_CURVE_OVERLAY_CLEAR, "menu_curve_overlay_clear"},
136   {"SurfaceInspector", 'S', 0, ID_TEXTURES_INSPECTOR, "menu_textures_inspector"},
137   {"PatchInspector", 'S', 0x01, ID_PATCH_INSPECTOR, "menu_patch_inspector"},
138   {"RedisperseRows", 'E', 0x04, ID_CURVE_REDISPERSE_ROWS, "menu_curve_redisperse_rows"},
139   {"RedisperseIntermediateCols", 'E', 0x05, ID_CURVE_REDISPERSE_INTERMEDIATE_COLS, "menu_curve_redisperse_cols"},
140   {"InvertCurveTextureX", 'I', 0x05, ID_CURVE_NEGATIVETEXTUREY, "menu_curve_negativetexturey"},
141   {"InvertCurveTextureY", 'I', 0x01, ID_CURVE_NEGATIVETEXTUREX, "menu_curve_negativetexturex"},
142   {"InvertCurve", 'I', 0x04, ID_CURVE_NEGATIVE, "menu_curve_negative"},
143   {"IncPatchColumn", GDK_KP_Add, 0x05, ID_CURVE_INSERTCOLUMN, "menu_curve_insertcolumn"},
144   {"IncPatchRow", GDK_KP_Add, 0x04, ID_CURVE_INSERTROW, "menu_curve_insertrow"},
145   {"DecPatchColumn", GDK_KP_Subtract, 0x05, ID_CURVE_DELETECOLUMN, "menu_curve_deletecolumn"},
146   {"DecPatchRow", GDK_KP_Subtract, 0x04, ID_CURVE_DELETEROW, "menu_curve_deleterow"},
147   {"Patch TAB", GDK_Tab, 0x00, ID_PATCH_TAB, "menu_patch_tab"},
148   {"Patch TAB", GDK_Tab, 0x01, ID_PATCH_TAB, "menu_patch_tab"},
149   {"SelectNudgeDown", GDK_Down, 0x02, ID_SELECTION_SELECT_NUDGEDOWN, "menu_selection_select_nudgedown"},
150   {"EntityColor",'K', 0, ID_MISC_SELECTENTITYCOLOR, "menu_misc_select_entitycolor"},
151   {"CameraForward", GDK_Up, 0, ID_CAMERA_FORWARD, "menu_camera_forward"},
152   {"CameraBack", GDK_Down, 0, ID_CAMERA_BACK, "menu_camera_back"},
153   {"CameraLeft", GDK_Left, 0, ID_CAMERA_LEFT, "menu_camera_left"},
154   {"CameraRight", GDK_Right, 0, ID_CAMERA_RIGHT, "menu_camera_right"},
155   {"CameraUp", 'D', 0, ID_CAMERA_UP, "menu_camera_up"},
156   {"CameraDown", 'C', 0, ID_CAMERA_DOWN, "menu_camera_down"},
157   {"CameraAngleUp", 'A', 0, ID_CAMERA_ANGLEUP, "menu_camera_angleup"},
158   {"CameraAngleDown", 'Z', 0, ID_CAMERA_ANGLEDOWN, "menu_camera_angledown"},
159   {"CameraStrafeRight", GDK_period, 0, ID_CAMERA_STRAFERIGHT, "menu_camera_straferight"},
160   {"CameraStrafeLeft", GDK_comma, 0, ID_CAMERA_STRAFELEFT, "menu_camera_strafeleft"},
161   {"ToggleGrid", '0', 0, ID_GRID_TOGGLE, "menu_grid_toggle"},
162   {"SetGrid1", '1', 0, ID_GRID_1, "menu_grid_1"},
163   {"SetGrid2", '2', 0, ID_GRID_2, "menu_grid_2"},
164   {"SetGrid4", '3', 0, ID_GRID_4, "menu_grid_4"},
165   {"SetGrid8", '4', 0, ID_GRID_8, "menu_grid_8"},
166   {"SetGrid16", '5', 0, ID_GRID_16, "menu_grid_16"},
167   {"SetGrid32", '6', 0, ID_GRID_32, "menu_grid_32"},
168   {"SetGrid64", '7', 0, ID_GRID_64, "menu_grid_64"},
169   {"SetGrid128", '8', 0, ID_GRID_128, "menu_grid_128"},
170   {"SetGrid256", '9', 0, ID_GRID_256, "menu_grid_256"},
171   {"DragEdges", 'E', 0, ID_SELECTION_DRAGEDGES, "menu_selection_dragedges"},
172   {"DragVertices", 'V', 0, ID_SELECTION_DRAGVERTECIES, "menu_selection_dragvertecies"},
173   {"ViewEntityInfo", 'N', 0, ID_VIEW_ENTITY, "menu_view_entity"},
174   //  {"ViewConsole", 'O', 0, ID_VIEW_CONSOLE, "menu_0,"},
175   {"CloneSelection", GDK_space, 0, ID_SELECTION_CLONE, "menu_selection_clone"},
176   {"DeleteSelection", GDK_BackSpace, 0, ID_SELECTION_DELETE, "menu_selection_delete"},
177   {"UnSelectSelection", GDK_Escape, 0, ID_SELECTION_DESELECT, "menu_selection_deselect"},
178   {"CenterView", GDK_End, 0, ID_VIEW_CENTER, "menu_view_center"},
179   {"ZoomOut", GDK_Insert, 0, ID_VIEW_ZOOMOUT, "menu_view_zoomout"},
180   {"ZoomIn", GDK_Delete, 0, ID_VIEW_ZOOMIN, "menu_view_zoomin"},
181   {"UpFloor", GDK_Prior, 0, ID_VIEW_UPFLOOR, "menu_view_upfloor"},
182   {"DownFloor", GDK_Next, 0, ID_VIEW_DOWNFLOOR, "menu_view_downfloor"},
183   {"ToggleClipper", 'X', 0, ID_VIEW_CLIPPER, "menu_view_clipper"},
184   {"ToggleCrosshairs", 'X', 0x01, ID_VIEW_CROSSHAIR, "menu_view_crosshair"},
185   {"TogTexLock", 'T', 0x01, ID_TOGGLE_LOCK, "menu_toggle_lock"},
186   {"TogTexRotLock", 'R', 0x01, ID_TOGGLE_ROTATELOCK, "menu_toggle_rotatelock"},
187   {"ToggleRealtime", 'R', 0x04, ID_VIEW_CAMERAUPDATE, "menu_view_cameraupdate"},
188   {"EntityList", 'L', 0, ID_EDIT_ENTITYINFO, "menu_edit_entityinfo"},
189   {"Preferences", 'P', 0, ID_PREFS, "menu_prefs"},
190   {"ToggleCamera", 'C', 0x05, ID_TOGGLECAMERA, "menu_togglecamera"},
191   {"ToggleConsole", 'O', 0, ID_TOGGLECONSOLE, "menu_toggleconsole"},
192   {"ToggleView", 'V', 0x05, ID_TOGGLEVIEW, "menu_toggleview"},
193   {"ToggleZ", 'Z', 0x05, ID_TOGGLEZ, "menu_togglez"},
194   {"ConnectSelection", 'K', 0x04, ID_SELECTION_CONNECT, "menu_selection_connect"},
195   {"Brush3Sided", '3', 0x04, ID_BRUSH_3SIDED, "menu_brush_3sided"},
196   {"Brush4Sided", '4', 0x04, ID_BRUSH_4SIDED, "menu_brush_4sided"},
197   {"Brush5Sided", '5', 0x04, ID_BRUSH_5SIDED, "menu_brush_5sided"},
198   {"Brush6Sided", '6', 0x04, ID_BRUSH_6SIDED, "menu_brush_6sided"},
199   {"Brush7Sided", '7', 0x04, ID_BRUSH_7SIDED, "menu_brush_7sided"},
200   {"Brush8Sided", '8', 0x04, ID_BRUSH_8SIDED, "menu_brush_8sided"},
201   {"Brush9Sided", '9', 0x04, ID_BRUSH_9SIDED, "menu_brush_9sided"},
202   {"MatrixTranspose", 'M', 0x05, ID_CURVE_MATRIX_TRANSPOSE, "menu_curve_matrix_transpose"},
203   {"MakeDetail", 'M', 0x04, ID_SELECTION_MAKE_DETAIL, "menu_selection_make_detail"},
204   {"MapInfo", 'M', 0, ID_EDIT_MAPINFO, "menu_edit_mapinfo"},
205   {"NextLeakSpot", 'K', 0x05, ID_MISC_NEXTLEAKSPOT, "menu_misc_nextleakspot"},
206   {"PrevLeakSpot", 'L', 0x05, ID_MISC_PREVIOUSLEAKSPOT, "menu_misc_previousleakspot"},
207   {"FileOpen", 'O', 0x04, ID_FILE_OPEN, "menu_file_open"},
208   {"FileSave", 'S', 0x04, ID_FILE_SAVE, "menu_file_save"},
209   //% {"Exit", 'X', 0x04, ID_FILE_EXIT, "menu_file_exit"}, // ydnar: Ctrl+X should be cut
210   {"CenterXYView", GDK_Tab, 0x05, ID_VIEW_CENTERVIEW, "menu_view_centerview"},
211   {"NextView", GDK_Tab, 0x04, ID_VIEW_NEXTVIEW, "menu_view_nextview"},
212   {"ClipSelected", GDK_Return, 0x00, ID_CLIP_SELECTED, "menu_clip_selected"},
213   {"SplitSelected", GDK_Return, 0x01, ID_SPLIT_SELECTED, "menu_split_selected"},
214   {"FlipClip", GDK_Return, 0x04, ID_FLIP_CLIP, "menu_flip_clip"},
215   {"MouseRotate", 'R', 0x00, ID_SELECT_MOUSEROTATE, "menu_select_mouserotate"},
216   {"Copy", 'C', 0x04, ID_EDIT_COPYBRUSH, "menu_edit_copybrush"},
217   {"Paste", 'V', 0x04, ID_EDIT_PASTEBRUSH, "menu_edit_pastebrush"},
218   {"PasteToCamera", 'V', RAD_ALT, ID_EDIT_PASTEBRUSHTOCAMERA, "menu_edit_pastebrushtocamera"},
219   {"Undo", 'Z', 0x04, ID_EDIT_UNDO, "menu_edit_undo"},
220   {"Redo", 'Y', 0x04, ID_EDIT_REDO, "menu_edit_redo"},
221   {"ZZoomOut", GDK_Insert, 0x04, ID_VIEW_ZZOOMOUT, "menu_view_zzoomout"},
222   {"ZZoomIn", GDK_Delete, 0x04, ID_VIEW_ZZOOMIN, "menu_view_zzoomin"},
223   {"TexRotateClock", GDK_Next, 0x01, ID_SELECTION_TEXTURE_ROTATECLOCK, "menu_selection_texture_rotateclock"},
224   {"TexRotateCounter", GDK_Prior, 0x01, ID_SELECTION_TEXTURE_ROTATECOUNTER, "menu_selection_texture_rotatecounter"},
225   {"TexScaleUp", GDK_Up, 0x04, ID_SELECTION_TEXTURE_SCALEUP, "menu_selection_texture_scaleup"},
226   {"TexScaleDown", GDK_Down, 0x04, ID_SELECTION_TEXTURE_SCALEDOWN, "menu_selection_texture_scaledown"},
227   {"TexShiftLeft", GDK_Left, 0x01, ID_SELECTION_TEXTURE_SHIFTLEFT, "menu_selection_texture_shiftleft"},
228   {"TexShiftRight", GDK_Right, 0x01, ID_SELECTION_TEXTURE_SHIFTRIGHT, "menu_selection_texture_shiftright"},
229   {"TexShiftUp", GDK_Up, 0x01, ID_SELECTION_TEXTURE_SHIFTUP, "menu_selection_texture_shiftup"},
230   {"TexShiftDown", GDK_Down, 0x01, ID_SELECTION_TEXTURE_SHIFTDOWN, "menu_selection_texture_shiftdown"},
231   {"GridDown", '[', 0x00, ID_GRID_PREV, "menu_grid_prev"},
232   {"GridUp", ']', 0x00, ID_GRID_NEXT, "menu_grid_next"},
233   {"TexScaleLeft", GDK_Left, 0x04, ID_SELECTION_TEXTURE_SCALELEFT, "menu_selection_texture_scaleleft"},
234   {"TexScaleRight", GDK_Right, 0x04, ID_SELECTION_TEXTURE_SCALERIGHT, "menu_selection_texture_scaleright"},
235   {"CubicClipZoomOut", ']', 0x04, ID_VIEW_CUBEOUT, "menu_view_cubeout"},
236   {"CubicClipZoomIn", '[', 0x04, ID_VIEW_CUBEIN, "menu_view_cubein"},
237   {"ToggleCubicClip", '\\', 0x04, ID_VIEW_CUBICCLIPPING, "menu_view_cubicclipping"},
238   {"MoveSelectionDOWN", GDK_KP_Subtract, 0x00, ID_SELECTION_MOVEDOWN, "menu_selection_movedown"},
239   {"MoveSelectionUP", GDK_KP_Add, 0x00, ID_SELECTION_MOVEUP, "menu_selection_moveup"},
240   {"DumpSelectedBrush", 'D', 0x01, ID_SELECTION_PRINT, "menu_selection_print"},
241   {"ToggleSizePaint", 'Q', 0x00, ID_SELECTION_TOGGLESIZEPAINT, "menu_selection_togglesizepaint"},
242   {"SelectNudgeLeft", GDK_Left, 0x02, ID_SELECTION_SELECT_NUDGELEFT, "menu_selection_select_nudgeleft"},
243   {"SelectNudgeRight", GDK_Right, 0x02, ID_SELECTION_SELECT_NUDGERIGHT, "menu_selection_select_nudgeright"},
244   {"SelectNudgeUp", GDK_Up, 0x02, ID_SELECTION_SELECT_NUDGEUP, "menu_selection_select_nudgeup"},
245   {"CycleCapTexturePatch", 'N', 0x05, ID_CURVE_CYCLECAP, "menu_curve_cyclecap"},
246   {"NaturalizePatch", 'N', 0x04, ID_PATCH_NATURALIZE, "menu_patch_naturalize"},
247   {"SnapToGrid", 'G', 0x04, ID_SELECT_SNAPTOGRID, "menu_select_snaptogrid"},
248   {"ShowAllTextures", 'A', 0x04, ID_TEXTURES_SHOWALL, "menu_textures_showall"},
249   {"SelectAllOfType", 'A', 0x01, ID_SELECT_ALL, "menu_select_all"},
250   {"CapCurrentCurve", 'C', 0x01, ID_CURVE_CAP, "menu_curve_cap"},
251   {"MakeStructural", 'S', 0x05, ID_SELECTION_MAKE_STRUCTURAL, "menu_selection_make_structural"},
252   {"RegionSetSelection", 'R', 0x05, ID_REGION_SETSELECTION, "menu_region_setselection"},
253   {"ShowInUse", 'U', 0, ID_TEXTURES_SHOWINUSE, "menu_textures_showinuse"},
254   {"InvertSelection", 'I', 0, ID_SELECTION_INVERT, "menu_selection_invert"},
255   {"Sleep", 'P', 0x05, ID_FILE_SLEEP, "menu_file_sleep"},
256   {"SimplePatchMesh", 'P', 0x01, ID_CURVE_SIMPLEPATCHMESH, "menu_simplepatchmesh"},
257   {"FilterWorldBrushes", '1', RAD_ALT, ID_FILTER_WORLD, "menu_filter_world"},
258   {"FilterEntities", '2', RAD_ALT, ID_FILTER_ENTITIES, "menu_filter_entities"},
259   {"FilterAreaportals", '3', RAD_ALT, ID_FILTER_AREAPORTALS, "menu_filter_areaportals"},
260   {"FilterTranslucent", '4', RAD_ALT, ID_FILTER_TRANSLUCENT, "menu_filter_translucent"},
261   {"FilterLiquids", '5', RAD_ALT, ID_FILTER_LIQUIDS, "menu_filter_liquids"},
262   {"FilterCaulk", '6', RAD_ALT , ID_FILTER_CAULK, "menu_filter_caulk"},
263   {"FilterClips", '7', RAD_ALT, ID_FILTER_CLIPS, "menu_filter_clips"},
264   {"FilterBotClips", 'M', RAD_ALT, ID_FILTER_BOTCLIPS, "menu_filter_botclips"},
265   {"FilterPaths", '8', RAD_ALT, ID_FILTER_PATHS, "menu_filter_paths"},
266   {"FilterClusterportals", '9', RAD_ALT, ID_FILTER_CLUSTERPORTALS, "menu_filter_clusterportals"},
267   {"FilterLights", '0', RAD_ALT, ID_FILTER_LIGHTS, "menu_filter_lights"},
268   {"FilterPatches", 'P', RAD_CONTROL, ID_FILTER_PATCHES, "menu_filter_patches"},
269   {"FilterDetails", 'D', RAD_CONTROL, ID_FILTER_DETAILS, "menu_filter_details"},
270   {"FilterStructural", 'D', RAD_CONTROL|RAD_SHIFT, ID_FILTER_STRUCTURAL, "menu_filter_structural"},
271   {"FilterHintsSkips", 'H', RAD_CONTROL, ID_FILTER_HINTSSKIPS, "menu_filter_hintsskips"},
272   {"FilterModels", 'M', RAD_SHIFT, ID_FILTER_MODELS, "menu_filter_models"},
273   {"FilterTriggers", 'T', RAD_CONTROL|RAD_SHIFT, ID_FILTER_TRIGGERS, "menu_filter_triggers"},
274   {"LoadPointfile", 'L', RAD_SHIFT, ID_FILE_POINTFILE, "menu_load_pointfile"},
275   {"TextureWindowScaledown", GDK_Insert, RAD_ALT, ID_TEXTUREWINDOW_SCALEDOWN, "menu_texturewindow_scaledown"},
276   {"TextureWindowScaleup", GDK_Delete, RAD_ALT, ID_TEXTUREWINDOW_SCALEUP, "menu_texturewindow_scaleup"},
277 };
278
279 int g_nCommandCount = sizeof(g_Commands) / sizeof(SCommandInfo);
280
281 SKeyInfo g_Keys[] =
282 {
283   {"Space", GDK_space},
284   {"Backspace", GDK_BackSpace},
285   {"Escape", GDK_Escape},
286   {"End", GDK_End},
287   {"Insert", GDK_Insert},
288   {"Delete", GDK_Delete},
289   {"PageUp", GDK_Prior},
290   {"PageDown", GDK_Next},
291   {"Up", GDK_Up},
292   {"Down", GDK_Down},
293   {"Left", GDK_Left},
294   {"Right", GDK_Right},
295   {"F1", GDK_F1},
296   {"F2", GDK_F2},
297   {"F3", GDK_F3},
298   {"F4", GDK_F4},
299   {"F5", GDK_F5},
300   {"F6", GDK_F6},
301   {"F7", GDK_F7},
302   {"F8", GDK_F8},
303   {"F9", GDK_F9},
304   {"F10", GDK_F10},
305   {"F11", GDK_F11},
306   {"F12", GDK_F12},
307   {"Tab", GDK_Tab},
308   {"Return", GDK_Return},
309   {"Comma", GDK_comma},
310   {"Period", GDK_period},
311   {"Plus", GDK_KP_Add},
312   {"Multiply", GDK_multiply},
313   {"Subtract", GDK_KP_Subtract},
314   {"NumPad0", GDK_KP_0},
315   {"NumPad1", GDK_KP_1},
316   {"NumPad2", GDK_KP_2},
317   {"NumPad3", GDK_KP_3},
318   {"NumPad4", GDK_KP_4},
319   {"NumPad5", GDK_KP_5},
320   {"NumPad6", GDK_KP_6},
321   {"NumPad7", GDK_KP_7},
322   {"NumPad8", GDK_KP_8},
323   {"NumPad9", GDK_KP_9},
324   {"[", 219},
325   {"]", 221},
326   {"\\", 220},
327   {"Home", GDK_Home}
328 };
329
330 int g_nKeyCount = sizeof(g_Keys) / sizeof(SKeyInfo);
331
332 // =============================================================================
333 // global functions
334
335 void WINAPI Sys_UpdateWindows (int nBits)
336 {
337   g_nUpdateBits |= nBits;
338 }
339
340 // =============================================================================
341 // Static functions
342
343 // Gef: Separate handling for keyup events
344 void HandleKeyUp (GtkWidget *widget, gpointer data)
345 {
346   int id = GPOINTER_TO_INT (data);
347 #ifdef DBG_KBD
348   Sys_Printf("HandleKeyUp: %d\n", id);
349 #endif
350
351   if(g_bIgnoreCommands)
352     return;
353
354   switch (id)
355   {
356     case ID_CAMERA_FORWARD: g_pParentWnd->OnCameraForward (FALSE); break;
357     case ID_CAMERA_BACK: g_pParentWnd->OnCameraBack (FALSE); break;
358     case ID_CAMERA_LEFT: g_pParentWnd->OnCameraLeft (FALSE); break;
359     case ID_CAMERA_RIGHT: g_pParentWnd->OnCameraRight (FALSE); break;
360     case ID_CAMERA_STRAFELEFT: g_pParentWnd->OnCameraStrafeleft (FALSE); break;
361     case ID_CAMERA_STRAFERIGHT: g_pParentWnd->OnCameraStraferight (FALSE); break;
362   }
363 }
364
365 gint HandleCommand (GtkWidget *widget, gpointer data)
366 {
367   int id = GPOINTER_TO_INT (data);
368 #ifdef DBG_KBD
369   Sys_Printf("HandleCommand %d\n", id);
370 #endif
371
372   if ( g_bIgnoreCommands ) {
373 #ifdef DBG_KBD
374     Sys_Printf( "g_bIgnoreCommands %d, returning FALSE\n", g_bIgnoreCommands );
375 #endif
376     return FALSE;
377   }
378
379   if (id >= CMD_TEXTUREWAD && id <= CMD_TEXTUREWAD_END) g_pParentWnd->OnTextureWad (id);
380   else if (id >= CMD_BSPCOMMAND && id <= CMD_BSPCOMMAND_END) g_pParentWnd->OnBspCommand (id);
381   else if (id >= ID_FILE_RECENT1 && id <= ID_FILE_RECENT4) g_pParentWnd->OnMru (id);
382   else if (id >= ID_VIEW_NEAREST && id <= ID_TEXTURES_FLATSHADE)
383   {
384     if (GTK_CHECK_MENU_ITEM (widget)->active)
385       g_pParentWnd->OnViewNearest (id);
386   } else if (id >= ID_GRID_025 && id <= ID_GRID_256) g_pParentWnd->OnGrid (id);
387   else if (id >= ID_PLUGIN_START && id <= ID_PLUGIN_END)
388   {
389     char *str;
390     gtk_label_get (GTK_LABEL (GTK_BIN (widget)->child), &str);
391     g_pParentWnd->OnPlugIn (id, str);
392   } else if (id >= ID_ENTITY_START && id <= ID_ENTITY_END)
393   {
394     char *str;
395     gtk_label_get (GTK_LABEL (GTK_BIN (widget)->child), &str);
396     g_pParentWnd->ActiveXY()->OnEntityCreate (str);
397   }
398   else switch (id)
399     {
400     case ID_FILE_NEW: g_pParentWnd->OnFileNew (); break;
401     case ID_FILE_SLEEP: g_pParentWnd->OnSleep(); break;
402     case ID_FILE_OPEN: g_pParentWnd->OnFileOpen (); break;
403     case ID_FILE_SAVE: g_pParentWnd->OnFileSave (); break;
404     case ID_FILE_SAVEAS: g_pParentWnd->OnFileSaveas (); break;
405     case ID_FILE_EXPORTMAP: g_pParentWnd->OnFileExportmap (); break;
406     case ID_FILE_SAVEREGION: g_pParentWnd->OnFileSaveregion (); break;
407     case ID_FILE_NEWPROJECT: g_pParentWnd->OnFileNewproject (); break;
408     case ID_FILE_LOADPROJECT: g_pParentWnd->OnFileLoadproject (); break;
409     case ID_FILE_PROJECTSETTINGS: g_pParentWnd->OnFileProjectsettings (); break;
410     case ID_FILE_POINTFILE: g_pParentWnd->OnFilePointfile (); break;
411     case ID_FILE_CHECKUPDATE: g_pParentWnd->OnFileCheckUpdate (); break;
412     case ID_FILE_EXIT: g_pParentWnd->OnFileExit (); break;
413     case ID_FILE_IMPORTMAP: g_pParentWnd->OnFileImportmap (); break;
414     case ID_EDIT_UNDO: g_pParentWnd->OnEditUndo (); break;
415     case ID_EDIT_REDO: g_pParentWnd->OnEditRedo (); break;
416     case ID_EDIT_COPYBRUSH: g_pParentWnd->OnEditCopybrush (); break;
417     case ID_EDIT_PASTEBRUSH: g_pParentWnd->OnEditPastebrush (); break;
418     case ID_EDIT_PASTEBRUSHTOCAMERA: g_pParentWnd->OnEditPastebrushToCamera (); break;
419     case ID_SELECTION_DELETE: g_pParentWnd->OnSelectionDelete (); break;
420     case ID_EDIT_MAPINFO: g_pParentWnd->OnEditMapinfo (); break;
421     case ID_EDIT_ENTITYINFO: g_pParentWnd->OnEditEntityinfo (); break;
422     case ID_BRUSH_SCRIPTS: g_pParentWnd->OnBrushScripts (); break;
423     case ID_EDIT_LOADPREFAB: g_pParentWnd->OnEditLoadprefab (); break;
424     case ID_EDIT_SAVEPREFAB: g_pParentWnd->OnEditSaveprefab (); break;
425     case ID_PREFS: g_pParentWnd->OnPrefs (); break;
426     case ID_TOGGLECAMERA: g_pParentWnd->OnTogglecamera (); break;
427     case ID_TOGGLECONSOLE: g_pParentWnd->OnToggleconsole (); break;
428     case ID_VIEW_ENTITY: g_pParentWnd->OnViewEntity (); break;
429     case ID_VIEW_GROUPS: g_pParentWnd->OnViewGroups (); break;
430     case ID_TOGGLEVIEW: g_pParentWnd->OnToggleview (); break;
431     case ID_TOGGLEVIEW_YZ: g_pParentWnd->OnToggleviewYz (); break;
432     case ID_TOGGLEVIEW_XZ: g_pParentWnd->OnToggleviewXz (); break;
433     case ID_TOGGLEZ: g_pParentWnd->OnTogglez (); break;
434     case ID_VIEW_CENTER: g_pParentWnd->OnViewCenter (); break;
435     case ID_VIEW_UPFLOOR: g_pParentWnd->OnViewUpfloor (); break;
436     case ID_VIEW_DOWNFLOOR: g_pParentWnd->OnViewDownfloor (); break;
437     case ID_VIEW_CENTERVIEW: g_pParentWnd->OnViewCenterview (); break;
438     case ID_VIEW_NEXTVIEW: g_pParentWnd->OnViewNextview (); break;
439     case ID_VIEW_XY: g_pParentWnd->OnViewXy (); break;
440     case ID_VIEW_SIDE: g_pParentWnd->OnViewSide (); break;
441     case ID_VIEW_FRONT: g_pParentWnd->OnViewFront (); break;
442     case ID_VIEW_100: g_pParentWnd->OnView100 (); break;
443     case ID_VIEW_ZOOMIN: g_pParentWnd->OnViewZoomin (); break;
444     case ID_VIEW_ZOOMOUT: g_pParentWnd->OnViewZoomout (); break;
445     case ID_VIEW_Z100: g_pParentWnd->OnViewZ100 (); break;
446     case ID_VIEW_ZZOOMIN: g_pParentWnd->OnViewZzoomin (); break;
447     case ID_VIEW_ZZOOMOUT: g_pParentWnd->OnViewZzoomout (); break;
448     case ID_VIEW_CUBEIN: g_pParentWnd->OnViewCubein (); break;
449     case ID_VIEW_CUBEOUT: g_pParentWnd->OnViewCubeout (); break;
450     case ID_VIEW_SHOWNAMES: g_pParentWnd->OnViewShownames (); break;
451     case ID_VIEW_SHOWBLOCKS: g_pParentWnd->OnViewShowblocks (); break;
452     case ID_VIEW_SHOWCOORDINATES: g_pParentWnd->OnViewShowcoordinates (); break;
453     case ID_VIEW_SHOWOUTLINE: g_pParentWnd->OnViewShowOutline (); break;
454     case ID_VIEW_SHOWAXES: g_pParentWnd->OnViewShowAxes (); break;
455     case ID_VIEW_SHOWWORKZONE: g_pParentWnd->OnViewShowWorkzone (); break;
456     case ID_VIEW_SHOWANGLES: g_pParentWnd->OnViewShowAngles (); break;
457     case ID_VIEW_HIDESHOW_HIDESELECTED: g_pParentWnd->OnViewHideshowHideselected (); break;
458     case ID_VIEW_HIDESHOW_SHOWHIDDEN: g_pParentWnd->OnViewHideshowShowhidden (); break;
459     case ID_VIEW_ENTITIESAS_BOUNDINGBOX:
460     case ID_VIEW_ENTITIESAS_WIREFRAME:
461     case ID_VIEW_ENTITIESAS_SELECTEDWIREFRAME:
462     case ID_VIEW_ENTITIESAS_SELECTEDSKINNED:
463     case ID_VIEW_ENTITIESAS_SKINNED:
464     case ID_VIEW_ENTITIESAS_SKINNEDANDBOXED:
465       g_pParentWnd->OnEntitiesSetViewAs(id);
466       break;
467     case ID_VIEW_CUBICCLIPPING: g_pParentWnd->OnViewCubicclipping (); break;
468     case ID_VIEW_OPENGLLIGHTING: g_pParentWnd->OnViewOpengllighting (); break;
469     case ID_SELECTION_DRAGEDGES: g_pParentWnd->OnSelectionDragedges (); break;
470     case ID_SELECTION_DRAGVERTECIES: g_pParentWnd->OnSelectionDragvertecies (); break;
471     case ID_SELECTION_CLONE: g_pParentWnd->OnSelectionClone (); break;
472     case ID_SELECTION_DESELECT: g_pParentWnd->OnSelectionDeselect (); break;
473     case ID_BRUSH_FLIPX: g_pParentWnd->OnBrushFlipx (); break;
474     case ID_BRUSH_FLIPY: g_pParentWnd->OnBrushFlipy (); break;
475     case ID_BRUSH_FLIPZ: g_pParentWnd->OnBrushFlipz (); break;
476     case ID_BRUSH_ROTATEX: g_pParentWnd->OnBrushRotatex (); break;
477     case ID_BRUSH_ROTATEY: g_pParentWnd->OnBrushRotatey (); break;
478     case ID_BRUSH_ROTATEZ: g_pParentWnd->OnBrushRotatez (); break;
479     case ID_SELECTION_ARBITRARYROTATION: g_pParentWnd->OnSelectionArbitraryrotation (); break;
480     case ID_SELECT_SCALE: g_pParentWnd->OnSelectScale (); break;
481     case ID_SELECTION_MAKEHOLLOW: g_pParentWnd->OnSelectionMakehollow (); break;
482     case ID_SELECTION_CSGSUBTRACT: g_pParentWnd->OnSelectionCsgsubtract (); break;
483     case ID_SELECTION_CSGMERGE: g_pParentWnd->OnSelectionCsgmerge (); break;
484     case ID_SELECTION_NOOUTLINE: g_pParentWnd->OnSelectionNoOutline (); break;
485     case ID_SELECTION_OUTLINESTYLE: g_pParentWnd->OnSelectionOutlineStyle (); break;
486     case ID_SELECTION_SELECTCOMPLETETALL: g_pParentWnd->OnSelectionSelectcompletetall (); break;
487     case ID_SELECTION_SELECTTOUCHING: g_pParentWnd->OnSelectionSelecttouching (); break;
488     case ID_SELECTION_SELECTPARTIALTALL: g_pParentWnd->OnSelectionSelectpartialtall (); break;
489     case ID_SELECTION_SELECTINSIDE: g_pParentWnd->OnSelectionSelectinside (); break;
490     case ID_SELECTION_SELECT_NUDGELEFT: g_pParentWnd->OnSelectionSelectNudgeleft (); break;
491     case ID_SELECTION_SELECT_NUDGERIGHT: g_pParentWnd->OnSelectionSelectNudgeright (); break;
492     case ID_SELECTION_SELECT_NUDGEUP: g_pParentWnd->OnSelectionSelectNudgeup (); break;
493     case ID_SELECTION_SELECT_NUDGEDOWN: g_pParentWnd->OnSelectionSelectNudgedown (); break;
494     case ID_VIEW_CLIPPER: g_pParentWnd->OnViewClipper (); break;
495     case ID_CLIP_SELECTED: g_pParentWnd->OnClipSelected (); break;
496     case ID_SPLIT_SELECTED: g_pParentWnd->OnSplitSelected (); break;
497     case ID_FLIP_CLIP: g_pParentWnd->OnFlipClip (); break;
498     case ID_SELECTION_CONNECT: g_pParentWnd->OnSelectionConnect (); break;
499     case ID_SELECTION_UNGROUPENTITY: g_pParentWnd->OnSelectionUngroupentity (); break;
500     case ID_SELECTION_MERGE: Select_MergeEntity(); break;
501     case ID_SELECTION_SEPERATE: Select_Seperate(); break;
502     case ID_SELECTION_MAKE_DETAIL: g_pParentWnd->OnSelectionMakeDetail (); break;
503     case ID_SELECTION_MAKE_STRUCTURAL: g_pParentWnd->OnSelectionMakeStructural (); break;
504     case ID_SNAPTOGRID: g_pParentWnd->OnSnaptogrid (); break;
505     case ID_TEXTURES_SHOWINUSE: g_pParentWnd->OnTexturesShowinuse (); break;
506     case ID_TEXTURES_SHOWALL: g_pParentWnd->OnTexturesShowall (); break;
507     case ID_TEXTURES_INSPECTOR: g_pParentWnd->OnTexturesInspector (); break;
508     case ID_TEXTURE_REPLACEALL: g_pParentWnd->OnTextureReplaceall (); break;
509     case ID_TOGGLE_LOCK: g_pParentWnd->OnToggleLock (); break;
510     case ID_TOGGLE_ROTATELOCK: g_pParentWnd->OnToggleRotatelock (); break;
511     case ID_TEXTURES_LOAD: g_pParentWnd->OnTexturesLoad (); break;
512     case ID_TEXTURES_RELOADSHADERS: g_pParentWnd->OnTexturesReloadshaders (); break;
513     case ID_TEXTURES_SHADERS_SHOW: g_pParentWnd->OnTexturesShadersShow (); break;
514     case ID_TEXTURES_TEXTUREWINDOWSCALE_200:
515     case ID_TEXTURES_TEXTUREWINDOWSCALE_100:
516     case ID_TEXTURES_TEXTUREWINDOWSCALE_50:
517     case ID_TEXTURES_TEXTUREWINDOWSCALE_25:
518     case ID_TEXTURES_TEXTUREWINDOWSCALE_10:
519       g_pParentWnd->SetTextureScale (id);
520       break;
521     case ID_TEXTURES_LOADLIST: g_pParentWnd->OnTexturesLoadlist (); break;
522     case ID_TEXTURES_SHADERLISTONLY: g_pParentWnd->OnTexturesShaderlistonly (); break;
523     case ID_TEXTUREWINDOW_SCALEUP: g_pParentWnd->OnTexturewindowScaleup (); break;
524     case ID_TEXTUREWINDOW_SCALEDOWN: g_pParentWnd->OnTexturewindowScaledown (); break;
525     case ID_MISC_BENCHMARK: g_pParentWnd->OnMiscBenchmark (); break;
526     case ID_COLOR_SETORIGINAL: g_pParentWnd->OnColorSetoriginal (); break;
527     case ID_COLOR_SETQER: g_pParentWnd->OnColorSetqer (); break;
528     case ID_COLOR_SETBLACK: g_pParentWnd->OnColorSetblack (); break;
529     case ID_COLOR_SETYDNAR: g_pParentWnd->OnColorSetydnar (); break;  /* ydnar */
530     case ID_TEXTUREBK: g_pParentWnd->OnTexturebk (); break;
531     case ID_COLORS_XYBK: g_pParentWnd->OnColorsXybk (); break;
532     case ID_COLORS_MAJOR: g_pParentWnd->OnColorsMajor (); break;
533     case ID_COLORS_MINOR: g_pParentWnd->OnColorsMinor (); break;
534     case ID_COLORS_GRIDTEXT: g_pParentWnd->OnColorsGridtext (); break;
535     case ID_COLORS_GRIDBLOCK: g_pParentWnd->OnColorsGridblock (); break;
536     case ID_COLORS_CAMERABACK: g_pParentWnd->OnColorsCameraBack (); break;
537     case ID_COLORS_BRUSH: g_pParentWnd->OnColorsBrush (); break;
538     case ID_COLORS_SELECTEDBRUSH: g_pParentWnd->OnColorsSelectedbrush (); break;
539     case ID_COLORS_SELECTEDBRUSH3D: g_pParentWnd->OnColorsSelectedbrush3D (); break;
540     case ID_COLORS_CLIPPER: g_pParentWnd->OnColorsClipper (); break;
541     case ID_COLORS_VIEWNAME: g_pParentWnd->OnColorsViewname (); break;
542     case ID_MISC_GAMMA: g_pParentWnd->OnMiscGamma (); break;
543     case ID_MISC_FINDBRUSH: g_pParentWnd->OnMiscFindbrush (); break;
544     case ID_MISC_NEXTLEAKSPOT: g_pParentWnd->OnMiscNextleakspot (); break;
545     case ID_MISC_PREVIOUSLEAKSPOT: g_pParentWnd->OnMiscPreviousleakspot (); break;
546     case ID_MISC_PRINTXY: g_pParentWnd->OnMiscPrintxy (); break;
547     case ID_MISC_SELECTENTITYCOLOR: g_pParentWnd->OnMiscSelectentitycolor (); break;
548     case ID_CONVERTCURVES: g_pParentWnd->OnConvertcurves (); break;
549     case ID_REGION_OFF: g_pParentWnd->OnRegionOff (); break;
550     case ID_REGION_SETXY: g_pParentWnd->OnRegionSetxy (); break;
551     case ID_REGION_SETTALLBRUSH: g_pParentWnd->OnRegionSettallbrush (); break;
552     case ID_REGION_SETBRUSH: g_pParentWnd->OnRegionSetbrush (); break;
553     case ID_REGION_SETSELECTION: g_pParentWnd->OnRegionSetselection (); break;
554     case ID_BRUSH_3SIDED: g_pParentWnd->OnBrush3sided (); break;
555     case ID_BRUSH_4SIDED: g_pParentWnd->OnBrush4sided (); break;
556     case ID_BRUSH_5SIDED: g_pParentWnd->OnBrush5sided (); break;
557     case ID_BRUSH_6SIDED: g_pParentWnd->OnBrush6sided (); break;
558     case ID_BRUSH_7SIDED: g_pParentWnd->OnBrush7sided (); break;
559     case ID_BRUSH_8SIDED: g_pParentWnd->OnBrush8sided (); break;
560     case ID_BRUSH_9SIDED: g_pParentWnd->OnBrush9sided (); break;
561     case ID_BRUSH_ARBITRARYSIDED: g_pParentWnd->OnBrushArbitrarysided (); break;
562     case ID_BRUSH_MAKECONE: g_pParentWnd->OnBrushMakecone (); break;
563     case ID_BRUSH_PRIMITIVES_SPHERE: g_pParentWnd->OnBrushPrimitivesSphere (); break;
564     case ID_CURVE_PATCHTUBE: g_pParentWnd->OnCurvePatchtube (); break;
565     case ID_CURVE_PATCHDENSETUBE: g_pParentWnd->OnCurvePatchdensetube (); break;
566     case ID_CURVE_PATCHVERYDENSETUBE: g_pParentWnd->OnCurvePatchverydensetube (); break;
567     case ID_CURVE_PATCHSQUARE: g_pParentWnd->OnCurvePatchsquare (); break;
568     case ID_CURVE_PATCHENDCAP: g_pParentWnd->OnCurvePatchendcap (); break;
569     case ID_CURVE_PATCHBEVEL: g_pParentWnd->OnCurvePatchbevel (); break;
570     case ID_CURVE_MOREENDCAPSBEVELS_SQUAREBEVEL: g_pParentWnd->OnCurveMoreendcapsbevelsSquarebevel (); break;
571     case ID_CURVE_MOREENDCAPSBEVELS_SQUAREENDCAP: g_pParentWnd->OnCurveMoreendcapsbevelsSquareendcap();break;
572     case ID_CURVE_PATCHCONE: g_pParentWnd->OnCurvePatchcone (); break;
573     case ID_CURVE_SIMPLEPATCHMESH: g_pParentWnd->OnCurveSimplepatchmesh (); break;
574     case ID_CURVE_INSERT_INSERTCOLUMN: g_pParentWnd->OnCurveInsertInsertcolumn (); break;
575     case ID_CURVE_INSERT_ADDCOLUMN: g_pParentWnd->OnCurveInsertAddcolumn (); break;
576     case ID_CURVE_INSERT_INSERTROW: g_pParentWnd->OnCurveInsertInsertrow (); break;
577     case ID_CURVE_INSERT_ADDROW: g_pParentWnd->OnCurveInsertAddrow (); break;
578     case ID_CURVE_DELETE_FIRSTCOLUMN: g_pParentWnd->OnCurveDeleteFirstcolumn (); break;
579     case ID_CURVE_DELETE_LASTCOLUMN: g_pParentWnd->OnCurveDeleteLastcolumn (); break;
580     case ID_CURVE_DELETE_FIRSTROW: g_pParentWnd->OnCurveDeleteFirstrow (); break;
581     case ID_CURVE_DELETE_LASTROW: g_pParentWnd->OnCurveDeleteLastrow (); break;
582     case ID_CURVE_NEGATIVE: g_pParentWnd->OnCurveNegative (); break;
583     case ID_CURVE_REDISPERSE_ROWS: g_pParentWnd->OnCurveRedisperseRows (); break;
584     case ID_CURVE_REDISPERSE_INTERMEDIATE_COLS: g_pParentWnd->OnCurveRedisperseIntermediateCols (); break;
585     case ID_CURVE_REDISPERSE_INTERMEDIATE_ROWS: g_pParentWnd->OnCurveRedisperseIntermediateRows (); break;
586     case ID_CURVE_MATRIX_TRANSPOSE: g_pParentWnd->OnCurveMatrixTranspose (); break;
587     case ID_CURVE_CAP: g_pParentWnd->OnCurveCap (); break;
588     case ID_CURVE_CYCLECAP: g_pParentWnd->OnCurveCyclecap (); break;
589     case ID_CURVE_OVERLAY_SET: g_pParentWnd->OnCurveOverlaySet (); break;
590     case ID_CURVE_OVERLAY_CLEAR: g_pParentWnd->OnCurveOverlayClear (); break;
591     case ID_CURVE_THICKEN: g_pParentWnd->OnCurveThicken (); break;
592     case ID_PLUGINS_REFRESH: g_pParentWnd->OnPluginsRefresh (); break;
593     case ID_HELP: g_pParentWnd->OnHelp (); break;
594     case ID_HELP_LINKS: g_pParentWnd->OnHelpLinks(); break;
595     case ID_HELP_BUGREPORT: g_pParentWnd->OnHelpBugreport(); break;
596     case ID_HELP_COMMANDLIST: g_pParentWnd->OnHelpCommandlist (); break;
597     case ID_HELP_ABOUT: g_pParentWnd->OnHelpAbout (); break;
598     case ID_DONTSELECTMODEL: g_pParentWnd->OnDontselectmodel (); break;
599     case ID_FILTER_AREAPORTALS: g_pParentWnd->OnFilterAreaportals (); break;
600     case ID_FILTER_CAULK: g_pParentWnd->OnFilterCaulk (); break;
601     case ID_FILTER_STRUCTURAL: g_pParentWnd->OnFilterStructural (); break;
602     case ID_FILTER_CLIPS: g_pParentWnd->OnFilterClips (); break;
603     case ID_FILTER_BOTCLIPS: g_pParentWnd->OnFilterBotClips (); break;
604     case ID_FILTER_DETAILS: g_pParentWnd->OnFilterDetails (); break;
605     case ID_FILTER_ENTITIES: g_pParentWnd->OnFilterEntities (); break;
606     case ID_FILTER_HINTSSKIPS: g_pParentWnd->OnFilterHintsskips (); break;
607     case ID_FILTER_LIGHTS: g_pParentWnd->OnFilterLights (); break;
608     case ID_FILTER_LIQUIDS: g_pParentWnd->OnFilterLiquids (); break;
609     case ID_FILTER_MODELS: g_pParentWnd->OnFilterModels (); break;
610     case ID_FILTER_PATCHES: g_pParentWnd->OnFilterPatches (); break;
611     case ID_FILTER_TRANSLUCENT: g_pParentWnd->OnFilterTranslucent (); break;
612     case ID_FILTER_TRIGGERS: g_pParentWnd->OnFilterTriggers (); break;
613     case ID_FILTER_WORLD: g_pParentWnd->OnFilterWorld (); break;
614     case ID_FILTER_PATHS: g_pParentWnd->OnFilterPaths (); break;
615     case ID_FILTER_CLUSTERPORTALS: g_pParentWnd->OnFilterClusterportals (); break;
616     case ID_FILTER_LIGHTGRID: g_pParentWnd->OnFilterLightgrid (); break;
617
618     case ID_POPUP_SELECTION: g_pParentWnd->OnPopupSelection (); break;
619     case ID_VIEW_CHANGE: g_pParentWnd->OnViewChange (); break;
620     case ID_TEXTURES_POPUP: g_pParentWnd->OnTexturesPopup (); break;
621     case ID_VIEW_CAMERATOGGLE: g_pParentWnd->ToggleCamera (); break;
622     case ID_VIEW_CAMERAUPDATE: g_pParentWnd->OnViewCameraupdate (); break;
623     case ID_SELECT_MOUSEROTATE: g_pParentWnd->OnSelectMouserotate (); break;
624     case ID_SELECT_MOUSESCALE: g_pParentWnd->OnSelectMousescale (); break;
625     case ID_SCALELOCKX: g_pParentWnd->OnScalelockx (); break;
626     case ID_SCALELOCKY: g_pParentWnd->OnScalelocky (); break;
627     case ID_SCALELOCKZ: g_pParentWnd->OnScalelockz (); break;
628     case ID_DONTSELECTCURVE: g_pParentWnd->OnDontselectcurve (); break;
629     case ID_PATCH_SHOWBOUNDINGBOX: g_pParentWnd->OnPatchToggleBox (); break;
630     case ID_PATCH_WIREFRAME: g_pParentWnd->OnPatchWireframe (); break;
631     case ID_PATCH_BEND: g_pParentWnd->OnPatchBend (); break;
632     case ID_PATCH_WELD: g_pParentWnd->OnPatchWeld (); break;
633     case ID_PATCH_DRILLDOWN: g_pParentWnd->OnPatchDrilldown (); break;
634     case ID_DROP_GROUP_NAME: g_pParentWnd->OnDropGroupName (); break;
635     case ID_DROP_GROUP_NEWGROUP: g_pParentWnd->OnDropGroupNewgroup (); break;
636     case ID_DROP_GROUP_REMOVE: g_pParentWnd->OnDropGroupRemove (); break;
637     case ID_SHOW_ENTITIES: g_pParentWnd->OnShowEntities (); break;
638
639     case IDC_BTN_FACEFIT: g_pParentWnd->OnFaceFit (); break;
640     case ID_VIEW_TEXTURE: g_pParentWnd->OnViewTexture (); break;
641     case ID_PATCH_INSPECTOR: g_pParentWnd->OnPatchInspector (); break;
642     case ID_CURVE_NEGATIVETEXTUREX: g_pParentWnd->OnCurveNegativeTextureX (); break;
643     case ID_CURVE_NEGATIVETEXTUREY: g_pParentWnd->OnCurveNegativeTextureY (); break;
644     case ID_CURVE_INSERTCOLUMN: g_pParentWnd->OnCurveInsertcolumn (); break;
645     case ID_CURVE_INSERTROW: g_pParentWnd->OnCurveInsertrow (); break;
646     case ID_CURVE_DELETECOLUMN: g_pParentWnd->OnCurveDeletecolumn (); break;
647     case ID_CURVE_DELETEROW: g_pParentWnd->OnCurveDeleterow (); break;
648     case ID_PATCH_TAB: g_pParentWnd->OnPatchTab (); break;
649     case ID_CAMERA_FORWARD: g_pParentWnd->OnCameraForward (TRUE); break;
650     case ID_CAMERA_BACK: g_pParentWnd->OnCameraBack (TRUE); break;
651     case ID_CAMERA_LEFT: g_pParentWnd->OnCameraLeft (TRUE); break;
652     case ID_CAMERA_RIGHT: g_pParentWnd->OnCameraRight (TRUE); break;
653     case ID_CAMERA_UP: g_pParentWnd->OnCameraUp (); break;
654     case ID_CAMERA_DOWN: g_pParentWnd->OnCameraDown (); break;
655     case ID_CAMERA_ANGLEUP: g_pParentWnd->OnCameraAngleup (); break;
656     case ID_CAMERA_ANGLEDOWN: g_pParentWnd->OnCameraAngledown (); break;
657     case ID_CAMERA_STRAFELEFT: g_pParentWnd->OnCameraStrafeleft (TRUE); break;
658     case ID_CAMERA_STRAFERIGHT: g_pParentWnd->OnCameraStraferight (TRUE); break;
659     case ID_GRID_TOGGLE: g_pParentWnd->OnGridToggle (); break;
660     case ID_VIEW_CONSOLE: g_pParentWnd->OnViewConsole (); break;
661     case ID_VIEW_CROSSHAIR: g_pParentWnd->OnViewCrosshair (); break;
662     case ID_SELECTION_TEXTURE_FIT: g_pParentWnd->OnSelectionTextureFit (); break;
663     case ID_SELECTION_TEXTURE_ROTATECLOCK: g_pParentWnd->OnSelectionTextureRotateclock (); break;
664     case ID_SELECTION_TEXTURE_ROTATECOUNTER: g_pParentWnd->OnSelectionTextureRotatecounter (); break;
665     case ID_SELECTION_TEXTURE_SCALEUP: g_pParentWnd->OnSelectionTextureScaleup (); break;
666     case ID_SELECTION_TEXTURE_SCALEDOWN: g_pParentWnd->OnSelectionTextureScaledown (); break;
667     case ID_SELECTION_TEXTURE_SHIFTLEFT: g_pParentWnd->OnSelectionTextureShiftleft (); break;
668     case ID_SELECTION_TEXTURE_SHIFTRIGHT: g_pParentWnd->OnSelectionTextureShiftright (); break;
669     case ID_SELECTION_TEXTURE_SHIFTUP: g_pParentWnd->OnSelectionTextureShiftup (); break;
670     case ID_SELECTION_TEXTURE_SHIFTDOWN: g_pParentWnd->OnSelectionTextureShiftdown (); break;
671     case ID_GRID_PREV: g_pParentWnd->OnGridPrev (); break;
672     case ID_GRID_NEXT: g_pParentWnd->OnGridNext (); break;
673     case ID_SELECTION_TEXTURE_SCALELEFT: g_pParentWnd->OnSelectionTextureScaleLeft (); break;
674     case ID_SELECTION_TEXTURE_SCALERIGHT: g_pParentWnd->OnSelectionTextureScaleRight (); break;
675     case ID_SELECTION_MOVEDOWN: g_pParentWnd->OnSelectionMovedown (); break;
676     case ID_SELECTION_MOVEUP: g_pParentWnd->OnSelectionMoveup (); break;
677     case ID_SELECTION_PRINT: g_pParentWnd->OnSelectionPrint (); break;
678     case ID_SELECTION_TOGGLESIZEPAINT: g_pParentWnd->OnSelectionTogglesizepaint (); break;
679     case ID_PATCH_NATURALIZE: g_pParentWnd->OnPatchNaturalize (); break;
680     case ID_SELECT_SNAPTOGRID: g_pParentWnd->OnSnapToGrid (); break;
681     case ID_SELECT_ALL: g_pParentWnd->OnSelectAll (); break;
682     case ID_SELECTION_INVERT: g_pParentWnd->OnSelectionInvert (); break;
683     }
684
685     return TRUE;
686 }
687
688 static gint timer (gpointer data)
689 {
690   MainFrame *wnd = (MainFrame*)data;
691   wnd->OnTimer ();
692   return TRUE;
693 }
694
695 static gint mainframe_delete (GtkWidget *widget, GdkEvent *event, gpointer data)
696 {
697   MainFrame *wnd = (MainFrame*)data;
698
699   wnd->OnDelete();
700
701   if (ConfirmModified())
702     return FALSE;
703
704   g_qeglobals_gui.d_edit = NULL;
705
706   return TRUE;
707 }
708
709 static void mainframe_destroy (GtkWidget *widget, gpointer data)
710 {
711   MainFrame *wnd = (MainFrame*)data;
712
713   // avoid saving prefs when the app is minimized
714   if (g_pParentWnd->IsSleeping())
715   {
716     Sys_Printf("Shutdown while sleeping, not saving prefs\n");
717     g_qeglobals.disable_ini = true;
718   }
719
720   // NOTE TTimo this is very clumsy, in MainFrame::OnDestroy we might call SavePrefs again
721   //   we will do more stuff in OnDestroy for window position saving too, so I guess this call is still relevant?
722   g_PrefsDlg.SavePrefs ();
723
724   wnd->OnDestroy ();
725
726   // shutdown modules
727   // NOTE: I've decided to do this before SavePrefs in case we broadcast some shutdown info
728   // and modules / plugins decide to save some stuff
729   g_pParentWnd->GetPlugInMgr().Shutdown();
730
731   delete wnd;
732
733   QGL_Shutdown();
734   g_PrefsDlg.Destroy ();
735   g_dlgSurface.Destroy ();
736   g_dlgFind.Destroy ();
737   g_PatchDialog.Destroy ();
738
739   gtk_main_quit ();
740 }
741
742 static gint mainframe_keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)
743 {
744   unsigned int code = gdk_keyval_to_upper(event->keyval);
745
746   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=924
747   if(code == GDK_ISO_Left_Tab) {
748     code = GDK_Tab;
749   }
750
751 #ifdef DBG_KBD
752   Sys_Printf("key: %d (keyval: %d) (ctrl: %d)\n", code, event->keyval, event->state & GDK_CONTROL_MASK);
753 #endif
754
755   // BUG: http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=865
756   // return only if Texture Viewport  is in main window, otherwise if Tex viewport is in it's own window
757   // the Filter GtkEntry won't release focus
758   if ( g_pParentWnd->GetTexWnd()->m_pFilter == gtk_window_get_focus(GTK_WINDOW(widget)) )
759     if ( gtk_widget_is_focus( g_pParentWnd->GetTexWnd()->m_pFilter ) )
760       return FALSE;
761
762 #ifdef DBG_KBD
763   Sys_Printf("mainframe_keypress processing into a command\n");
764 #endif
765   for (int i = 0; i < g_nCommandCount; i++)
766   {
767     if (g_Commands[i].m_nKey == code)    // find a match?
768     {
769       // check modifiers
770       unsigned int nState = 0;
771       if (Sys_AltDown ())
772         nState |= RAD_ALT;
773       if ((event->state & GDK_CONTROL_MASK) != 0)
774         nState |= RAD_CONTROL;
775       if ((event->state & GDK_SHIFT_MASK) != 0)
776         nState |= RAD_SHIFT;
777       if ((g_Commands[i].m_nModifiers & 0x7) == nState)
778       {
779         HandleCommand (NULL, GINT_TO_POINTER (g_Commands[i].m_nCommand));
780         gtk_signal_emit_stop_by_name (GTK_OBJECT(widget), "key_press_event");
781         return FALSE;
782       }
783     }
784   }
785
786   return TRUE;
787 }
788
789 static gint mainframe_keyrelease (GtkWidget* widget, GdkEventKey* event, gpointer data)
790 {
791   unsigned int code = gdk_keyval_to_upper(event->keyval);
792
793   if (gtk_accelerator_valid (event->keyval, (GdkModifierType)0))
794     return TRUE;
795
796   for (int i = 0; i < g_nCommandCount; i++)
797   {
798     if (g_Commands[i].m_nKey == code)    // find a match?
799     {
800       if(!g_Commands[i].m_nModifiers)
801       {
802         // Gef: Only call the handler if it's a key that needs keyup events
803         switch (g_Commands[i].m_nCommand)
804         {
805           case ID_CAMERA_FORWARD:
806           case ID_CAMERA_BACK:
807           case ID_CAMERA_LEFT:
808           case ID_CAMERA_RIGHT:
809           case ID_CAMERA_STRAFELEFT:
810           case ID_CAMERA_STRAFERIGHT:
811           {
812             HandleKeyUp (NULL, GINT_TO_POINTER (g_Commands[i].m_nCommand));
813             gtk_signal_emit_stop_by_name (GTK_OBJECT(widget), "key_release_event");
814           }
815
816         }
817         return FALSE;
818       }
819     }
820   }
821
822   return TRUE;
823 }
824
825
826 // =============================================================================
827 // Window creation functions
828
829 void AddMenuItem (GtkWidget* item, unsigned int id)
830 {
831   for (int i = 0; i < g_nCommandCount; i++)
832     if (g_Commands[i].m_nCommand == id)
833     {
834       g_object_set_data (G_OBJECT (g_pParentWnd->m_pWidget), g_Commands[i].m_strMenu, item);
835       break;
836     }
837 }
838
839 void MainFrame::handle_help_command(int id)
840 {
841   OpenURL(mHelpURLs[id]->GetBuffer());
842 }
843
844 /*!
845 needed for hooking in Gtk+
846 */
847 void HandleHelpCommand (GtkWidget *widget, gpointer data)
848 {
849   int id = GPOINTER_TO_INT (data);
850   g_pParentWnd->handle_help_command(id);
851 }
852
853 void MainFrame::process_xlink (Str &FileName, const char *menu_name, const char *base_url, GtkWidget *menu, GtkAccelGroup *accel)
854 {
855   xmlDocPtr pDoc;
856   pDoc = xmlParseFile(FileName.GetBuffer());
857   if (pDoc)
858   {
859     Sys_Printf("Processing .xlink file '%s'\n", FileName.GetBuffer());
860     // create sub menu
861     GtkWidget* menu_in_menu = create_menu_in_menu_with_mnemonic(menu, menu_name);
862     // start walking the nodes, find the 'links' one
863     xmlNodePtr pNode = pDoc->children;
864     while (pNode && strcmp((const char*)pNode->name, "links"))
865       pNode=pNode->next;
866     if (pNode)
867     {
868       pNode = pNode->children;
869       while(pNode)
870       {
871         if (!strcmp((const char*)pNode->name, "item"))
872         {
873           // process the URL
874           Str *url;
875           if (strstr((char *)xmlGetProp(pNode, (xmlChar *)"url"), "http://"))
876           {
877             // complete URL
878             url = new Str;
879             *url = (char *)xmlGetProp(pNode, (xmlChar *)"url");
880           }
881           else
882           {
883             // relative URL
884             url = new Str;
885             *url = base_url;
886             *url += (char *)xmlGetProp(pNode, (xmlChar *)"url");
887           }
888           mHelpURLs.push_back(url);
889           create_menu_item_with_mnemonic (menu_in_menu, (char *)xmlGetProp(pNode, (xmlChar *)"name"), GTK_SIGNAL_FUNC(HandleHelpCommand), mHelpURLs.size()-1);
890         }
891         pNode=pNode->next;
892       }
893     }
894     xmlFreeDoc(pDoc);
895   }
896   else
897   {
898     Sys_Printf("'%s' not found / parse failed\n", FileName.GetBuffer());
899   }
900 }
901
902 void MainFrame::create_game_help_menu (GtkWidget *menu, GtkAccelGroup *accel)
903 {
904   Str FileName;
905   list<CGameDescription *>::iterator iGame;
906
907   // start in the global dir
908   FileName = g_strAppPath;
909   FileName += "global.xlink";
910   process_xlink(FileName, "General", g_strAppPath.GetBuffer(), menu, accel);
911
912   for (iGame = g_PrefsDlg.mGamesDialog.mGames.begin(); iGame != g_PrefsDlg.mGamesDialog.mGames.end(); iGame++)
913   {
914     FileName = (*iGame)->mGameToolsPath;
915     FileName += "game.xlink";
916     process_xlink(FileName, (*iGame)->mGameName, (*iGame)->mGameToolsPath.GetBuffer(), menu, accel);
917   }
918 }
919
920 void MainFrame::create_main_menu (GtkWidget *window, GtkWidget *vbox)
921 {
922   GtkWidget *handle_box, *menu_bar, *menu, *menu_in_menu, *menu_3, *item;
923   GtkAccelGroup *accel;
924
925   g_bIgnoreCommands++;
926   accel = gtk_accel_group_new ();
927   global_accel = accel;
928   gtk_window_add_accel_group (GTK_WINDOW (window), accel);
929
930   handle_box = gtk_handle_box_new ();
931   gtk_box_pack_start (GTK_BOX (vbox), handle_box, FALSE, FALSE, 0);
932   gtk_widget_show (handle_box);
933
934   menu_bar = gtk_menu_bar_new ();
935   gtk_container_add (GTK_CONTAINER (handle_box), menu_bar);
936   gtk_widget_show (menu_bar);
937
938   // File menu
939   menu = create_sub_menu_with_mnemonic (menu_bar, "_File");
940   if (g_PrefsDlg.m_bDetachableMenus)
941     menu_tearoff (menu);
942
943   create_menu_item_with_mnemonic (menu, "_New Map",
944                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_NEW);
945   menu_separator (menu);
946
947   //++timo temporary experimental stuff for sleep mode..
948   item = create_menu_item_with_mnemonic (menu, "_Sleep",
949                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_SLEEP);
950   g_object_set_data (G_OBJECT (window), "menu_file_sleep", item );
951   menu_separator (menu);
952   // end experimental
953
954   item = create_menu_item_with_mnemonic (menu, "_Open...",
955                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_OPEN);
956   g_object_set_data (G_OBJECT (window), "menu_file_open", item);
957   create_menu_item_with_mnemonic (menu, "_Import...", // Hydra: give it it's proper name
958                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_IMPORTMAP);
959   item = create_menu_item_with_mnemonic (menu, "_Save",
960                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_SAVE);
961   g_object_set_data (G_OBJECT (window), "menu_file_save", item);
962   create_menu_item_with_mnemonic (menu, "Save _as...",
963                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_SAVEAS);
964   create_menu_item_with_mnemonic (menu, "Save s_elected...",
965                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_EXPORTMAP);
966   menu_separator (menu);
967   item = create_menu_item_with_mnemonic (menu, "Save re_gion...",
968                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_SAVEREGION);
969   g_object_set_data (G_OBJECT (window), "menu_file_saveregion", item);
970   menu_separator (menu);
971   create_menu_item_with_mnemonic (menu, "New p_roject...",
972                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_NEWPROJECT);
973   create_menu_item_with_mnemonic (menu, "Load _project...",
974                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_LOADPROJECT);
975   create_menu_item_with_mnemonic (menu, "Pro_ject settings...",
976                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_PROJECTSETTINGS);
977   menu_separator (menu);
978   create_menu_item_with_mnemonic (menu, "_Pointfile...",
979                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_POINTFILE);
980   menu_separator (menu);
981   item = create_menu_item_with_mnemonic (menu, "Recent Files",
982                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_RECENT1);
983   g_object_set_data (G_OBJECT (item), "accel", accel);
984   gtk_widget_set_sensitive (item, FALSE);
985   MRU_AddWidget (item, 0);
986   item = create_menu_item_with_mnemonic (menu, "2",
987                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_RECENT2);
988   gtk_widget_hide (item);
989   MRU_AddWidget (item, 1);
990   item = create_menu_item_with_mnemonic (menu, "3",
991                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_RECENT3);
992   gtk_widget_hide (item);
993   MRU_AddWidget (item, 2);
994   item = create_menu_item_with_mnemonic (menu, "4",
995                            GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_RECENT4);
996   gtk_widget_hide (item);
997   MRU_AddWidget (item, 3);
998   menu_separator (menu);
999   item = create_menu_item_with_mnemonic (menu, "Check for GtkRadiant update (web)",
1000     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_CHECKUPDATE);
1001   // disable, the functionality is no longer available
1002   gtk_widget_set_sensitive( item, FALSE );
1003
1004   create_menu_item_with_mnemonic (menu, "E_xit",
1005                     GTK_SIGNAL_FUNC (HandleCommand), ID_FILE_EXIT);
1006
1007   // Edit menu
1008   menu = create_sub_menu_with_mnemonic (menu_bar, "_Edit");
1009   if (g_PrefsDlg.m_bDetachableMenus)
1010     menu_tearoff (menu);
1011   item = create_menu_item_with_mnemonic (menu, "_Undo",
1012                            GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_UNDO);
1013   g_object_set_data (G_OBJECT (window), "menu_edit_undo", item);
1014   item = create_menu_item_with_mnemonic (menu, "_Redo",
1015                            GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_REDO);
1016   g_object_set_data (G_OBJECT (window), "menu_edit_redo", item);
1017   menu_separator (menu);
1018   item = create_menu_item_with_mnemonic (menu, "_Copy", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_COPYBRUSH);
1019   item = create_menu_item_with_mnemonic (menu, "_Paste", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_PASTEBRUSH);
1020   item = create_menu_item_with_mnemonic (menu, "P_aste To Camera", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_PASTEBRUSHTOCAMERA);
1021   item = create_menu_item_with_mnemonic (menu, "_Delete", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DELETE);
1022   g_object_set_data (G_OBJECT (window), "menu_selection_delete", item);
1023   menu_separator (menu);
1024   create_menu_item_with_mnemonic (menu, "Map Info...", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_MAPINFO);
1025   create_menu_item_with_mnemonic (menu, "Entity Info...", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_ENTITYINFO);
1026   menu_separator (menu);
1027   create_menu_item_with_mnemonic (menu, "Brush Scripts...", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_SCRIPTS);
1028   menu_separator (menu);
1029   create_menu_item_with_mnemonic (menu, "Load Pre_fab...", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_LOADPREFAB);
1030   create_menu_item_with_mnemonic (menu, "Save Selection as Prefab...", GTK_SIGNAL_FUNC (HandleCommand), ID_EDIT_SAVEPREFAB);
1031   menu_separator (menu);
1032   create_menu_item_with_mnemonic (menu, "Preferences...", GTK_SIGNAL_FUNC (HandleCommand), ID_PREFS);
1033
1034   // View menu
1035   menu = create_sub_menu_with_mnemonic (menu_bar, "_View");
1036   if (g_PrefsDlg.m_bDetachableMenus)
1037     menu_tearoff (menu);
1038
1039   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Toggle");
1040   create_menu_item_with_mnemonic (menu_in_menu, "Camera View", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLECAMERA);
1041   create_menu_item_with_mnemonic (menu_in_menu, "Console View", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLECONSOLE);
1042   item = create_menu_item_with_mnemonic (menu_in_menu, "Entity View", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITY);
1043   g_object_set_data (G_OBJECT (window), "menu_view_entity", item);
1044   //  create_menu_item_with_mnemonic (menu_in_menu, "Groups View", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_GROUPS);
1045   create_menu_item_with_mnemonic (menu_in_menu, "XY (Top)", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLEVIEW);
1046   create_menu_item_with_mnemonic (menu_in_menu, "YZ (Side)", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLEVIEW_YZ);
1047   create_menu_item_with_mnemonic (menu_in_menu, "XZ (Front)", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLEVIEW_XZ);
1048   create_menu_item_with_mnemonic (menu_in_menu, "Z View", GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLEZ);
1049   menu_separator (menu);
1050   item = create_menu_item_with_mnemonic (menu, "_Center", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CENTER);
1051   item = create_menu_item_with_mnemonic (menu, "_Center 2d", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CENTERVIEW);
1052   item = create_menu_item_with_mnemonic (menu, "_Up Floor", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_UPFLOOR);
1053   item = create_menu_item_with_mnemonic (menu, "_Down Floor", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_DOWNFLOOR);
1054   menu_separator (menu);
1055   item = create_menu_item_with_mnemonic (menu, "_Next (XY, YZ, XY)", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_NEXTVIEW);
1056   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Layout");
1057   create_menu_item_with_mnemonic (menu_in_menu, "XY (Top)", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_XY);
1058   create_menu_item_with_mnemonic (menu_in_menu, "YZ", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SIDE);
1059   create_menu_item_with_mnemonic (menu_in_menu, "XZ", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_FRONT);
1060   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Zoom");
1061   create_menu_item_with_mnemonic (menu_in_menu, "_XY 100%", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_100);
1062   item = create_menu_item_with_mnemonic (menu_in_menu, "XY Zoom _In", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ZOOMIN);
1063   item = create_menu_item_with_mnemonic (menu_in_menu, "XY Zoom _Out", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ZOOMOUT);
1064   menu_separator (menu_in_menu);
1065   create_menu_item_with_mnemonic (menu_in_menu, "_Z 100%", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_Z100);
1066   item = create_menu_item_with_mnemonic (menu_in_menu, "Z Zoo_m In", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ZZOOMIN);
1067   g_object_set_data (G_OBJECT (window), "menu_view_zzoomin", item);
1068   item = create_menu_item_with_mnemonic (menu_in_menu, "Z Zoom O_ut", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ZZOOMOUT);
1069   g_object_set_data (G_OBJECT (window), "menu_view_zzoomout", item);
1070   menu_separator (menu_in_menu);
1071   item = create_menu_item_with_mnemonic (menu_in_menu, "Cubic Clip Zoom In", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CUBEIN);
1072   item = create_menu_item_with_mnemonic (menu_in_menu, "Cubic Clip Zoom Out", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CUBEOUT);
1073   menu_separator (menu);
1074
1075   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Show");
1076   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show _Angles", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWANGLES, FALSE);
1077   g_object_set_data (G_OBJECT (window), "menu_view_showangles", item);
1078   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show _Names", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWNAMES, TRUE);
1079   g_object_set_data (G_OBJECT (window), "menu_view_shownames", item);
1080   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show Blocks", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWBLOCKS, FALSE);
1081   g_object_set_data (G_OBJECT (window), "menu_view_showblocks", item);
1082   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show C_oordinates", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWCOORDINATES, TRUE);
1083   g_object_set_data (G_OBJECT (window), "menu_view_showcoordinates", item);
1084   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show Window Outline", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWOUTLINE, TRUE);
1085   g_object_set_data (G_OBJECT (window), "menu_view_showoutline", item);
1086   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show ZBuffered Outline", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_NOOUTLINE, TRUE);
1087   g_object_set_data (G_OBJECT (window), "menu_selection_nooutline", item);
1088   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show Axes", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWAXES, TRUE);
1089   g_object_set_data (G_OBJECT (window), "menu_view_showaxes", item);
1090   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Show Workzone", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_SHOWWORKZONE, FALSE);
1091   g_object_set_data (G_OBJECT (window), "menu_view_showworkzone", item);
1092
1093   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Filter");
1094   create_check_menu_item_with_mnemonic (menu_in_menu, "World", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_WORLD, FALSE);
1095   create_check_menu_item_with_mnemonic (menu_in_menu, "Entities", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_ENTITIES, FALSE);
1096   create_check_menu_item_with_mnemonic (menu_in_menu, "Areaportals", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_AREAPORTALS, FALSE);
1097   create_check_menu_item_with_mnemonic (menu_in_menu, "Translucent", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_TRANSLUCENT, FALSE);
1098   create_check_menu_item_with_mnemonic (menu_in_menu, "Liquids", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_LIQUIDS, FALSE);
1099   create_check_menu_item_with_mnemonic (menu_in_menu, "Caulk", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_CAULK, FALSE);
1100   create_check_menu_item_with_mnemonic (menu_in_menu, "Clips", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_CLIPS, FALSE);
1101   create_check_menu_item_with_mnemonic (menu_in_menu, "Paths", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_PATHS, FALSE);
1102   create_check_menu_item_with_mnemonic (menu_in_menu, "Clusterportals", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_CLUSTERPORTALS, FALSE);
1103   create_check_menu_item_with_mnemonic (menu_in_menu, "Lights", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_LIGHTS, FALSE);
1104   create_check_menu_item_with_mnemonic (menu_in_menu, "Structural", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_STRUCTURAL, FALSE);
1105   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Lightgrid", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_LIGHTGRID, FALSE);
1106   g_object_set_data (G_OBJECT (window), "menu_filter_lightgrid", item);
1107   create_check_menu_item_with_mnemonic (menu_in_menu, "Patches", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_PATCHES, FALSE);
1108   create_check_menu_item_with_mnemonic (menu_in_menu, "Details", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_DETAILS, FALSE);
1109   create_check_menu_item_with_mnemonic (menu_in_menu, "Hints", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_HINTSSKIPS, FALSE);
1110   create_check_menu_item_with_mnemonic (menu_in_menu, "Models", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_MODELS, FALSE);
1111   create_check_menu_item_with_mnemonic (menu_in_menu, "Triggers", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_TRIGGERS, FALSE);
1112   create_check_menu_item_with_mnemonic (menu_in_menu, "Botclips", GTK_SIGNAL_FUNC (HandleCommand), ID_FILTER_BOTCLIPS, FALSE);
1113
1114   menu_separator (menu);
1115   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Hide/Show");
1116   create_menu_item_with_mnemonic (menu_in_menu, "Hide Selected",
1117                     GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_HIDESHOW_HIDESELECTED);
1118   create_menu_item_with_mnemonic (menu_in_menu, "Show Hidden",
1119                     GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_HIDESHOW_SHOWHIDDEN);
1120   menu_separator (menu);
1121   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Entities as");
1122   g_object_set_data (G_OBJECT (window), "view_entitiesas_menu", menu_in_menu);
1123   item = create_radio_menu_item_with_mnemonic (menu_in_menu, NULL, "Bounding box",
1124                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_BOUNDINGBOX,FALSE);
1125   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_boundingbox", item);
1126   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Wireframe",
1127                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_WIREFRAME,FALSE);
1128   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_wireframe", item);
1129   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Selected Wireframe",
1130                                  GTK_SIGNAL_FUNC (HandleCommand),ID_VIEW_ENTITIESAS_SELECTEDWIREFRAME,FALSE);
1131   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_selectedwireframe", item);
1132   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Selected Skinned",
1133                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_SELECTEDSKINNED,FALSE);
1134   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_selectedskinned", item);
1135   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Skinned",
1136                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_SKINNED,FALSE);
1137   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_skinned", item);
1138   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Skinned and Boxed",
1139                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_ENTITIESAS_SKINNEDANDBOXED,FALSE);
1140   g_object_set_data (G_OBJECT (window), "menu_view_entitiesas_skinnedandboxed", item);
1141   menu_separator (menu);
1142   item = create_check_menu_item_with_mnemonic (menu, "Cubic Clipping",
1143                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CUBICCLIPPING, TRUE);
1144   g_object_set_data (G_OBJECT (window), "menu_view_cubicclipping", item);
1145   menu_separator (menu);
1146   item = create_check_menu_item_with_mnemonic (menu, "OpenGL Lighting",
1147                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_OPENGLLIGHTING, FALSE);
1148   g_object_set_data (G_OBJECT (window), "menu_view_opengllighting", item);
1149
1150   // Selection menu
1151   menu = create_sub_menu_with_mnemonic (menu_bar, "_Selection");
1152   if (g_PrefsDlg.m_bDetachableMenus)
1153     menu_tearoff (menu);
1154
1155   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Drag");
1156   create_menu_item_with_mnemonic (menu_in_menu, "Drag _Edges",
1157                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DRAGEDGES);
1158   create_menu_item_with_mnemonic (menu_in_menu, "Drag _Vertices",
1159                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DRAGVERTECIES);
1160   menu_separator (menu);
1161   create_menu_item_with_mnemonic (menu, "_Clone",
1162                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_CLONE);
1163   item = create_menu_item_with_mnemonic (menu, "Deselect",
1164                            GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DESELECT);
1165   item = create_menu_item_with_mnemonic (menu, "Invert",
1166                            GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_INVERT);
1167 #ifndef QUAKE3
1168   create_menu_item_with_mnemonic (menu, "_Delete",
1169                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_DELETE);
1170 #endif
1171   menu_separator (menu);
1172   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Flip");
1173   create_menu_item_with_mnemonic (menu_in_menu, "Flip _X",
1174                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_FLIPX);
1175   create_menu_item_with_mnemonic (menu_in_menu, "Flip _Y",
1176                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_FLIPY);
1177   create_menu_item_with_mnemonic (menu_in_menu, "Flip _Z",
1178                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_FLIPZ);
1179   menu_separator (menu);
1180   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Rotate");
1181   create_menu_item_with_mnemonic (menu_in_menu, "Rotate X",
1182                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_ROTATEX);
1183   create_menu_item_with_mnemonic (menu_in_menu, "Rotate Y",
1184                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_ROTATEY);
1185   create_menu_item_with_mnemonic (menu_in_menu, "Rotate Z",
1186                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_ROTATEZ);
1187   create_menu_item_with_mnemonic (menu_in_menu, "Arbitrary rotation...",
1188                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_ARBITRARYROTATION);
1189   menu_separator (menu);
1190   create_menu_item_with_mnemonic (menu, "Scale...", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECT_SCALE);
1191   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "CSG");
1192   create_menu_item_with_mnemonic (menu_in_menu, "Make _Hollow",
1193                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MAKEHOLLOW);
1194   create_menu_item_with_mnemonic (menu_in_menu, "CSG _Subtract",
1195                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_CSGSUBTRACT);
1196   create_menu_item_with_mnemonic (menu_in_menu, "CSG _Merge",
1197                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_CSGMERGE);
1198   menu_separator (menu);
1199   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Select");
1200   create_menu_item_with_mnemonic (menu_in_menu, "Select Complete _Tall",
1201                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECTCOMPLETETALL);
1202   create_menu_item_with_mnemonic (menu_in_menu, "Select T_ouching",
1203                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECTTOUCHING);
1204   create_menu_item_with_mnemonic (menu_in_menu, "Select _Partial Tall",
1205                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECTPARTIALTALL);
1206   create_menu_item_with_mnemonic (menu_in_menu, "Select _Inside",
1207                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECTINSIDE);
1208 #ifndef QUAKE3
1209   create_menu_item_with_mnemonic (menu_in_menu, "Nudge Left",
1210                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGELEFT);
1211   create_menu_item_with_mnemonic (menu_in_menu, "Nudge Right",
1212                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGERIGHT);
1213   create_menu_item_with_mnemonic (menu_in_menu, "Nudge Up",
1214                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGEUP);
1215   create_menu_item_with_mnemonic (menu_in_menu, "Nudge Down",
1216                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGEDOWN);
1217 #endif
1218   menu_separator (menu);
1219   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Clipper");
1220   create_menu_item_with_mnemonic (menu_in_menu, "Toggle Clipper",
1221                     GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CLIPPER);
1222   menu_separator (menu_in_menu);
1223   create_menu_item_with_mnemonic (menu_in_menu, "Clip selection",
1224                     GTK_SIGNAL_FUNC (HandleCommand), ID_CLIP_SELECTED);
1225   create_menu_item_with_mnemonic (menu_in_menu, "Split selection",
1226                     GTK_SIGNAL_FUNC (HandleCommand), ID_SPLIT_SELECTED);
1227   create_menu_item_with_mnemonic (menu_in_menu, "Flip Clip orientation",
1228                     GTK_SIGNAL_FUNC (HandleCommand), ID_FLIP_CLIP);
1229   menu_separator (menu);
1230   create_menu_item_with_mnemonic (menu, "Connect entities",
1231                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_CONNECT);
1232   create_menu_item_with_mnemonic (menu, "Ungroup entity",
1233                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_UNGROUPENTITY);
1234   create_menu_item_with_mnemonic (menu, "Make detail",
1235                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MAKE_DETAIL);
1236   create_menu_item_with_mnemonic (menu, "Make structural",
1237                     GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MAKE_STRUCTURAL);
1238
1239   // BSP menu
1240   menu = create_sub_menu_with_mnemonic (menu_bar, "_Bsp");
1241
1242   menu_separator (menu);
1243   g_object_set_data (G_OBJECT (window), "menu_bsp", menu);
1244
1245   // Grid menu
1246   menu = create_sub_menu_with_mnemonic (menu_bar, "_Grid");
1247   if (g_PrefsDlg.m_bDetachableMenus)
1248     menu_tearoff (menu);
1249
1250   item = create_radio_menu_item_with_mnemonic (menu, NULL, "Grid0.25",
1251                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_025, FALSE);
1252   g_object_set_data (G_OBJECT (window), "menu_grid_025", item);
1253   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid0.5",
1254                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_05, FALSE);
1255   g_object_set_data (G_OBJECT (window), "menu_grid_05", item);
1256   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid1",
1257                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_1, FALSE);
1258   g_object_set_data (G_OBJECT (window), "menu_grid_1", item);
1259   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid2",
1260                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_2, FALSE);
1261   g_object_set_data (G_OBJECT (window), "menu_grid_2", item);
1262   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid4",
1263                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_4, FALSE);
1264   g_object_set_data (G_OBJECT (window), "menu_grid_4", item);
1265   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid8",
1266                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_8, TRUE);
1267   g_object_set_data (G_OBJECT (window), "menu_grid_8", item);
1268   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid16",
1269                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_16, FALSE);
1270   g_object_set_data (G_OBJECT (window), "menu_grid_16", item);
1271   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid32",
1272                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_32, FALSE);
1273   g_object_set_data (G_OBJECT (window), "menu_grid_32", item);
1274   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid64",
1275                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_64, FALSE);
1276   g_object_set_data (G_OBJECT (window), "menu_grid_64", item);
1277   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid128",
1278                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_128, FALSE);
1279   g_object_set_data (G_OBJECT (window), "menu_grid_128", item);
1280   item = create_radio_menu_item_with_mnemonic (menu, item, "Grid256",
1281                                  GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_256, FALSE);
1282   g_object_set_data (G_OBJECT (window), "menu_grid_256", item);
1283   menu_separator (menu);
1284   item = create_check_menu_item_with_mnemonic (menu, "Snap to grid",
1285                                  GTK_SIGNAL_FUNC (HandleCommand), ID_SNAPTOGRID, TRUE);
1286   g_object_set_data (G_OBJECT (window), "menu_snaptogrid", item);
1287
1288   // Textures menu
1289   menu = create_sub_menu_with_mnemonic (menu_bar, "_Textures");
1290   if (g_PrefsDlg.m_bDetachableMenus)
1291     menu_tearoff (menu);
1292
1293   item = create_check_menu_item_with_mnemonic (menu, "Show In _Use",
1294                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_SHOWINUSE, FALSE);
1295   g_object_set_data (G_OBJECT (window), "menu_textures_showinuse", item);
1296   item = create_check_menu_item_with_mnemonic (menu, "Show _All",
1297                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_SHOWALL, FALSE);
1298   g_object_set_data (G_OBJECT (window), "menu_textures_showall", item);
1299   menu_separator (menu);
1300   item = create_check_menu_item_with_mnemonic (menu, "Show shaders",
1301                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_SHADERS_SHOW, FALSE);
1302   g_object_set_data (G_OBJECT (window), "menu_textures_shaders_show", item);
1303   item = create_menu_item_with_mnemonic (menu, "Flush & Reload Shaders",
1304                            GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_RELOADSHADERS);
1305   g_object_set_data (G_OBJECT (window), "menu_textures_reloadshaders", item);
1306   item = create_menu_item_with_mnemonic (menu, "Load directory...",
1307                            GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_LOAD);
1308   g_object_set_data (G_OBJECT (window), "menu_textures_load", item);
1309   item = create_menu_item_with_mnemonic (menu, "Directory list...",
1310                            GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_LOADLIST);
1311   menu_separator (menu);
1312
1313   item = create_menu_item_with_mnemonic (menu, "_Surface Inspector",
1314                            GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_INSPECTOR);
1315   menu_separator (menu);
1316   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Render Quality");
1317   g_object_set_data (G_OBJECT (window), "render_quality_menu", menu_in_menu);
1318   item = create_radio_menu_item_with_mnemonic (menu_in_menu, NULL, "_Wireframe",
1319                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_WIREFRAME, FALSE);
1320   g_object_set_data (G_OBJECT (window), "menu_textures_wireframe", item);
1321   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "_Flat shade",
1322                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_FLATSHADE, FALSE);
1323   g_object_set_data (G_OBJECT (window), "menu_textures_flatshade", item);
1324   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "_Nearest",
1325                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_NEAREST, FALSE);
1326   g_object_set_data (G_OBJECT (window), "menu_view_nearest", item);
1327   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "Nearest _Mipmap",
1328                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_NEARESTMIPMAP, FALSE);
1329   g_object_set_data (G_OBJECT (window), "menu_view_nearestmipmap", item);
1330   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "_Linear",
1331                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_LINEAR, FALSE);
1332   g_object_set_data (G_OBJECT (window), "menu_view_linear", item);
1333   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "_Bilinear",
1334                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_BILINEAR, FALSE);
1335   g_object_set_data (G_OBJECT (window), "menu_view_bilinear", item);
1336   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "B_ilinear Mipmap",
1337                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_BILINEARMIPMAP, FALSE);
1338   g_object_set_data (G_OBJECT (window), "menu_view_bilinearmipmap", item);
1339   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "T_rilinear",
1340                                  GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_TRILINEAR, FALSE);
1341   g_object_set_data (G_OBJECT (window), "menu_view_trilinear", item);
1342   create_menu_item_with_mnemonic (menu, "Find / Replace...",
1343                     GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURE_REPLACEALL);
1344
1345   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Texture Lock");
1346   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Moves",
1347                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLE_LOCK, TRUE);
1348   g_object_set_data (G_OBJECT (window), "menu_toggle_lock", item);
1349   item = create_check_menu_item_with_mnemonic (menu_in_menu, "Rotations",
1350                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TOGGLE_ROTATELOCK, TRUE);
1351   g_object_set_data (G_OBJECT (window), "menu_toggle_rotatelock", item);
1352   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Texture Window Scale");
1353   item = create_radio_menu_item_with_mnemonic (menu_in_menu, NULL, "200%",
1354                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_200, FALSE);
1355   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_200", item);
1356   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "100%",
1357                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_100, FALSE);
1358   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_100", item);
1359   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "50%",
1360                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_50, FALSE);
1361   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_50", item);
1362   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "25%",
1363                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_25, FALSE);
1364   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_25", item);
1365   item = create_radio_menu_item_with_mnemonic (menu_in_menu, item, "10%",
1366                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_TEXTUREWINDOWSCALE_10, FALSE);
1367   g_object_set_data (G_OBJECT (window), "menu_textures_texturewindowscale_10", item);
1368   item = menu_separator (menu);
1369   item = create_check_menu_item_with_mnemonic (menu, "shaderlist.txt only",
1370                                  GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTURES_SHADERLISTONLY, FALSE);
1371   g_object_set_data (G_OBJECT (window), "menu_textures_shaderlistonly", item);
1372   item = menu_separator (menu);
1373   g_object_set_data (G_OBJECT (window), "menu_textures_separator", item);
1374   g_object_set_data (G_OBJECT (window), "menu_textures", menu);
1375
1376   // Misc menu
1377   menu = create_sub_menu_with_mnemonic (menu_bar, "_Misc");
1378   if (g_PrefsDlg.m_bDetachableMenus)
1379     menu_tearoff (menu);
1380
1381   create_menu_item_with_mnemonic (menu, "_Benchmark", GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_BENCHMARK);
1382   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Colors");
1383   menu_3 = create_menu_in_menu_with_mnemonic (menu_in_menu, "Themes");
1384   create_menu_item_with_mnemonic (menu_3, "QE4 Original", GTK_SIGNAL_FUNC (HandleCommand), ID_COLOR_SETORIGINAL);
1385   create_menu_item_with_mnemonic (menu_3, "Q3Radiant Original", GTK_SIGNAL_FUNC (HandleCommand), ID_COLOR_SETQER);
1386   create_menu_item_with_mnemonic (menu_3, "Black and Green", GTK_SIGNAL_FUNC (HandleCommand), ID_COLOR_SETBLACK);
1387   create_menu_item_with_mnemonic (menu_3, "Maya/Max/Lightwave Emulation", GTK_SIGNAL_FUNC (HandleCommand), ID_COLOR_SETYDNAR);
1388
1389   menu_separator (menu_in_menu);
1390   create_menu_item_with_mnemonic (menu_in_menu, "_Texture Background...",
1391                     GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTUREBK);
1392   create_menu_item_with_mnemonic (menu_in_menu, "Grid Background...",
1393                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_XYBK);
1394   create_menu_item_with_mnemonic (menu_in_menu, "Grid Major...",
1395                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_MAJOR);
1396   create_menu_item_with_mnemonic (menu_in_menu, "Grid Minor...",
1397                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_MINOR);
1398   create_menu_item_with_mnemonic (menu_in_menu, "Grid Major Small...",
1399                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_MAJOR_ALT);
1400   create_menu_item_with_mnemonic (menu_in_menu, "Grid Minor Small...",
1401                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_MINOR_ALT);
1402   create_menu_item_with_mnemonic (menu_in_menu, "Grid Text...",
1403                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_GRIDTEXT);
1404   create_menu_item_with_mnemonic (menu_in_menu, "Grid Block...",
1405                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_GRIDBLOCK);
1406   create_menu_item_with_mnemonic (menu_in_menu, "Default Brush...",
1407                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_BRUSH);
1408   create_menu_item_with_mnemonic (menu_in_menu, "Camera Background...",
1409                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_CAMERABACK);
1410   create_menu_item_with_mnemonic (menu_in_menu, "Selected Brush...",
1411                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_SELECTEDBRUSH);
1412   create_menu_item_with_mnemonic (menu_in_menu, "Selected Brush (Camera)...",
1413                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_SELECTEDBRUSH3D);
1414   create_menu_item_with_mnemonic (menu_in_menu, "Clipper...",
1415                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_CLIPPER);
1416   create_menu_item_with_mnemonic (menu_in_menu, "Active View name...",
1417                     GTK_SIGNAL_FUNC (HandleCommand), ID_COLORS_VIEWNAME);
1418
1419   create_menu_item_with_mnemonic (menu, "_Gamma...",
1420                     GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_GAMMA);
1421   create_menu_item_with_mnemonic (menu, "Find brush...",
1422                     GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_FINDBRUSH);
1423   item = create_menu_item_with_mnemonic (menu, "Next leak spot",
1424                            GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_NEXTLEAKSPOT);
1425   item = create_menu_item_with_mnemonic (menu, "Previous leak spot",
1426                            GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_PREVIOUSLEAKSPOT);
1427   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394
1428 //  create_menu_item_with_mnemonic (menu, "_Print XY View", GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_PRINTXY);
1429   item = create_menu_item_with_mnemonic (menu, "_Select Entity Color...",
1430                            GTK_SIGNAL_FUNC (HandleCommand), ID_MISC_SELECTENTITYCOLOR);
1431   g_object_set_data (G_OBJECT (window), "menu_misc_selectentitycolor", item);
1432
1433   // Region menu
1434   menu = create_sub_menu_with_mnemonic (menu_bar, "_Region");
1435   if (g_PrefsDlg.m_bDetachableMenus)
1436     menu_tearoff (menu);
1437
1438   create_menu_item_with_mnemonic (menu, "_Off",
1439                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_OFF);
1440   create_menu_item_with_mnemonic (menu, "_Set XY",
1441                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_SETXY);
1442   create_menu_item_with_mnemonic (menu, "Set _Tall Brush",
1443                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_SETTALLBRUSH);
1444   create_menu_item_with_mnemonic (menu, "Set _Brush",
1445                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_SETBRUSH);
1446   create_menu_item_with_mnemonic (menu, "Set Se_lected Brushes",
1447                     GTK_SIGNAL_FUNC (HandleCommand), ID_REGION_SETSELECTION);
1448
1449   // Brush menu
1450   menu = create_sub_menu_with_mnemonic (menu_bar, "_Brush");
1451   if (g_PrefsDlg.m_bDetachableMenus)
1452     menu_tearoff (menu);
1453
1454   item = create_menu_item_with_mnemonic (menu, "3 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_3SIDED);
1455   item = create_menu_item_with_mnemonic (menu, "4 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_4SIDED);
1456   item = create_menu_item_with_mnemonic (menu, "5 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_5SIDED);
1457   item = create_menu_item_with_mnemonic (menu, "6 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_6SIDED);
1458   item = create_menu_item_with_mnemonic (menu, "7 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_7SIDED);
1459   item = create_menu_item_with_mnemonic (menu, "8 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_8SIDED);
1460   item = create_menu_item_with_mnemonic (menu, "9 sided", GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_9SIDED);
1461   menu_separator (menu);
1462   create_menu_item_with_mnemonic (menu, "Arbitrary sided...",
1463                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_ARBITRARYSIDED);
1464   menu_separator (menu);
1465   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Primitives");
1466   create_menu_item_with_mnemonic (menu_in_menu, "Cone...",
1467                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_MAKECONE);
1468   create_menu_item_with_mnemonic (menu_in_menu, "Sphere...",
1469                     GTK_SIGNAL_FUNC (HandleCommand), ID_BRUSH_PRIMITIVES_SPHERE);
1470
1471   // Curve menu
1472   if (!g_pGameDescription->mNoPatch)
1473   {
1474   menu = create_sub_menu_with_mnemonic (menu_bar, "_Curve");
1475   if (g_PrefsDlg.m_bDetachableMenus)
1476     menu_tearoff (menu);
1477
1478   create_menu_item_with_mnemonic (menu, "Cylinder", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHTUBE);
1479   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "More Cylinders");
1480   create_menu_item_with_mnemonic (menu_in_menu, "Dense Cylinder",
1481                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHDENSETUBE);
1482   create_menu_item_with_mnemonic (menu_in_menu, "Very Dense Cylinder",
1483                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHVERYDENSETUBE);
1484   create_menu_item_with_mnemonic (menu_in_menu, "Square Cylinder",
1485                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHSQUARE);
1486   menu_separator (menu);
1487   create_menu_item_with_mnemonic (menu, "End cap", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHENDCAP);
1488   create_menu_item_with_mnemonic (menu, "Bevel", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHBEVEL);
1489   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "More End caps, Bevels");
1490   create_menu_item_with_mnemonic (menu_in_menu, "Square Endcap",
1491                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_MOREENDCAPSBEVELS_SQUAREBEVEL);
1492   create_menu_item_with_mnemonic (menu_in_menu, "Square Bevel",
1493                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_MOREENDCAPSBEVELS_SQUAREENDCAP);
1494   menu_separator (menu);
1495   create_menu_item_with_mnemonic (menu, "Cone", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PATCHCONE);
1496   item = create_menu_item_with_mnemonic (menu, "Sphere",
1497                            GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_PRIMITIVES_SPHERE);
1498   gtk_widget_set_sensitive (item, FALSE);
1499   menu_separator (menu);
1500   item = create_menu_item_with_mnemonic (menu, "Simple Patch Mesh...",
1501                            GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_SIMPLEPATCHMESH);
1502   g_object_set_data (G_OBJECT (window), "menu_simplepatchmesh", item);
1503   menu_separator (menu);
1504   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Insert");
1505   create_menu_item_with_mnemonic (menu_in_menu, "Insert (2) Columns",
1506                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERT_INSERTCOLUMN);
1507   create_menu_item_with_mnemonic (menu_in_menu, "Add (2) Columns",
1508                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERT_ADDCOLUMN);
1509   menu_separator (menu_in_menu);
1510   create_menu_item_with_mnemonic (menu_in_menu, "Insert (2) Rows",
1511                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERT_INSERTROW);
1512   create_menu_item_with_mnemonic (menu_in_menu, "Add (2) Rows",
1513                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERT_ADDROW);
1514   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Delete");
1515   create_menu_item_with_mnemonic (menu_in_menu, "First (2) Columns",
1516                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETE_FIRSTCOLUMN);
1517   create_menu_item_with_mnemonic (menu_in_menu, "Last (2) Columns",
1518                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETE_LASTCOLUMN);
1519   menu_separator (menu_in_menu);
1520   create_menu_item_with_mnemonic (menu_in_menu, "First (2) Rows",
1521                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETE_FIRSTROW);
1522   create_menu_item_with_mnemonic (menu_in_menu, "Last (2) Rows",
1523                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETE_LASTROW);
1524   menu_separator (menu);
1525   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Matrix");
1526   create_menu_item_with_mnemonic (menu_in_menu, "Invert",
1527                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_NEGATIVE);
1528   menu_3 = create_menu_in_menu_with_mnemonic (menu_in_menu, "Re-disperse");
1529   create_menu_item_with_mnemonic (menu_3, "Rows", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_REDISPERSE_ROWS);
1530   create_menu_item_with_mnemonic (menu_3, "Cols (Intermediate)", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_REDISPERSE_INTERMEDIATE_COLS);
1531   create_menu_item_with_mnemonic (menu_3, "Rows (Intermediate)", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_REDISPERSE_INTERMEDIATE_ROWS);
1532   create_menu_item_with_mnemonic (menu_in_menu, "Transpose",
1533                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_MATRIX_TRANSPOSE);
1534   menu_separator (menu);
1535   create_menu_item_with_mnemonic (menu, "Cap Selection",
1536                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_CAP);
1537   create_menu_item_with_mnemonic (menu, "Cycle Cap Texture",
1538                         GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_CYCLECAP);
1539   menu_separator (menu);
1540   menu_in_menu = create_menu_in_menu_with_mnemonic (menu, "Overlay");
1541   create_menu_item_with_mnemonic (menu_in_menu, "Set",
1542                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_OVERLAY_SET);
1543   create_menu_item_with_mnemonic (menu_in_menu, "Clear",
1544                     GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_OVERLAY_CLEAR);
1545   menu_separator (menu);
1546   create_menu_item_with_mnemonic (menu, "Thicken...", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_THICKEN);
1547   }
1548   // Plugins menu
1549   menu = create_sub_menu_with_mnemonic (menu_bar, "_Plugins");
1550   if (g_PrefsDlg.m_bDetachableMenus)
1551     menu_tearoff (menu);
1552
1553   /*
1554   create_menu_item_with_mnemonic (menu, "Refresh", GTK_SIGNAL_FUNC (HandleCommand), ID_PLUGINS_REFRESH);
1555   */
1556   // NOTE: the seperator is used when doing a refresh of the list, everything past the seperator is removed
1557   item = menu_separator (menu);
1558   g_object_set_data (G_OBJECT (window), "menu_plugin_separator", item);
1559   g_object_set_data (G_OBJECT (window), "menu_plugin", menu);
1560
1561   // Help menu
1562   menu = create_sub_menu_with_mnemonic (menu_bar, "_Help");
1563   if (g_PrefsDlg.m_bDetachableMenus)
1564     menu_tearoff (menu);
1565
1566   item = create_menu_item_with_mnemonic (menu, "Manual",
1567                            GTK_SIGNAL_FUNC (HandleCommand), ID_HELP);
1568   gtk_widget_add_accelerator (item, "activate", accel, GDK_F1, (GdkModifierType)0, GTK_ACCEL_VISIBLE);
1569
1570   // this creates all the per-game drop downs for the game pack helps
1571   // it will take care of hooking the Sys_OpenURL calls etc.
1572   create_game_help_menu(menu, accel);
1573
1574   // TTimo: this is in global.xlink now
1575   //create_menu_item_with_mnemonic (menu, "Links",
1576   //                  GTK_SIGNAL_FUNC (HandleCommand), ID_HELP_LINKS);
1577   create_menu_item_with_mnemonic (menu, "Bug report",
1578                     GTK_SIGNAL_FUNC (HandleCommand), ID_HELP_BUGREPORT);
1579   create_menu_item_with_mnemonic (menu, "Shortcuts list",
1580                     GTK_SIGNAL_FUNC (HandleCommand), ID_HELP_COMMANDLIST);
1581   create_menu_item_with_mnemonic (menu, "_About",
1582                     GTK_SIGNAL_FUNC (HandleCommand), ID_HELP_ABOUT);
1583
1584
1585   // leo: Hidden menu to make the accelerators work,
1586   // this is a hack that needs to be changed later if someone has a better idea.
1587   // NOTE TTimo
1588   // maybe the better idea would be NOT to use any such accelerator scheme and do all key listening and interpret ourselves
1589   menu = create_sub_menu_with_mnemonic (menu_bar, "Hidden");
1590   if (g_PrefsDlg.m_bDetachableMenus)
1591     menu_tearoff (menu);
1592
1593   gtk_widget_hide (gtk_menu_get_attach_widget (GTK_MENU (menu)));
1594
1595   create_menu_item_with_mnemonic (menu, "BendMode", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_BEND);
1596   create_menu_item_with_mnemonic (menu, "FitTexture", GTK_SIGNAL_FUNC (HandleCommand), IDC_BTN_FACEFIT);
1597   create_menu_item_with_mnemonic (menu, "ViewTextures", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_TEXTURE);
1598   create_menu_item_with_mnemonic (menu, "PatchInspector", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_INSPECTOR);
1599   create_menu_item_with_mnemonic (menu, "InvertCurveTextureX", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_NEGATIVETEXTUREY);
1600   create_menu_item_with_mnemonic (menu, "InvertCurveTextureY", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_NEGATIVETEXTUREX);
1601   create_menu_item_with_mnemonic (menu, "IncPatchColumn", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERTCOLUMN);
1602   create_menu_item_with_mnemonic (menu, "IncPatchRow", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_INSERTROW);
1603   create_menu_item_with_mnemonic (menu, "DecPatchColumn", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETECOLUMN);
1604   create_menu_item_with_mnemonic (menu, "DecPatchRow", GTK_SIGNAL_FUNC (HandleCommand), ID_CURVE_DELETEROW);
1605   create_menu_item_with_mnemonic (menu, "Patch TAB", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_TAB);
1606   create_menu_item_with_mnemonic (menu, "Patch TAB", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_TAB);
1607   create_menu_item_with_mnemonic (menu, "SelectNudgeDown", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGEDOWN);
1608   create_menu_item_with_mnemonic (menu, "CameraForward", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_FORWARD);
1609   create_menu_item_with_mnemonic (menu, "CameraBack", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_BACK);
1610   create_menu_item_with_mnemonic (menu, "CameraLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_LEFT);
1611   create_menu_item_with_mnemonic (menu, "CameraRight", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_RIGHT);
1612   create_menu_item_with_mnemonic (menu, "CameraUp", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_UP);
1613   create_menu_item_with_mnemonic (menu, "CameraDown", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_DOWN);
1614   create_menu_item_with_mnemonic (menu, "CameraAngleUp", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_ANGLEUP);
1615   create_menu_item_with_mnemonic (menu, "CameraAngleDown", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_ANGLEDOWN);
1616   create_menu_item_with_mnemonic (menu, "CameraStrafeRight", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_STRAFERIGHT);
1617   create_menu_item_with_mnemonic (menu, "CameraStrafeLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_CAMERA_STRAFELEFT);
1618   create_menu_item_with_mnemonic (menu, "ToggleGrid", GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_TOGGLE);
1619   create_menu_item_with_mnemonic (menu, "ToggleCrosshairs", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CROSSHAIR);
1620   create_menu_item_with_mnemonic (menu, "ToggleRealtime", GTK_SIGNAL_FUNC (HandleCommand), ID_VIEW_CAMERAUPDATE);
1621   create_menu_item_with_mnemonic (menu, "MouseRotate", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECT_MOUSEROTATE);
1622   create_menu_item_with_mnemonic (menu, "TexRotateClock", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_ROTATECLOCK);
1623   create_menu_item_with_mnemonic (menu, "TexRotateCounter", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_ROTATECOUNTER);
1624   create_menu_item_with_mnemonic (menu, "TexScaleUp", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SCALEUP);
1625   create_menu_item_with_mnemonic (menu, "TexScaleDown", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SCALEDOWN);
1626   create_menu_item_with_mnemonic (menu, "TexShiftLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SHIFTLEFT);
1627   create_menu_item_with_mnemonic (menu, "TexShiftRight", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SHIFTRIGHT);
1628   create_menu_item_with_mnemonic (menu, "TexShiftUp", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SHIFTUP);
1629   create_menu_item_with_mnemonic (menu, "TexShiftDown", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SHIFTDOWN);
1630   create_menu_item_with_mnemonic (menu, "GridDown", GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_PREV);
1631   create_menu_item_with_mnemonic (menu, "GridUp", GTK_SIGNAL_FUNC (HandleCommand), ID_GRID_NEXT);
1632   create_menu_item_with_mnemonic (menu, "TexScaleLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SCALELEFT);
1633   create_menu_item_with_mnemonic (menu, "TexScaleRight", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TEXTURE_SCALERIGHT);
1634   create_menu_item_with_mnemonic (menu, "MoveSelectionDOWN", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MOVEDOWN);
1635   create_menu_item_with_mnemonic (menu, "MoveSelectionUP", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_MOVEUP);
1636   create_menu_item_with_mnemonic (menu, "DumpSelectedBrush", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_PRINT);
1637   create_menu_item_with_mnemonic (menu, "ToggleSizePaint", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_TOGGLESIZEPAINT);
1638   create_menu_item_with_mnemonic (menu, "SelectNudgeLeft", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGELEFT);
1639   create_menu_item_with_mnemonic (menu, "SelectNudgeRight", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGERIGHT);
1640   create_menu_item_with_mnemonic (menu, "SelectNudgeUp", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_SELECT_NUDGEUP);
1641   create_menu_item_with_mnemonic (menu, "NaturalizePatch", GTK_SIGNAL_FUNC (HandleCommand), ID_PATCH_NATURALIZE);
1642   create_menu_item_with_mnemonic (menu, "SnapPatchToGrid", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECT_SNAPTOGRID);
1643   create_menu_item_with_mnemonic (menu, "SelectAllOfType", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECT_ALL);
1644   create_menu_item_with_mnemonic (menu, "CycleOutlineStyle", GTK_SIGNAL_FUNC (HandleCommand), ID_SELECTION_OUTLINESTYLE);
1645   create_menu_item_with_mnemonic (menu, "TextureWindowScaleup", GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTUREWINDOW_SCALEUP);
1646   create_menu_item_with_mnemonic (menu, "TextureWindowScaledown", GTK_SIGNAL_FUNC (HandleCommand), ID_TEXTUREWINDOW_SCALEDOWN);
1647
1648   g_bIgnoreCommands--;
1649 }
1650
1651 void MainFrame::create_main_toolbar (GtkWidget *window, GtkWidget *vbox)
1652 {
1653   GtkWidget *handle_box, *toolbar, *w;
1654
1655   handle_box = gtk_handle_box_new ();
1656   gtk_box_pack_start (GTK_BOX (vbox), handle_box, FALSE, FALSE, 0);
1657   gtk_widget_show (handle_box);
1658   g_object_set_data (G_OBJECT (window), "tb_handle_box", handle_box);
1659
1660   toolbar = gtk_toolbar_new ();
1661   gtk_toolbar_set_orientation (GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1662   gtk_toolbar_set_style (GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
1663   //  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), user_rc.toolbar_style);
1664   gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
1665
1666   gtk_widget_show (toolbar);
1667
1668   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "Open", "Open an existing map", "",
1669                                new_pixmap (window, "file_open.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1670                                GINT_TO_POINTER (ID_FILE_OPEN));
1671   g_object_set_data (G_OBJECT (window), "tb_file_open", w);
1672   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "Save", "Save the active map", "",
1673                                new_pixmap (window, "file_save.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1674                                GINT_TO_POINTER (ID_FILE_SAVE));
1675   g_object_set_data (G_OBJECT (window), "tb_file_save", w);
1676   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1677   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "x-axis Flip", "",
1678                                new_pixmap (window, "brush_flipx.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1679                                GINT_TO_POINTER (ID_BRUSH_FLIPX));
1680   g_object_set_data (G_OBJECT (window), "tb_brush_flipx", w);
1681   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "x-axis Rotate", "",
1682                                new_pixmap (window, "brush_rotatex.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1683                                GINT_TO_POINTER (ID_BRUSH_ROTATEX));
1684   g_object_set_data (G_OBJECT (window), "tb_brush_rotatex", w);
1685   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "y-axis Flip", "",
1686                                new_pixmap (window, "brush_flipy.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1687                                GINT_TO_POINTER (ID_BRUSH_FLIPY));
1688   g_object_set_data (G_OBJECT (window), "tb_brush_flipy", w);
1689   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "y-axis Rotate", "",
1690                                new_pixmap (window, "brush_rotatey.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1691                                GINT_TO_POINTER (ID_BRUSH_ROTATEY));
1692   g_object_set_data (G_OBJECT (window), "tb_brush_rotatey", w);
1693   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "z-axis Flip", "",
1694                                new_pixmap (window, "brush_flipz.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1695                                GINT_TO_POINTER (ID_BRUSH_FLIPZ));
1696   g_object_set_data (G_OBJECT (window), "tb_brush_flipz", w);
1697   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "z-axis Rotate", "",
1698                                new_pixmap (window, "brush_rotatez.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1699                                GINT_TO_POINTER (ID_BRUSH_ROTATEZ));
1700   g_object_set_data (G_OBJECT (window), "tb_brush_rotatez", w);
1701   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1702
1703   if (g_PrefsDlg.m_bWideToolbar)
1704   {
1705     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Complete Tall", "",
1706                                  new_pixmap (window, "selection_selectcompletetall.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1707                                  GINT_TO_POINTER (ID_SELECTION_SELECTCOMPLETETALL));
1708     g_object_set_data (G_OBJECT (window), "tb_selection_selectcompletetall", w);
1709     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Select Touching", "",
1710                                  new_pixmap (window, "selection_selecttouching.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1711                                  GINT_TO_POINTER (ID_SELECTION_SELECTTOUCHING));
1712     g_object_set_data (G_OBJECT (window), "tb_selection_selecttouching", w);
1713     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Select Partial Tall", "",
1714                                  new_pixmap (window, "selection_selectpartialtall.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1715                                  GINT_TO_POINTER (ID_SELECTION_SELECTPARTIALTALL));
1716     g_object_set_data (G_OBJECT (window), "tb_selection_selectpartialtall", w);
1717     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Select Inside", "",
1718                                  new_pixmap (window, "selection_selectinside.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1719                                  GINT_TO_POINTER (ID_SELECTION_SELECTINSIDE));
1720     g_object_set_data (G_OBJECT (window), "tb_selection_selectinside", w);
1721   } else
1722   {
1723     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Selection", "",
1724                                  new_pixmap (window, "popup_selection.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1725                                  GINT_TO_POINTER (ID_POPUP_SELECTION));
1726     g_object_set_data (G_OBJECT (window), "tb_popup_selection", w);
1727   }
1728   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1729
1730   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "CSG Subtract", "",
1731                                new_pixmap (window, "selection_csgsubtract.bmp"),
1732                                GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECTION_CSGSUBTRACT));
1733   g_object_set_data (G_OBJECT (window), "tb_selection_csgsubtract", w);
1734
1735   if (g_PrefsDlg.m_bWideToolbar)
1736   {
1737     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "CSG Merge", "",
1738                                  new_pixmap (window, "selection_csgmerge.bmp"),
1739                                  GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECTION_CSGMERGE));
1740     g_object_set_data (G_OBJECT (window), "tb_selection_csgmerge", w);
1741   }
1742
1743   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Hollow", "",
1744                                new_pixmap (window, "selection_makehollow.bmp"),
1745                                GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECTION_MAKEHOLLOW));
1746   g_object_set_data (G_OBJECT (window), "tb_selection_makehollow", w);
1747
1748   if (g_PrefsDlg.m_bWideToolbar)
1749   {
1750     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1751                                     "", "Clipper", "", new_pixmap (window, "view_clipper.bmp"),
1752                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CLIPPER));
1753     g_object_set_data (G_OBJECT (window), "tb_view_clipper", w);
1754   }
1755
1756   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1757
1758   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Change views", "",
1759                                new_pixmap (window, "view_change.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1760                                GINT_TO_POINTER (ID_VIEW_CHANGE));
1761   g_object_set_data (G_OBJECT (window), "tb_view_change", w);
1762
1763   if (!g_PrefsDlg.m_bWideToolbar)
1764   {
1765     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1766   }
1767
1768   w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Texture view mode", "",
1769                                new_pixmap (window, "textures_popup.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1770                                GINT_TO_POINTER (ID_TEXTURES_POPUP));
1771   g_object_set_data (G_OBJECT (window), "tb_textures_popup", w);
1772
1773   if (g_PrefsDlg.m_bWideToolbar)
1774   {
1775     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1776                                     "", "Cubic clip the camera view", "",
1777                                     new_pixmap (window, "view_cubicclipping.bmp"),
1778                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CUBICCLIPPING));
1779     g_object_set_data (G_OBJECT (window), "tb_view_cubicclipping", w);
1780   }
1781
1782   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1783
1784   if (!g_PrefsDlg.m_bWideToolbar)
1785   {
1786     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1787                                 "", "Camera preview", "", new_pixmap (window, "view_cameratoggle.bmp"),
1788                                 GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CAMERATOGGLE));
1789     g_object_set_data (G_OBJECT (window), "tb_view_cameratoggle", w);
1790     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Update Camera", "",
1791                              new_pixmap (window, "view_cameraupdate.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1792                              GINT_TO_POINTER (ID_VIEW_CAMERAUPDATE));
1793     g_object_set_data (G_OBJECT (window), "tb_view_cameraupdate", w);
1794     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1795                                 "", "Cubic clip the camera view", "",
1796                                 new_pixmap (window, "view_cubicclipping.bmp"),
1797                                 GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CUBICCLIPPING));
1798     g_object_set_data (G_OBJECT (window), "tb_view_cubicclipping", w);
1799     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1800     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1801                                     "", "Entity inspector", "", new_pixmap (window, "view_entity.bmp"),
1802                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_ENTITY));
1803     g_object_set_data (G_OBJECT (window), "tb_view_entity", w);
1804     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1805     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1806                                     "", "Clipper", "", new_pixmap (window, "view_clipper.bmp"),
1807                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_VIEW_CLIPPER));
1808     g_object_set_data (G_OBJECT (window), "tb_view_clipper", w);
1809     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1810   }
1811
1812   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1813                               "", "Free Rotation", "", new_pixmap (window, "select_mouserotate.bmp"),
1814                               GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECT_MOUSEROTATE));
1815   g_object_set_data (G_OBJECT (window), "tb_select_mouserotate", w);
1816   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1817   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1818                               "", "Free Scaling", "", new_pixmap (window, "select_mousescale.bmp"),
1819                               GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SELECT_MOUSESCALE));
1820   g_object_set_data (G_OBJECT (window), "tb_select_mousescale", w);
1821   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1822                                   "", "Scale X", "", new_pixmap (window, "scalelockx.bmp"),
1823                                   GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SCALELOCKX));
1824   g_object_set_data (G_OBJECT (window), "tb_scalelockx", w);
1825   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1826                                   "", "Scale Y", "", new_pixmap (window, "scalelocky.bmp"),
1827                                   GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SCALELOCKY));
1828   g_object_set_data (G_OBJECT (window), "tb_scalelocky", w);
1829   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1830                                   "", "Scale Z", "", new_pixmap (window, "scalelockz.bmp"),
1831                                   GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_SCALELOCKZ));
1832   g_object_set_data (G_OBJECT (window), "tb_scalelockz", w);
1833
1834   if (g_PrefsDlg.m_bWideToolbar)
1835   {
1836     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1837     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1838                              "", "Don't select model brushes", "",
1839                              new_pixmap (window, "dontselectmodel.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1840                              GINT_TO_POINTER (ID_DONTSELECTMODEL));
1841     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1842     g_object_set_data (G_OBJECT (window), "tb_dontselectmodel", w);
1843
1844     if (!g_pGameDescription->mNoPatch)
1845     {
1846       w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1847                              "", "Don't select curved brushes", "",
1848                              new_pixmap (window, "dontselectcurve.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1849                              GINT_TO_POINTER (ID_DONTSELECTCURVE));
1850       g_object_set_data (G_OBJECT (window), "tb_dontselectcurve", w);
1851     }
1852   }
1853
1854   // bug #292, patch toolbar option
1855   if (g_PrefsDlg.m_bPatchToolbar)
1856   {
1857     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1858                              "", "Show patch bounding box", "",
1859                              new_pixmap (window, "patch_showboundingbox.bmp"),
1860                              GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_PATCH_SHOWBOUNDINGBOX));
1861     g_object_set_data (G_OBJECT (window), "tb_patch_showboundingbox", w);
1862     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1863                                     "", "Show patches as wireframes", "",
1864                                     new_pixmap (window, "patch_wireframe.bmp"),
1865                                     GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (ID_PATCH_WIREFRAME));
1866     g_object_set_data (G_OBJECT (window), "tb_patch_wireframe", w);
1867     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1868                              "", "Patch Bend mode", "",
1869                              new_pixmap (window, "patch_bend.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1870                              GINT_TO_POINTER (ID_PATCH_BEND));
1871     g_object_set_data (G_OBJECT (window), "tb_patch_bend", w);
1872     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Put caps on the current patch", "",
1873                              new_pixmap (window, "curve_cap.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1874                              GINT_TO_POINTER (ID_CURVE_CAP));
1875     g_object_set_data (G_OBJECT (window), "tb_curve_cap", w);
1876     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1877                                  "", "Welds equal patch points during moves", "",
1878                                  new_pixmap (window, "patch_weld.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1879                                  GINT_TO_POINTER (ID_PATCH_WELD));
1880     g_object_set_data (G_OBJECT (window), "tb_patch_weld", w);
1881     w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL,
1882                              "", "Selects drill down rows and columns", "",
1883                              new_pixmap (window, "patch_drilldown.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1884                              GINT_TO_POINTER (ID_PATCH_DRILLDOWN));
1885     g_object_set_data (G_OBJECT (window), "tb_patch_drilldown", w);
1886   }
1887
1888   if (g_PrefsDlg.m_bWideToolbar)
1889   {
1890     gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1891     w = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "", "Show Entities as", "",
1892                              new_pixmap (window, "show_entities.bmp"), GTK_SIGNAL_FUNC (HandleCommand),
1893                              GINT_TO_POINTER (ID_SHOW_ENTITIES));
1894     g_object_set_data (G_OBJECT (window), "tb_show_entities", w);
1895   }
1896
1897   /*
1898   uh? that is OLD
1899 #ifndef QUAKE3
1900   w = g_object_get_data (G_OBJECT (window), "tb_dontselectcurve");
1901   gtk_widget_hide (w);
1902   w = g_object_get_data (G_OBJECT (window), "tb_patch_showboundingbox");
1903   gtk_widget_hide (w);
1904   w = g_object_get_data (G_OBJECT (window), "tb_patch_weld");
1905   gtk_widget_hide (w);
1906   w = g_object_get_data (G_OBJECT (window), "tb_patch_wireframe");
1907   gtk_widget_hide (w);
1908 #endif
1909   */
1910
1911   m_bCamPreview = true;
1912   g_nScaleHow = (SCALE_X | SCALE_Y | SCALE_Z);
1913 }
1914
1915 void MainFrame::create_plugin_toolbar (GtkWidget *window, GtkWidget *vbox)
1916 {
1917   GtkWidget *handle_box, *toolbar;
1918
1919   handle_box = gtk_handle_box_new ();
1920   gtk_box_pack_start (GTK_BOX (vbox), handle_box, FALSE, FALSE, 0);
1921   if (g_PrefsDlg.m_bPluginToolbar)
1922     gtk_widget_show (handle_box);
1923   g_object_set_data (G_OBJECT (window), "tb_handle_box", handle_box);
1924
1925   toolbar = gtk_toolbar_new();
1926   gtk_toolbar_set_orientation (GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL);
1927   gtk_toolbar_set_style (GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
1928   //  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), user_rc.toolbar_style);
1929   gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
1930   g_object_set_data (G_OBJECT (window), "toolbar_plugin", toolbar);
1931   gtk_widget_show (toolbar);
1932 }
1933
1934 void MainFrame::create_main_statusbar (GtkWidget *window, GtkWidget *vbox)
1935 {
1936   GtkWidget *hbox, *hbox1;
1937   GtkWidget *frame;
1938   GtkWidget *label;
1939
1940   hbox = gtk_hbox_new (FALSE, 0);
1941   gtk_widget_show (hbox);
1942   gtk_widget_set_usize (hbox, -1, 24);
1943   gtk_container_border_width (GTK_CONTAINER (hbox), 1);
1944   gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, TRUE, 2);
1945
1946   frame = gtk_frame_new ((char*)NULL);
1947   gtk_widget_show (frame);
1948   gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1949   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1950
1951   hbox1 = gtk_hbox_new (FALSE, 0);
1952   gtk_container_add (GTK_CONTAINER (frame), hbox1);
1953   gtk_container_border_width (GTK_CONTAINER (hbox1), 0);
1954   gtk_widget_show (hbox1);
1955
1956   label = gtk_label_new (" Label ");
1957   gtk_widget_show (label);
1958   gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, TRUE, 0);
1959   gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1960   gtk_misc_set_padding (GTK_MISC (label), 3, 0);
1961   m_pStatusLabel[0] = label;
1962
1963   for (int i = 1; i < 6; i++)
1964   {
1965     frame = gtk_frame_new ((char*)NULL);
1966     gtk_widget_show (frame);
1967     gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
1968     gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1969
1970     label = gtk_label_new (" Label ");
1971     gtk_widget_show (label);
1972     gtk_container_add (GTK_CONTAINER (frame), label);
1973     m_pStatusLabel[i] = label;
1974   }
1975 }
1976
1977 guint s_idle_id;
1978 static gint mainframe_idle (gpointer user_data)
1979 {
1980   g_pParentWnd->RoutineProcessing ();
1981   return TRUE;
1982 }
1983
1984 static void Sys_Iconify (GtkWidget *w);
1985 static void Sys_Restore (GtkWidget *w);
1986
1987 inline void CHECK_RESTORE(GtkWidget* w)
1988 {
1989   if (g_object_get_data (G_OBJECT (w), "was_mapped") != NULL)
1990     gtk_widget_show (w);
1991 }
1992
1993
1994 // this is called when the window is restored from the iconified state
1995 static void mainframe_map (GtkWidget *widget)
1996 {
1997   if (g_pParentWnd->IsSleeping ())
1998     g_pParentWnd->OnSleep ();
1999
2000   if ((g_pParentWnd->CurrentStyle() == MainFrame::eFloating) && (widget == g_pParentWnd->m_pWidget))
2001   {
2002     // restore previously visible windows
2003     CHECK_RESTORE (g_pParentWnd->GetCamWnd ()->m_pParent);
2004     if (g_PrefsDlg.m_bFloatingZ)
2005       CHECK_RESTORE (g_pParentWnd->GetZWnd ()->m_pParent);
2006     CHECK_RESTORE (g_pParentWnd->GetXYWnd ()->m_pParent);
2007     CHECK_RESTORE (g_pParentWnd->GetXZWnd ()->m_pParent);
2008     CHECK_RESTORE (g_pParentWnd->GetYZWnd ()->m_pParent);
2009     CHECK_RESTORE (g_pGroupDlg->m_pWidget);
2010   }
2011 }
2012
2013 inline void CHECK_MINIMIZE(GtkWidget* w)
2014 {
2015   g_object_set_data (G_OBJECT (w), "was_mapped", (void*)(GTK_WIDGET_VISIBLE (w) != 0));
2016   gtk_widget_hide (w);
2017 }
2018
2019 static void mainframe_unmap (GtkWidget *widget)
2020 {
2021
2022   if ((g_pParentWnd->CurrentStyle() == MainFrame::eFloating) && (widget == g_pParentWnd->m_pWidget))
2023   {
2024     // minimize all other windows when the main window is minimized
2025     CHECK_MINIMIZE (g_pParentWnd->GetCamWnd ()->m_pParent);
2026     if (g_PrefsDlg.m_bFloatingZ)
2027       CHECK_MINIMIZE (g_pParentWnd->GetZWnd ()->m_pParent);
2028     CHECK_MINIMIZE (g_pParentWnd->GetXYWnd ()->m_pParent);
2029     CHECK_MINIMIZE (g_pParentWnd->GetXZWnd ()->m_pParent);
2030     CHECK_MINIMIZE (g_pParentWnd->GetYZWnd ()->m_pParent);
2031     CHECK_MINIMIZE (g_pGroupDlg->m_pWidget);
2032   }
2033 }
2034
2035 static GtkWidget* create_floating (MainFrame* mainframe)
2036 {
2037   GtkWidget *wnd = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2038   //if (mainframe->CurrentStyle() != MainFrame::eFloating)
2039     gtk_window_set_transient_for (GTK_WINDOW (wnd), GTK_WINDOW (mainframe->m_pWidget));
2040   gtk_widget_set_events (wnd, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
2041   gtk_signal_connect (GTK_OBJECT (wnd), "delete_event", GTK_SIGNAL_FUNC (widget_delete_hide), NULL);
2042   gtk_signal_connect (GTK_OBJECT (wnd), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
2043   gtk_signal_connect (GTK_OBJECT (wnd), "key_press_event",
2044                       GTK_SIGNAL_FUNC (mainframe_keypress), mainframe);
2045   gtk_signal_connect (GTK_OBJECT (wnd), "key_release_event",
2046                       GTK_SIGNAL_FUNC (mainframe_keyrelease), mainframe);
2047   gtk_signal_connect (GTK_OBJECT (wnd), "map_event",
2048                       GTK_SIGNAL_FUNC (mainframe_map), mainframe);
2049
2050   gtk_window_set_default_size (GTK_WINDOW (wnd), 100, 100);
2051
2052 #ifdef DBG_WINDOWPOS
2053   Sys_Printf("create_floating: %p, gtk_window_set_default_size 100, 100\n", wnd);
2054 #endif
2055
2056   return wnd;
2057 }
2058
2059 void console_populate_popup(GtkTextView* textview, GtkMenu* menu, gpointer user_data)
2060 {
2061   menu_separator(GTK_WIDGET(menu));
2062
2063   GtkWidget* item = gtk_menu_item_new_with_label ("Clear");
2064   gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (Sys_ClearPrintf), NULL);
2065   gtk_widget_show (item);
2066   gtk_menu_append (GTK_MENU (menu), item);
2067 }
2068
2069 void console_construct(GtkWidget* textview)
2070 {
2071   g_signal_connect(G_OBJECT(textview), "populate-popup", G_CALLBACK(console_populate_popup), NULL);
2072 }
2073
2074 extern MemStream g_Clipboard;
2075
2076 void Clipboard_CopyMap()
2077 {
2078   g_Clipboard.SetLength(0);
2079   Map_Export (&g_Clipboard, "xmap", false, true);
2080 }
2081
2082 void Clipboard_PasteMap()
2083 {
2084   if (g_Clipboard.GetLength() > 0)
2085   {
2086     g_Clipboard.Seek(0, SEEK_SET);
2087     Map_Import(&g_Clipboard, "xmap", true);
2088   }
2089 }
2090
2091 /*!
2092 Platform-independent GTK clipboard support.
2093 \todo Using GDK_SELECTION_CLIPBOARD fails on win32, so we use the win32 API directly for now.
2094 */
2095 #if defined (__linux__) || defined (__APPLE__)
2096
2097 enum
2098 {
2099   RADIANT_CLIPPINGS = 23,
2100 };
2101
2102 static const GtkTargetEntry clipboard_targets[] = {
2103   { "RADIANT_CLIPPINGS", 0, RADIANT_CLIPPINGS, },
2104 };
2105
2106 static void clipboard_get (GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer user_data_or_owner)
2107 {
2108   guchar *buffer;
2109   gint len;
2110   GdkAtom type = GDK_NONE;
2111
2112   len = g_Clipboard.GetLength();
2113
2114   if (!len)
2115   {
2116     buffer = NULL;
2117   } else
2118   {
2119     buffer = g_Clipboard.GetBuffer ();
2120   }
2121
2122   if(info == clipboard_targets[0].info)
2123   {
2124     type = gdk_atom_intern(clipboard_targets[0].target, FALSE);
2125   }
2126
2127   gtk_selection_data_set (selection_data, type, 8, buffer, len);
2128 }
2129
2130 static void clipboard_clear (GtkClipboard *clipboard, gpointer user_data_or_owner)
2131 {
2132 }
2133
2134 static void clipboard_received (GtkClipboard *clipboard, GtkSelectionData *data, gpointer user_data)
2135 {
2136   g_Clipboard.SetLength (0);
2137
2138   if (data->length < 0)
2139     Sys_FPrintf(SYS_ERR, "Error retrieving selection\n");
2140   else if(strcmp(gdk_atom_name(data->type), clipboard_targets[0].target) == 0)
2141     g_Clipboard.Write (data->data, data->length);
2142
2143   Clipboard_PasteMap();
2144 }
2145
2146 void clipboard_copy()
2147 {
2148   Clipboard_CopyMap();
2149
2150   GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
2151
2152   gtk_clipboard_set_with_data (clipboard, clipboard_targets, 1, clipboard_get, clipboard_clear, NULL);
2153 }
2154
2155 void clipboard_paste()
2156 {
2157   GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
2158
2159   gtk_clipboard_request_contents (clipboard, gdk_atom_intern(clipboard_targets[0].target, FALSE), clipboard_received, NULL);
2160 }
2161
2162
2163 #elif defined(WIN32)
2164
2165 void clipboard_copy()
2166 {
2167   Clipboard_CopyMap();
2168
2169   bool bClipped = false;
2170   UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings");
2171   if (nClipboard > 0)
2172   {
2173     if (::OpenClipboard(NULL))
2174     {
2175       EmptyClipboard();
2176                 long lSize = g_Clipboard.GetLength();
2177       HANDLE h = ::GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, lSize + sizeof(long));
2178       if (h != NULL)
2179       {
2180         unsigned char *cp = reinterpret_cast<unsigned char*>(::GlobalLock(h));
2181                                 memcpy(cp, &lSize, sizeof(long));
2182                                 cp += sizeof(long);
2183         g_Clipboard.Seek(0, SEEK_SET);
2184         g_Clipboard.Read(cp, lSize);
2185         ::GlobalUnlock(h);
2186         ::SetClipboardData(nClipboard, h);
2187         ::CloseClipboard();
2188         bClipped = true;
2189       }
2190     }
2191   }
2192
2193   if (!bClipped)
2194   {
2195     Sys_Printf("Unable to register Windows clipboard formats, copy/paste between editors will not be possible\n");
2196   }
2197 }
2198
2199 void clipboard_paste()
2200 {
2201   bool bPasted = false;
2202   UINT nClipboard = ::RegisterClipboardFormat("RadiantClippings");
2203   if (nClipboard > 0 && ::OpenClipboard(NULL))
2204   {
2205     if(IsClipboardFormatAvailable(nClipboard))
2206     {
2207       HANDLE h = ::GetClipboardData(nClipboard);
2208       if (h)
2209       {
2210         g_Clipboard.SetLength(0);
2211                           unsigned char *cp = reinterpret_cast<unsigned char*>(::GlobalLock(h));
2212                           long lSize = 0;
2213                           memcpy(&lSize, cp, sizeof(long));
2214                           cp += sizeof(long);
2215         g_Clipboard.Write(cp, lSize);
2216         ::GlobalUnlock(h);
2217       }
2218     }
2219     ::CloseClipboard();
2220   }
2221
2222   Clipboard_PasteMap();
2223 }
2224
2225 #endif
2226
2227 void MainFrame::Copy()
2228 {
2229   clipboard_copy();
2230 }
2231
2232 void MainFrame::Paste()
2233 {
2234   clipboard_paste();
2235   UpdateSurfaceDialog();
2236 }
2237
2238
2239 #ifdef DBG_WINDOWPOS
2240 GtkWidget *watchit = NULL;
2241
2242 void CheckWatchit(char *msg)
2243 {
2244   static int width = 0;
2245   if ((watchit!=NULL) && (watchit->allocation.width != width))
2246   {
2247     Sys_Printf("CheckWatchit %s: %d\n", msg, watchit->allocation.width);
2248     width = watchit->allocation.width;
2249   }
2250 }
2251 #endif
2252
2253 #ifdef _WIN32
2254 BOOL CALLBACK m_pCountMonitor (HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
2255 {
2256   int *n = (int *) dwData;
2257
2258   (*n)++;
2259
2260   return TRUE;
2261 }
2262
2263 struct monitorInfo_s {
2264   GdkRectangle *win_monitors;
2265   int i_win_mon;
2266 };
2267
2268 BOOL CALLBACK m_pEnumMonitor (HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
2269 {
2270   monitorInfo_s *monitorInfo = (monitorInfo_s *) dwData;
2271   GdkRectangle *monitor;
2272   MONITORINFOEX lpmi;
2273
2274   monitor = monitorInfo->win_monitors + monitorInfo->i_win_mon;
2275
2276   memset(&lpmi, 0, sizeof(MONITORINFOEX));
2277   lpmi.cbSize = sizeof(MONITORINFOEX);
2278
2279   GetMonitorInfo( hMonitor, &lpmi );
2280
2281   if( lpmi.dwFlags & MONITORINFOF_PRIMARY ) {
2282     RECT rect;
2283
2284     SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0);
2285     monitor->x = rect.left;
2286     monitor->y = rect.top;
2287     monitor->width = rect.right - rect.left;
2288     monitor->height = rect.bottom - rect.top;
2289
2290     if (monitorInfo->i_win_mon != 0)
2291           {
2292             GdkRectangle temp = *monitor;
2293       *monitor = monitorInfo->win_monitors[0];
2294             monitorInfo->win_monitors[0] = temp;
2295           }
2296   } else {
2297     monitor->x = lpmi.rcMonitor.left;
2298     monitor->y = lpmi.rcMonitor.top;
2299     monitor->width = lpmi.rcMonitor.right - lpmi.rcMonitor.left;
2300     monitor->height = lpmi.rcMonitor.bottom - lpmi.rcMonitor.top;
2301   }
2302
2303   monitorInfo->i_win_mon++;
2304
2305   return TRUE;
2306 }
2307
2308 void PositionWindowOnPrimaryScreen(window_position_t& position)
2309 {
2310   const GdkRectangle primaryMonitorRect = g_pParentWnd->GetPrimaryMonitorRect();
2311
2312   if( position.x <= primaryMonitorRect.x + 6 )
2313     position.x = primaryMonitorRect.x + 6;
2314   else if( position.x >= ( primaryMonitorRect.x + primaryMonitorRect.width ) - 6 )
2315     position.x = primaryMonitorRect.x + 6;
2316
2317   if( position.y <= primaryMonitorRect.y + 6 )
2318     position.y = primaryMonitorRect.y + 6;
2319   else if( position.y >= ( primaryMonitorRect.y + primaryMonitorRect.height ) - 6 )
2320     position.y = primaryMonitorRect.y + 6;
2321
2322   if( position.x + position.w >= ( primaryMonitorRect.x + primaryMonitorRect.width ) - 18 )
2323     position.w = primaryMonitorRect.width - 18;
2324   if( position.y + position.h >= ( primaryMonitorRect.y + primaryMonitorRect.height ) - 18 )
2325     position.h = primaryMonitorRect.height - 18;
2326 }
2327 #endif
2328
2329 GtkWidget* create_framed_widget(GtkWidget* widget)
2330 {
2331   GtkWidget* frame = gtk_frame_new ((char*)NULL);
2332   gtk_widget_show (frame);
2333   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
2334   gtk_container_add (GTK_CONTAINER (frame), widget);
2335   gtk_widget_show(widget);
2336   return frame;
2337 }
2338
2339 gboolean entry_focus_in(GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
2340 {
2341   gtk_window_remove_accel_group (GTK_WINDOW (g_pParentWnd->m_pWidget), global_accel);
2342   return FALSE;
2343 }
2344
2345 gboolean entry_focus_out(GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
2346 {
2347   gtk_window_add_accel_group (GTK_WINDOW (g_pParentWnd->m_pWidget), global_accel);
2348   return FALSE;
2349 }
2350
2351 GtkWidget* create_framed_texwnd(TexWnd* texwnd)
2352 {
2353   GtkWidget* frame = gtk_frame_new ((char*)NULL);
2354   gtk_widget_show (frame);
2355   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
2356
2357   GtkWidget* hbox = gtk_hbox_new (FALSE, 0);
2358   gtk_widget_show (hbox);
2359   gtk_container_add (GTK_CONTAINER (frame), hbox);
2360
2361   GtkWidget* w = gtk_vscrollbar_new (GTK_ADJUSTMENT (gtk_adjustment_new (0,0,0,1,1,1)));
2362   gtk_widget_show (w);
2363   gtk_box_pack_end (GTK_BOX (hbox), w, FALSE, TRUE, 0);
2364   g_qeglobals_gui.d_texture_scroll = w;
2365
2366   GtkWidget* texbox = gtk_vbox_new (FALSE, 0);
2367   gtk_widget_show (texbox);
2368   gtk_box_pack_start (GTK_BOX (hbox), texbox, TRUE, TRUE, 0);
2369
2370   w = gtk_entry_new ();
2371   gtk_box_pack_start (GTK_BOX (texbox), w, FALSE, FALSE, 0);
2372   texwnd->m_pFilter = w;
2373   g_signal_connect(G_OBJECT(w), "focus_in_event", G_CALLBACK(entry_focus_in), NULL);
2374   g_signal_connect(G_OBJECT(w), "focus_out_event", G_CALLBACK(entry_focus_out), NULL);
2375
2376   w = texwnd->GetWidget ();
2377   gtk_box_pack_start (GTK_BOX (texbox), w, TRUE, TRUE, 0);
2378   gtk_widget_show (w);
2379
2380   return frame;
2381 }
2382
2383 static ZWnd *create_floating_zwnd(MainFrame *mainframe)
2384 {
2385   ZWnd *pZWnd = new ZWnd ();
2386   GtkWidget* wnd = create_floating (mainframe);
2387
2388   gtk_window_set_title (GTK_WINDOW (wnd), "Z");
2389
2390   pZWnd->m_pParent = wnd;
2391
2392   {
2393     GtkWidget* frame = create_framed_widget(pZWnd->GetWidget());
2394     gtk_container_add (GTK_CONTAINER (wnd), frame);
2395   }
2396
2397   gtk_widget_realize (wnd);
2398
2399   // turn OFF minimize and maximize boxes.
2400   // Must be *after* realize, or wnd->window is NULL
2401   // should do the right thing on *nix, need to verify.
2402   gdk_window_set_decorations ( wnd->window,
2403                                 GdkWMDecoration(GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE ) );
2404   //TODO 50 by observation, will vary depending on decoration sizes
2405   {
2406     GdkGeometry geometry;
2407     geometry.min_width = 50;
2408     //we only care about width, but have to set this too, or get nasty bugs
2409     geometry.min_height = 10;
2410     gdk_window_set_geometry_hints( wnd->window,&geometry,GDK_HINT_MIN_SIZE);
2411   }
2412
2413 #ifdef _WIN32
2414   if( g_PrefsDlg.m_bStartOnPrimMon ) {
2415     PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posZWnd );
2416   }
2417 #endif
2418   load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posZWnd);
2419
2420   if (g_PrefsDlg.m_bZVis)
2421     gtk_widget_show (wnd);
2422
2423   return pZWnd;
2424 }
2425
2426 static const int gutter = 12;
2427
2428 void MainFrame::Create ()
2429 {
2430   GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2431   m_pWidget = window;
2432   gtk_widget_set_events (window, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
2433   gtk_signal_connect (GTK_OBJECT (window), "delete_event",
2434                       GTK_SIGNAL_FUNC (mainframe_delete), this);
2435   gtk_signal_connect (GTK_OBJECT (window), "destroy",
2436                       GTK_SIGNAL_FUNC (mainframe_destroy), this);
2437   gtk_signal_connect (GTK_OBJECT (window), "key_press_event",
2438                       GTK_SIGNAL_FUNC (mainframe_keypress), this);
2439   gtk_signal_connect (GTK_OBJECT (window), "key_release_event",
2440                       GTK_SIGNAL_FUNC (mainframe_keyrelease), this);
2441   gtk_signal_connect (GTK_OBJECT (window), "map_event",
2442                       GTK_SIGNAL_FUNC (mainframe_map), this);
2443   gtk_signal_connect (GTK_OBJECT (window), "unmap_event",
2444                       GTK_SIGNAL_FUNC (mainframe_unmap), this);
2445
2446   g_qeglobals_gui.d_main_window = window;
2447
2448 #ifdef _WIN32
2449   // calculate gdk offset
2450   int n_win_monitors = 0;
2451
2452   monitorInfo_s monitorInfo;
2453
2454   // detect multiple monitors
2455   EnumDisplayMonitors (NULL, NULL, m_pCountMonitor, reinterpret_cast<LPARAM>(&n_win_monitors));
2456
2457   monitorInfo.win_monitors = new GdkRectangle [ n_win_monitors ];
2458   monitorInfo.i_win_mon = 0;
2459   EnumDisplayMonitors (NULL, NULL, m_pEnumMonitor, reinterpret_cast<LPARAM>(&monitorInfo));
2460
2461   gdk_offset_x = G_MININT;
2462   gdk_offset_y = G_MININT;
2463
2464   // calculate offset
2465   for( monitorInfo.i_win_mon = 0; monitorInfo.i_win_mon < n_win_monitors; monitorInfo.i_win_mon++ ) {
2466     gdk_offset_x = MAX (gdk_offset_x, -monitorInfo.win_monitors[monitorInfo.i_win_mon].x);
2467     gdk_offset_y = MAX (gdk_offset_y, -monitorInfo.win_monitors[monitorInfo.i_win_mon].y);
2468   }
2469
2470   Sys_Printf( "GDK's coordinate system is offset by %d over the x-axis and %d over the y-axis from Windows' coordinate system.\n", gdk_offset_x, gdk_offset_y );
2471
2472   if( g_PrefsDlg.m_bStartOnPrimMon )
2473   {
2474     // get gdk monitors
2475     GdkDisplay *display;
2476     GdkScreen *screen;
2477     gint n_gdk_monitors = 0;
2478     gint i_mon;
2479     GdkRectangle rect;
2480
2481     // detect multiple monitors
2482     display = gdk_display_get_default ();
2483     Sys_Printf( "GDK detects that server %s manages %d screens\n", gdk_display_get_name (display), gdk_display_get_n_screens (display) );
2484
2485     screen = gdk_display_get_screen( display, 1 );
2486     n_gdk_monitors = gdk_screen_get_n_monitors( screen );
2487
2488     Sys_Printf( "GDK detects that screen 1 has %d monitors\n", n_gdk_monitors );
2489
2490     for( i_mon = 0; i_mon < n_gdk_monitors; i_mon++ ) {
2491       memset( &rect, 0, sizeof(rect) );
2492       gdk_screen_get_monitor_geometry( screen, i_mon, &rect );
2493       Sys_Printf( "  monitor %d: x: %d y: %d w: %d h: %d\n", i_mon, rect.x, rect.y, rect.width, rect.height );
2494
2495       if( i_mon == 0 ) {
2496         memcpy( &primaryMonitorRect, &rect, sizeof(primaryMonitorRect) );
2497       }
2498     }
2499
2500     PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.position );
2501   }
2502   else {
2503     primaryMonitorRect.x = primaryMonitorRect.y = 0;
2504     primaryMonitorRect.width = gdk_screen_width ();
2505     primaryMonitorRect.height = gdk_screen_height ();
2506   }
2507
2508 #endif
2509
2510   load_window_pos(window, g_PrefsDlg.mWindowInfo.position);
2511
2512   GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
2513   gtk_container_add (GTK_CONTAINER (window), vbox);
2514   gtk_widget_show (vbox);
2515
2516   create_main_menu (window, vbox);
2517   MRU_Load ();
2518   create_main_toolbar (window, vbox);
2519   create_plugin_toolbar (window,vbox);
2520
2521   m_nCurrentStyle = g_PrefsDlg.m_nView;
2522
2523   g_pGroupDlg->Create ();
2524   OnPluginsRefresh();
2525
2526   CreateQEChildren();
2527
2528   gtk_widget_show (window);
2529
2530   // not needed on win32, it's in the .rc
2531 #ifndef _WIN32
2532   {
2533     GdkPixmap *pixmap;
2534     GdkBitmap *mask;
2535     load_pixmap ("icon.bmp", window, &pixmap, &mask);
2536     gdk_window_set_icon (window->window, NULL, pixmap, mask);
2537   }
2538 #endif
2539
2540   if (CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft)
2541   {
2542     {
2543       GtkWidget* vsplit = gtk_vpaned_new ();
2544       m_pSplits[0] = vsplit;
2545       gtk_box_pack_start (GTK_BOX (vbox), vsplit, TRUE, TRUE, 0);
2546       gtk_widget_show (vsplit);
2547
2548       {
2549         GtkWidget* hsplit = gtk_hpaned_new ();
2550         m_pSplits[2] = hsplit;
2551         gtk_paned_add1 (GTK_PANED (vsplit), hsplit);
2552         gtk_widget_show (hsplit);
2553
2554         {
2555           GtkWidget* hsplit2 = gtk_hpaned_new ();
2556           m_pSplits[3] = hsplit2;
2557           gtk_paned_add2 (GTK_PANED (hsplit), hsplit2);
2558           gtk_widget_show (hsplit2);
2559
2560           {
2561             GtkWidget* vsplit2 = gtk_vpaned_new ();
2562             m_pSplits[1] = vsplit2;
2563             if (CurrentStyle() == eRegular)
2564               gtk_paned_add2 (GTK_PANED (hsplit2), vsplit2);
2565             else
2566               gtk_paned_add1 (GTK_PANED (hsplit), vsplit2);
2567             gtk_widget_show (vsplit2);
2568
2569             // camera
2570             m_pCamWnd = new CamWnd ();
2571             {
2572               GtkWidget* frame = create_framed_widget(m_pCamWnd->GetWidget());
2573               gtk_paned_add1 (GTK_PANED (vsplit2), frame);
2574             }
2575
2576             // xy
2577             m_pXYWnd = new XYWnd ();
2578             m_pXYWnd->SetViewType(XY);
2579             {
2580               GtkWidget* frame = create_framed_widget(m_pXYWnd->GetWidget ());
2581               gtk_paned_add1 (GTK_PANED (hsplit2), frame);
2582             }
2583
2584             // z
2585             m_pZWnd = new ZWnd ();
2586             {
2587               GtkWidget* frame = create_framed_widget(m_pZWnd->GetWidget ());
2588               if (CurrentStyle() == eRegular)
2589                 gtk_paned_add1 (GTK_PANED (hsplit), frame);
2590               else
2591                 gtk_paned_add2 (GTK_PANED (hsplit2), frame);
2592             }
2593
2594             // textures
2595             m_pTexWnd = new TexWnd ();
2596             {
2597               GtkWidget* frame = create_framed_texwnd(m_pTexWnd);
2598               gtk_paned_add2 (GTK_PANED (vsplit2), frame);
2599             }
2600
2601             // console
2602             {
2603               GtkWidget* scr = gtk_scrolled_window_new (NULL, NULL);
2604               gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2605               gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scr), GTK_SHADOW_IN);
2606               gtk_widget_show (scr);
2607               gtk_paned_pack2 (GTK_PANED (vsplit), scr, FALSE, TRUE);
2608
2609               {
2610                 GtkWidget* text = gtk_text_view_new ();
2611                 gtk_widget_set_size_request(text, 0, -1); // allow shrinking
2612                 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
2613                 gtk_text_view_set_editable (GTK_TEXT_VIEW(text), FALSE);
2614                 gtk_container_add (GTK_CONTAINER (scr), text);
2615                 gtk_widget_show (text);
2616                 g_qeglobals_gui.d_edit = text;
2617               }
2618             }
2619           }
2620         }
2621       }
2622     }
2623
2624     gtk_paned_set_position (GTK_PANED (m_pSplits[0]), g_PrefsDlg.mWindowInfo.nXYHeight+28);
2625
2626     if (CurrentStyle() == eRegular)
2627     {
2628       gtk_paned_set_position (GTK_PANED (m_pSplits[2]), g_PrefsDlg.mWindowInfo.nZWidth);
2629       gtk_paned_set_position (GTK_PANED (m_pSplits[3]), g_PrefsDlg.mWindowInfo.nXYWidth);
2630     }
2631     else
2632     {
2633       gtk_paned_set_position (GTK_PANED (m_pSplits[2]), g_PrefsDlg.mWindowInfo.nCamWidth);
2634       while (gtk_events_pending ())  gtk_main_iteration ();
2635       gtk_paned_set_position (GTK_PANED (m_pSplits[3]), g_PrefsDlg.mWindowInfo.nXYWidth);
2636     }
2637
2638     while (gtk_events_pending ())  gtk_main_iteration ();
2639
2640     gtk_paned_set_position (GTK_PANED (m_pSplits[1]), g_PrefsDlg.mWindowInfo.nCamHeight);
2641   }
2642   else if (CurrentStyle() == eFloating)
2643   {
2644     {
2645       GtkWidget* wnd = create_floating (this);
2646       gtk_window_set_title (GTK_WINDOW (wnd), "Camera");
2647
2648 #ifdef _WIN32
2649       if( g_PrefsDlg.m_bStartOnPrimMon ) {
2650         PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posCamWnd );
2651       }
2652 #endif
2653       load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posCamWnd);
2654
2655       gtk_widget_show (wnd);
2656
2657       m_pCamWnd = new CamWnd ();
2658
2659       {
2660         GtkWidget* frame = create_framed_widget(m_pCamWnd->GetWidget ());
2661         gtk_container_add (GTK_CONTAINER (wnd), frame);
2662       }
2663
2664       m_pCamWnd->m_pParent = wnd;
2665     }
2666
2667     if (g_PrefsDlg.m_bFloatingZ)
2668     {
2669       m_pZWnd = create_floating_zwnd(this);
2670
2671       {
2672         GtkWidget* wnd = create_floating (this);
2673         gtk_window_set_title (GTK_WINDOW (wnd), "XY View");
2674
2675 #ifdef _WIN32
2676         if( g_PrefsDlg.m_bStartOnPrimMon ) {
2677           PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posXYWnd );
2678         }
2679 #endif
2680         load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posXYWnd);
2681
2682         m_pXYWnd = new XYWnd ();
2683         m_pXYWnd->SetViewType(XY);
2684
2685         {
2686           GtkWidget* frame = create_framed_widget(m_pXYWnd->GetWidget());
2687           gtk_container_add (GTK_CONTAINER (wnd), frame);
2688         }
2689
2690         m_pXYWnd->m_pParent = wnd;
2691
2692         gtk_widget_show (wnd);
2693       }
2694     }
2695     else
2696     {
2697       GtkWidget* wnd = create_floating (this);
2698       gtk_window_set_title (GTK_WINDOW (wnd), "XY View");
2699
2700 #ifdef _WIN32
2701       if( g_PrefsDlg.m_bStartOnPrimMon ) {
2702         PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posXYWnd );
2703       }
2704 #endif
2705       load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posXYWnd);
2706
2707       m_pZWnd = new ZWnd ();
2708       m_pZWnd->m_pParent = wnd;
2709
2710       m_pXYWnd = new XYWnd ();
2711       m_pXYWnd->SetViewType(XY);
2712       m_pXYWnd->m_pParent = wnd;
2713
2714
2715       {
2716         GtkWidget* hsplit = gtk_hpaned_new ();
2717         m_pSplits[0] = hsplit;
2718         gtk_container_add (GTK_CONTAINER (wnd), hsplit);
2719         gtk_widget_show (hsplit);
2720
2721         {
2722           GtkWidget* frame = create_framed_widget(m_pZWnd->GetWidget());
2723           gtk_paned_add1 (GTK_PANED (hsplit), frame);
2724         }
2725         {
2726           GtkWidget* frame = create_framed_widget(m_pXYWnd->GetWidget());
2727           gtk_paned_add2 (GTK_PANED (hsplit), frame);
2728         }
2729       }
2730
2731       gtk_widget_show (wnd);
2732
2733       gtk_paned_set_position (GTK_PANED (m_pSplits[0]), g_PrefsDlg.mWindowInfo.nZFloatWidth);
2734     }
2735
2736     {
2737       GtkWidget* wnd = create_floating (this);
2738       gtk_window_set_title (GTK_WINDOW (wnd), "XZ View");
2739
2740 #ifdef _WIN32
2741       if( g_PrefsDlg.m_bStartOnPrimMon ) {
2742         PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posXZWnd );
2743       }
2744 #endif
2745       load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posXZWnd);
2746
2747       m_pXZWnd = new XYWnd ();
2748       m_pXZWnd->m_pParent = wnd;
2749       m_pXZWnd->SetViewType(XZ);
2750
2751       {
2752         GtkWidget* frame = create_framed_widget(m_pXZWnd->GetWidget());
2753         gtk_container_add (GTK_CONTAINER (wnd), frame);
2754       }
2755
2756       if (g_PrefsDlg.m_bXZVis)
2757         gtk_widget_show (wnd);
2758     }
2759
2760     {
2761       GtkWidget* wnd = create_floating (this);
2762       gtk_window_set_title (GTK_WINDOW (wnd), "YZ View");
2763
2764 #ifdef _WIN32
2765       if( g_PrefsDlg.m_bStartOnPrimMon ) {
2766         PositionWindowOnPrimaryScreen( g_PrefsDlg.mWindowInfo.posYZWnd );
2767       }
2768 #endif
2769       load_window_pos (wnd, g_PrefsDlg.mWindowInfo.posYZWnd);
2770
2771       m_pYZWnd = new XYWnd ();
2772       m_pYZWnd->m_pParent = wnd;
2773       m_pYZWnd->SetViewType(YZ);
2774
2775       {
2776         GtkWidget* frame = create_framed_widget(m_pYZWnd->GetWidget());
2777         gtk_container_add (GTK_CONTAINER (wnd), frame);
2778       }
2779
2780       if (g_PrefsDlg.m_bYZVis)
2781         gtk_widget_show (wnd);
2782     }
2783
2784     m_pTexWnd = new TexWnd ();
2785     {
2786       GtkWidget* frame = create_framed_texwnd(m_pTexWnd);
2787       m_pTexWnd->m_pParent = g_pGroupDlg->m_pWidget;
2788
2789       {
2790         GtkWidget* w = gtk_label_new ("Textures");
2791         gtk_widget_show (w);
2792         gtk_notebook_insert_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), frame, w, 1);
2793       }
2794     }
2795
2796     g_pGroupDlg->Show ();
2797   }
2798   else // 4 way
2799   {
2800     {
2801       GtkWidget* hsplit = gtk_hpaned_new ();
2802       m_pSplits[0] = hsplit;
2803       gtk_box_pack_start (GTK_BOX (vbox), hsplit, TRUE, TRUE, 0);
2804       gtk_widget_show (hsplit);
2805
2806       {
2807         GtkWidget* vsplit1 = gtk_vpaned_new ();
2808         m_pSplits[1] = vsplit1;
2809         gtk_paned_add1 (GTK_PANED (hsplit), vsplit1);
2810         gtk_widget_show (vsplit1);
2811
2812         {
2813           GtkWidget* vsplit2 = gtk_vpaned_new ();
2814           m_pSplits[2] = vsplit2;
2815           gtk_paned_add2 (GTK_PANED (hsplit), vsplit2);
2816           gtk_widget_show (vsplit2);
2817
2818           m_pCamWnd = new CamWnd ();
2819           {
2820             GtkWidget* frame = create_framed_widget(m_pCamWnd->GetWidget());
2821             gtk_paned_add1 (GTK_PANED (vsplit1), frame);
2822           }
2823
2824           m_pXYWnd = new XYWnd ();
2825           m_pXYWnd->SetViewType(XY);
2826           {
2827             GtkWidget* frame = create_framed_widget(m_pXYWnd->GetWidget());
2828             gtk_paned_add1 (GTK_PANED (vsplit2), frame);
2829           }
2830
2831           m_pYZWnd = new XYWnd ();
2832           m_pYZWnd->SetViewType(YZ);
2833           {
2834             GtkWidget* frame = create_framed_widget(m_pYZWnd->GetWidget());
2835             gtk_paned_add2 (GTK_PANED (vsplit1), frame);
2836           }
2837
2838           m_pXZWnd = new XYWnd ();
2839           m_pXZWnd->SetViewType(XZ);
2840           {
2841             GtkWidget* frame = create_framed_widget(m_pXZWnd->GetWidget());
2842             gtk_paned_add2 (GTK_PANED (vsplit2), frame);
2843           }
2844         }
2845       }
2846     }
2847
2848     //    g_qeglobals_gui.d_edit = NULL;
2849
2850     {
2851       m_pTexWnd = new TexWnd ();
2852       GtkWidget* frame = create_framed_texwnd(m_pTexWnd);
2853
2854       {
2855         GtkWidget* w = gtk_label_new ("Textures");
2856         gtk_widget_show (w);
2857         gtk_notebook_insert_page (GTK_NOTEBOOK (g_pGroupDlg->m_pNotebook), frame, w, 1);
2858       }
2859     }
2860
2861     m_pTexWnd->m_pParent = g_pGroupDlg->m_pWidget;
2862 //    gtk_widget_realize (m_pTexWnd->GetWidget ());
2863     m_pZWnd = create_floating_zwnd(this);
2864
2865     while (gtk_events_pending ())
2866       gtk_main_iteration ();
2867
2868     {
2869       int x = GTK_PANED (m_pSplits[0])->max_position/2 - gutter;
2870       gtk_paned_set_position (GTK_PANED (m_pSplits[0]), x);
2871     }
2872
2873     {
2874       int y = GTK_PANED (m_pSplits[1])->max_position/2 - gutter;
2875       gtk_paned_set_position (GTK_PANED (m_pSplits[1]), y);
2876       gtk_paned_set_position (GTK_PANED (m_pSplits[2]), y);
2877     }
2878   }
2879
2880   if(g_PrefsDlg.mWindowInfo.nState & GDK_WINDOW_STATE_MAXIMIZED)
2881     gtk_window_maximize(GTK_WINDOW(window));
2882
2883   gtk_widget_show (window);
2884
2885   Texture_Init();
2886
2887   if (m_pXYWnd) // this is always true?
2888   {
2889     m_pXYWnd->SetActive(true);
2890   }
2891   m_bSplittersOK = true;
2892   Texture_SetMode(g_qeglobals.d_savedinfo.iTexMenu);
2893
2894   g_pParentWnd->OnEntitiesSetViewAs(0);
2895
2896 //  m_wndTextureBar.Create (vbox);
2897   create_main_statusbar (window, vbox);
2898
2899   LoadCommandMap();
2900   ShowMenuItemKeyBindings(window);
2901
2902   if (g_qeglobals_gui.d_edit != NULL)
2903     console_construct(g_qeglobals_gui.d_edit);
2904
2905   //  bool load_last = FALSE;
2906
2907   SetGridStatus();
2908   SetButtonMenuStates();
2909
2910   // m_bShowShader and m_bTextureShaderlistOnly have a menu checkbox, update it now
2911   GtkWidget *item;
2912   g_bIgnoreCommands++;
2913   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_shaders_show"));
2914   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bShowShaders ? TRUE : FALSE);
2915   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_shaderlistonly"));
2916   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bTexturesShaderlistOnly ? TRUE : FALSE);
2917   g_bIgnoreCommands--;
2918
2919 //  if (g_PrefsDlg.m_bTextureBar)
2920 //    gtk_widget_show (m_wndTextureBar.m_pWidget);
2921
2922   SetActiveXY(m_pXYWnd);
2923
2924   s_idle_id = gtk_timeout_add (25, mainframe_idle, this);
2925
2926   QGL_InitExtensions ();
2927
2928   if (g_PrefsDlg.mLocalPrefs.mbEmpty)
2929   {
2930     g_PrefsDlg.mLocalPrefs.mbEmpty = false;
2931     g_PrefsDlg.SavePrefs();
2932   }
2933
2934   // remove the pid file
2935   remove (g_pidGameFile.GetBuffer ());
2936
2937   Sys_Printf ("Entering message loop\n");
2938
2939   m_bDoLoop = true;
2940
2941   m_nTimer = gtk_timeout_add (1000, timer, this);
2942 }
2943
2944 // =============================================================================
2945 // MainFrame class
2946
2947 MainFrame::MainFrame()
2948 {
2949   m_bDoLoop = false;
2950   m_bSplittersOK = false;
2951   g_pParentWnd = this;
2952   m_pXYWnd = (XYWnd*)NULL;
2953   m_pCamWnd = NULL;
2954   m_pTexWnd = (TexWnd*)NULL;
2955   m_pZWnd = (ZWnd*)NULL;
2956   m_pYZWnd = (XYWnd*)NULL;
2957   m_pXZWnd = (XYWnd*)NULL;
2958   m_pActiveXY = (XYWnd*)NULL;
2959   m_bCamPreview = true;
2960   m_pWatchBSP = NULL;
2961   for (int n = 0; n < 6; n++)
2962     m_pStatusLabel[n] = NULL;
2963   m_bNeedStatusUpdate = false;
2964   m_nTimer = 0;
2965   m_bSleeping = false;
2966   Create ();
2967 }
2968
2969 MainFrame::~MainFrame()
2970 {
2971   while (g_BSPFrontendCommands)
2972   {
2973     free (g_BSPFrontendCommands->data);
2974     g_BSPFrontendCommands = g_slist_remove (g_BSPFrontendCommands, g_BSPFrontendCommands->data);
2975   }
2976 }
2977
2978 void MainFrame::ReleaseContexts ()
2979 {
2980   if (m_pXYWnd)
2981     m_pXYWnd->DestroyContext ();
2982   if (m_pYZWnd)
2983     m_pYZWnd->DestroyContext ();
2984   if (m_pXZWnd)
2985     m_pXZWnd->DestroyContext ();
2986   if (m_pCamWnd)
2987     m_pCamWnd->DestroyContext ();
2988   if (m_pTexWnd)
2989     m_pTexWnd->DestroyContext ();
2990   if (m_pZWnd)
2991     m_pZWnd->DestroyContext ();
2992 }
2993
2994 void MainFrame::CreateContexts ()
2995 {
2996   if (m_pCamWnd)
2997     m_pCamWnd->CreateContext ();
2998   if (m_pXYWnd)
2999     m_pXYWnd->CreateContext ();
3000   if (m_pYZWnd)
3001     m_pYZWnd->CreateContext ();
3002   if (m_pXZWnd)
3003     m_pXZWnd->CreateContext ();
3004   if (m_pTexWnd)
3005     m_pTexWnd->CreateContext ();
3006   if (m_pZWnd)
3007     m_pZWnd->CreateContext ();
3008 }
3009
3010 static void Sys_Iconify (GtkWidget *w)
3011 {
3012   // we might not have been realized yet
3013   if (w->window == NULL)
3014     return;
3015
3016   if (!GTK_WIDGET_MAPPED (w))
3017     return;
3018
3019 #if defined (__linux__) || defined (__APPLE__)
3020   Sys_FPrintf(SYS_WRN, "FIXME: Sys_Iconify\n");
3021 #if 0
3022   XWindowAttributes xattr;
3023   GdkWindowPrivate *Private;
3024
3025   Private = (GdkWindowPrivate*)w->window;
3026   g_object_set_data (G_OBJECT (w), "was_mapped", GINT_TO_POINTER (0));
3027
3028   if (!Private->destroyed)
3029   {
3030     xattr.map_state = IsUnmapped;
3031     XGetWindowAttributes(Private->xdisplay, Private->xwindow, &xattr);
3032
3033     if (xattr.map_state != IsUnmapped)
3034       g_object_set_data (G_OBJECT (w), "was_mapped", GINT_TO_POINTER (1));
3035
3036     XIconifyWindow (Private->xdisplay, Private->xwindow, 0);
3037   }
3038 #endif
3039 #endif
3040
3041 #ifdef _WIN32
3042   ShowWindow ((HWND)GDK_WINDOW_HWND (w->window), SW_MINIMIZE);
3043 #endif
3044 }
3045
3046 static void Sys_Restore (GtkWidget *w)
3047 {
3048   // we might not have been realized yet
3049   if (w->window == NULL)
3050     return;
3051
3052   if (!GTK_WIDGET_VISIBLE (w))
3053     return;
3054
3055 #if defined (__linux__) || defined (__APPLE__)
3056   Sys_FPrintf(SYS_WRN, "FIXME: Sys_Restore\n");
3057   #if 0
3058   XWindowAttributes xattr;
3059   GdkWindowPrivate *Private;
3060
3061   Private = (GdkWindowPrivate*)w->window;
3062
3063   xattr.map_state = IsUnmapped;
3064   XGetWindowAttributes(Private->xdisplay, Private->xwindow, &xattr);
3065
3066   if (xattr.map_state == IsUnmapped)
3067     XMapRaised (Private->xdisplay, Private->xwindow);
3068   #endif
3069 #endif
3070
3071 #ifdef _WIN32
3072   ShowWindow ((HWND)GDK_WINDOW_HWND (w->window), SW_RESTORE);
3073 #endif
3074 }
3075
3076 #ifdef _DEBUG
3077 //#define DBG_SLEEP
3078 #endif
3079
3080 void RefreshModelSkin (GSList **pModels, entitymodel_t *model)
3081 {
3082   //++timo FIXME: the are some bogus entitymodel_t that appear in the list cause of buggy HasModel
3083   // so we avoid the fucked up ones, assuming they are at the end
3084   if (!model->strSkin)
3085   {
3086 #ifdef DBG_SLEEP
3087     Sys_Printf("Dropping model %p with empty skin in RefreshModelSkin\n", model);
3088 #endif
3089
3090     // and also keeping it so we have an actual count of empty models
3091     g_slist_append (*pModels, model);
3092     return;
3093   }
3094   // do we have this model already?
3095   if (g_slist_find (*pModels, model))
3096   {
3097 #ifdef DBG_SLEEP
3098
3099     // looks like we don't have the filename for the model, only the skin name and tris.. so we put the adress
3100     Sys_Printf("Already processed model: %p %s\n", model, ((GString *)model->strSkin)->str);
3101 #endif
3102     return;
3103   }
3104   model->nTextureBind = Texture_LoadSkin(((GString *)model->strSkin)->str, &model->nSkinWidth, &model->nSkinHeight );
3105   if (model->nTextureBind != -1)
3106     Sys_Printf("LOADED SKIN: %s\n", ((GString *)model->strSkin)->str );
3107   else
3108     Sys_Printf("Load skin failed: %s\n", ((GString *)model->strSkin)->str );
3109   *pModels = g_slist_append (*pModels, model);
3110 #ifdef DBG_SLEEP
3111   Sys_Printf("Processed model %p %s\n", model, ((GString *)model->strSkin)->str);
3112 #endif
3113 }
3114
3115 void MainFrame::OnSleep()
3116 {
3117   m_bSleeping ^= 1;
3118   if (m_bSleeping)
3119   {
3120     // useful when trying to debug crashes in the sleep code
3121     Sys_Printf("Going into sleep mode..\n");
3122
3123     Sys_Printf("Dispatching sleep msg...");
3124     DispatchRadiantMsg (RADIANT_SLEEP);
3125     Sys_Printf("Done.\n");
3126
3127     if (CurrentStyle() == eSplit)
3128       Sys_Iconify (m_pZWnd->m_pParent);
3129
3130     Sys_Iconify (m_pWidget);
3131     Select_Deselect();
3132     QERApp_FreeShaders ();
3133     g_bScreenUpdates = false;
3134
3135     // release contexts
3136     Sys_Printf("Releasing contexts...");
3137     ReleaseContexts();
3138     Sys_Printf("Done.\n");
3139
3140     // free all the skins in the caches
3141     // their GL resources have been freed but the structs are not, so Radiant would think they are still valid
3142     g_lstSkinCache.RemoveAll();
3143   } else
3144   {
3145     Sys_Printf("Waking up\n");
3146     if (CurrentStyle() == eSplit)
3147       Sys_Restore (m_pZWnd->m_pParent);
3148
3149     Sys_Restore (m_pWidget);
3150
3151     // create contexts
3152     Sys_Printf("Creating contexts...");
3153     CreateContexts();
3154     Sys_Printf("Done.\n");
3155
3156     Sys_Printf("Making current on camera...");
3157     m_pCamWnd->MakeCurrent ();
3158     Sys_Printf("Done.\n");
3159
3160     Sys_Printf("Reloading shaders...");
3161     // reload the shader scripts and textures
3162     QERApp_ReloadShaders ();
3163     // current shader
3164     // NOTE: we are kinda making it loop on itself, it will update the pShader and scroll the texture window
3165     Texture_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, NULL, false);
3166     Sys_Printf("Done.\n");
3167
3168     // rebuild the patches by setting the bDirty flag on them
3169     for (brush_t* b=active_brushes.next ; b != &active_brushes ; b=b->next)
3170     {
3171       if (b->patchBrush)
3172         b->pPatch->bDirty = true;
3173     }
3174
3175     Sys_Printf("Reloading skins...");
3176     // we have purged all the skins before going to sleep
3177     // to rebuild, go through everything that needs a skin and call Texture_LoadSkin
3178     // namely, all entitymodel_t
3179     // since there's no direct list we go through entities to get the eclass_t and from there the entitymodel_t
3180     // (a single eclass_t can reference several entitymodel_t)
3181     // FIXME: and what's up with md3Class then? what is it used for?
3182 /*
3183     eclass_t *e;
3184     entity_t *ent;
3185     GSList *Models = NULL;
3186     for (ent = entities.next; ent != &entities; ent = ent->next)
3187     {
3188       // if it's a model with skin then the fixedsize flag must be on
3189       // only if there IS a model .. we are not trying to load
3190       if (ent->eclass->fixedsize)
3191       {
3192         if (ent->eclass->model)
3193         {
3194 #ifdef DBG_SLEEP
3195           if (ent->md3Class)
3196             Sys_Printf("WARNING: unexpected ent->md3Class!=NULL with ent->eclass->model!=NULL\n");
3197 #endif
3198           entitymodel_t *model;
3199           for (model = ent->eclass->model; model; model=model->pNext)
3200             RefreshModelSkin (&Models, model);
3201         } else if (ent->md3Class)
3202         {
3203           entitymodel_t *model;
3204           for (model = ent->md3Class->model; model; model=model->pNext)
3205             RefreshModelSkin (&Models, model);
3206         }
3207 #ifdef DBG_SLEEP
3208         else
3209           Sys_Printf("WARNING: entity %p %s with fixedsize and no model no md3Class\n", ent, ent->eclass->name);
3210 #endif
3211       }
3212     }
3213 #ifdef DBG_SLEEP
3214     for (e = g_md3Cache; e ; e = e->next)
3215     {
3216       entitymodel_t *model;
3217       for (model = e->model; model; model=model->pNext)
3218         if (!g_slist_find (Models, model))
3219         {
3220           Sys_Printf("model %p ", model);
3221           if (model->strSkin)
3222             Sys_Printf("%s not found in main loop\n", ((GString *)model->strSkin)->str);
3223           else
3224             Sys_Printf("not found in main loop (no skin)\n");
3225         }
3226     }
3227 #endif
3228     // clean the model list
3229     g_slist_free (Models);
3230 */
3231     Sys_Printf("Done.\n");
3232
3233     // bring back the GL font
3234     gtk_glwidget_create_font (m_pCamWnd->GetWidget ());
3235
3236     g_bScreenUpdates = true;
3237
3238     Sys_Printf("Dispatching wake msg...");
3239     DispatchRadiantMsg (RADIANT_WAKEUP);
3240     Sys_Printf("Done\n");
3241   }
3242 }
3243
3244 void WINAPI QERApp_Sleep()
3245 {
3246   g_pParentWnd->OnSleep();
3247 }
3248
3249 /*!
3250 NOTE TTimo
3251 the exit path is a bit complicated, I guess we have to run the window pos saving in OnDelete
3252 and not in OnDestroy because the info may be lost already?
3253 \todo try sinking OnDelete into OnDestroy and see if it breaks anything
3254 */
3255 void MainFrame::OnDelete ()
3256 {
3257   save_window_pos(m_pWidget, g_PrefsDlg.mWindowInfo.position);
3258
3259   // surface inspector and patch inspector
3260   save_window_pos (g_dlgSurface.GetWidget(), g_PrefsDlg.mWindowInfo.posSurfaceWnd);
3261   save_window_pos (g_PatchDialog.GetWidget(), g_PrefsDlg.mWindowInfo.posPatchWnd);
3262
3263   // entity inspector / group dialog
3264   // NOTE TTimo do we have to save a different window depending on the view mode?
3265   save_window_pos (g_pGroupDlg->m_pWidget, g_PrefsDlg.mWindowInfo.posEntityWnd);
3266
3267   if (g_PrefsDlg.m_bFloatingZ)
3268     save_window_pos (m_pZWnd->m_pParent, g_PrefsDlg.mWindowInfo.posZWnd);
3269   else
3270     g_PrefsDlg.mWindowInfo.nZFloatWidth = GTK_PANED (m_pSplits[0])->child1_size;
3271
3272   if (CurrentStyle() == eFloating)
3273   {
3274     save_window_pos (m_pCamWnd->m_pParent, g_PrefsDlg.mWindowInfo.posCamWnd);
3275     save_window_pos (m_pXYWnd->m_pParent, g_PrefsDlg.mWindowInfo.posXYWnd);
3276     save_window_pos (m_pXZWnd->m_pParent, g_PrefsDlg.mWindowInfo.posXZWnd);
3277     save_window_pos (m_pYZWnd->m_pParent, g_PrefsDlg.mWindowInfo.posYZWnd);
3278   }
3279
3280   g_PrefsDlg.mWindowInfo.nState = gdk_window_get_state(g_pParentWnd->m_pWidget->window);
3281 }
3282
3283 void MainFrame::OnDestroy ()
3284 {
3285   // shut down console output first
3286   // (we'll still get the info if we are running a log file anyway)
3287   g_qeglobals_gui.d_edit = NULL;
3288
3289 #ifdef _DEBUG
3290   Sys_Printf("MainFrame::OnDestroy\n");
3291 #endif
3292   if (s_idle_id)
3293     gtk_timeout_remove (s_idle_id);
3294   if (m_nTimer)
3295     gtk_timeout_remove (m_nTimer);
3296
3297   if (!g_qeglobals.disable_ini)
3298   {
3299     Sys_Printf("Start writing prefs\n");
3300     Sys_Printf("MRU_Save... ");
3301     MRU_Save ();
3302     Sys_Printf("OK\n");
3303
3304     gpointer w;
3305
3306     w = g_object_get_data (G_OBJECT (g_pGroupDlg->m_pWidget), "split1");
3307     g_PrefsDlg.mWindowInfo.nEntitySplit1 = GTK_PANED (w)->child1_size;
3308     w = g_object_get_data (G_OBJECT (g_pGroupDlg->m_pWidget), "split2");
3309     g_PrefsDlg.mWindowInfo.nEntitySplit2 = GTK_PANED (w)->child1_size;
3310
3311     if (!FloatingGroupDialog())
3312     {
3313       GtkWidget *vsplit, *hsplit, *vsplit2, *hsplit2;
3314
3315       vsplit = m_pSplits[0];
3316       vsplit2 = m_pSplits[1];
3317       hsplit = m_pSplits[2];
3318       hsplit2 = m_pSplits[3];
3319
3320       g_PrefsDlg.mWindowInfo.nXYHeight  = GTK_PANED (vsplit)->child1_size;
3321       g_PrefsDlg.mWindowInfo.nXYWidth   = GTK_PANED (hsplit2)->child1_size;
3322
3323       if(CurrentStyle() == eRegular)
3324         g_PrefsDlg.mWindowInfo.nZWidth = GTK_PANED (hsplit)->child1_size;
3325       else
3326         g_PrefsDlg.mWindowInfo.nCamWidth = GTK_PANED (hsplit)->child1_size;
3327
3328       g_PrefsDlg.mWindowInfo.nCamHeight = GTK_PANED (vsplit2)->child1_size;
3329     } else
3330     {
3331       if (g_PrefsDlg.m_bFloatingZ || CurrentStyle() == eSplit)
3332       {
3333         if (GTK_WIDGET_VISIBLE (m_pZWnd->m_pParent))
3334           g_PrefsDlg.m_bZVis = TRUE;
3335         else
3336           g_PrefsDlg.m_bZVis = FALSE;
3337       }
3338     }
3339     g_PrefsDlg.SavePrefs();
3340     Sys_Printf("Done prefs\n");
3341   }
3342
3343   // spog - this may be better in another place..
3344   // deletes filters list and assigns g_qeglobals.d_savedinfo.filters = NULL
3345   g_qeglobals.d_savedinfo.filters = FilterListDelete(g_qeglobals.d_savedinfo.filters);
3346
3347   delete m_pXYWnd; m_pXYWnd = NULL;
3348   delete m_pYZWnd; m_pYZWnd = NULL;
3349   delete m_pXZWnd; m_pXZWnd = NULL;
3350   delete m_pZWnd; m_pZWnd = NULL;
3351   delete m_pTexWnd; m_pTexWnd = NULL;
3352   delete m_pCamWnd; m_pCamWnd = NULL;
3353
3354   if (g_pGroupDlg->m_pWidget)
3355   {
3356     //!\todo fix "Gtk-CRITICAL **: file gtknotebook.c: line 4643 (gtk_notebook_get_tab_label): assertion `GTK_IS_WIDGET (child)' failed"
3357     gtk_widget_destroy (g_pGroupDlg->m_pWidget);
3358     g_pGroupDlg->m_pWidget = NULL;
3359   }
3360
3361   if (strcmpi(currentmap, "unnamed.map") != 0)
3362   {
3363     g_PrefsDlg.m_strLastMap = currentmap;
3364     g_PrefsDlg.SavePrefs ();
3365   }
3366   Sys_Printf("CleanUpEntities...");
3367   CleanUpEntities();
3368   Sys_Printf("Done.\n");
3369
3370   Sys_Printf("Releasing brushes...");
3371   while (active_brushes.next != &active_brushes)
3372     Brush_Free (active_brushes.next, false);
3373   while (selected_brushes.next != &selected_brushes)
3374     Brush_Free (selected_brushes.next, false);
3375   while (filtered_brushes.next != &filtered_brushes)
3376     Brush_Free (filtered_brushes.next, false);
3377   Sys_Printf("Done.\n");
3378
3379   Sys_Printf("Releasing entities...");
3380   while (entities.next != &entities)
3381     Entity_Free (entities.next);
3382   Sys_Printf("Done.\n");
3383
3384   epair_t* pEPair = g_qeglobals.d_project_entity->epairs;
3385   while (pEPair)
3386   {
3387     epair_t* pNextEPair = pEPair->next;
3388     free (pEPair->key);
3389     free (pEPair->value);
3390     free (pEPair);
3391     pEPair = pNextEPair;
3392   }
3393
3394   entity_t* pEntity = g_qeglobals.d_project_entity->next;
3395   while (pEntity != NULL && pEntity != g_qeglobals.d_project_entity)
3396   {
3397     entity_t* pNextEntity = pEntity->next;
3398     Entity_Free(pEntity);
3399     pEntity = pNextEntity;
3400   }
3401
3402   Sys_Printf("Freeing world entity...");
3403   if (world_entity)
3404     Entity_Free(world_entity);
3405   Sys_Printf("Done.\n");
3406
3407   Sys_Printf("Shutdown VFS...");
3408   vfsShutdown ();
3409   Sys_Printf("Done.\n");
3410
3411   Sys_Printf("FreeShaders...");
3412   QERApp_FreeShaders();
3413   Sys_Printf("Done.\n");
3414 }
3415
3416 // TTimo: now using profile.cpp code
3417 void MainFrame::LoadCommandMap()
3418 {
3419   FILE *f;
3420   CString strINI;
3421   bool bUserCmdList = false;
3422   int nLen;
3423   // verbose a little: count of user commands we recognized
3424   int iCount = 0;
3425   int iOverrideCount = 0;
3426   int j;
3427
3428
3429 #if defined (__linux__) || defined (__APPLE__)
3430   strINI = g_PrefsDlg.m_rc_path->str;
3431 #elif defined(WIN32)
3432   strINI = g_strGameToolsPath;
3433 #else
3434 #error "WTF are you compiling this on"
3435 #endif
3436   AddSlash (strINI);
3437   strINI += "shortcuts.ini";
3438
3439   f = fopen (strINI.GetBuffer(), "r");
3440   if (f != NULL)
3441   {
3442     fclose(f);
3443     // loop through all the commands
3444     for (int i = 0; i < g_nCommandCount; i++)
3445     {
3446       char value[1024];
3447       if (read_var( strINI.GetBuffer(), "Commands", g_Commands[i].m_strCommand, value ))
3448       {
3449         if (!bUserCmdList)
3450         {
3451           Sys_Printf("Found user's shortcuts list at %s\n", strINI.GetBuffer() );
3452           bUserCmdList = true;
3453         }
3454         CString strBuff;
3455         strBuff = value;
3456         strBuff.TrimLeft();
3457         strBuff.TrimRight();
3458         strBuff.MakeLower();
3459         int nSpecial = strBuff.Find("+alt");
3460         g_Commands[i].m_nModifiers = 0;
3461         if (nSpecial >= 0)
3462         {
3463           g_Commands[i].m_nModifiers |= RAD_ALT;
3464           FindReplace(strBuff, "+alt", "");
3465         }
3466         nSpecial = strBuff.Find("+ctrl");
3467         if (nSpecial >= 0)
3468         {
3469           g_Commands[i].m_nModifiers |= RAD_CONTROL;
3470           FindReplace(strBuff, "+ctrl", "");
3471         }
3472         nSpecial = strBuff.Find("+shift");
3473         if (nSpecial >= 0)
3474         {
3475           g_Commands[i].m_nModifiers |= RAD_SHIFT;
3476           FindReplace(strBuff, "+shift", "");
3477         }
3478         strBuff.TrimLeft();
3479         strBuff.TrimRight();
3480         strBuff.MakeUpper();
3481         // strBuff has been cleaned of it's modifiers .. switch between a regular key and a virtual one
3482         // based on length
3483         nLen = strBuff.GetLength();
3484         if (nLen == 1) // most often case.. deal with first
3485         {
3486           g_Commands[i].m_nKey = __toascii(strBuff.GetAt(0));
3487           iCount++;
3488         } else // special key
3489         {
3490           for (j = 0; j < g_nKeyCount; j++)
3491           {
3492             if (strBuff.CompareNoCase(g_Keys[j].m_strName) == 0)
3493             {
3494               g_Commands[i].m_nKey = g_Keys[j].m_nVKKey;
3495               iCount++;
3496               break;
3497             }
3498           }
3499           if (j == g_nKeyCount)
3500           {
3501             Sys_Printf("WARNING: failed to parse user command %s\n", value);
3502             continue;
3503           }
3504         }
3505         // maybe this new shortcut is overriding another one
3506         // then we need to disable the other binded key
3507         for (j = 0; j < g_nCommandCount; j++)
3508         {
3509           if (j == i)
3510             continue;
3511           if (g_Commands[i].m_nKey == g_Commands[j].m_nKey && g_Commands[i].m_nModifiers == g_Commands[j].m_nModifiers)
3512           {
3513             // found!
3514             g_Commands[j].m_nKey = 0;
3515             // verbose
3516             iOverrideCount++;
3517             // it's the only one
3518             break;
3519           }
3520         }
3521       }
3522     }
3523     if (iOverrideCount)
3524       Sys_Printf("User's command list overrides %d default commands\n", iOverrideCount);
3525     Sys_Printf("Parsed %d custom shortcuts\n", iCount );
3526   }
3527   else
3528     Sys_Printf("Looked for a '%s' keyboard shortcuts file, not found\n", strINI.GetBuffer());
3529 }
3530
3531 // TTimo: an m_nKey can be set to zero if there's no shorcut binded
3532 // we also output the count of commands that are not binded .. dunno if it's much use ..
3533 // (non-binded keys are usually keys that were defined by shortcuts overriden by user prefs)
3534 void MainFrame::ShowMenuItemKeyBindings(GtkWidget* window)
3535 {
3536   //!\todo Find a better way to get the global accelerator group..
3537   GtkAccelGroup *accel = GTK_ACCEL_GROUP(gtk_accel_groups_from_object(G_OBJECT(window))->data);
3538   gpointer item;
3539   guint mods;
3540   int i;
3541   int iCount = 0;
3542
3543   for (i = 0; i < g_nCommandCount; i++)
3544   {
3545     if (g_Commands[i].m_nKey == 0)
3546     {
3547       iCount++;
3548       continue;
3549     }
3550
3551     item = g_object_get_data (G_OBJECT (m_pWidget), g_Commands[i].m_strMenu);
3552     if (item == NULL)
3553     {
3554       Sys_FPrintf (SYS_WRN, "WARNING: keyboard shortcuts init, no menu item found for command: \"%s\"\n",
3555                    g_Commands[i].m_strCommand);
3556       continue;
3557     }
3558
3559     mods = 0;
3560     if (g_Commands[i].m_nModifiers)     // are there modifiers present?
3561     {
3562       if (g_Commands[i].m_nModifiers & RAD_SHIFT)
3563         mods |= GDK_SHIFT_MASK;
3564       if (g_Commands[i].m_nModifiers & RAD_ALT)
3565         mods |= GDK_MOD1_MASK;
3566       if (g_Commands[i].m_nModifiers & RAD_CONTROL)
3567         mods |= GDK_CONTROL_MASK;
3568     }
3569
3570     // GTK won't add accelerators for some keys (ex.: delete), so we have to do it manually
3571     if (gtk_accelerator_valid (g_Commands[i].m_nKey, (GdkModifierType)mods))
3572     {
3573 #ifdef DBG_KBD
3574       // NOTE TTimo this is the important place where all the shortcuts are binded
3575       Sys_Printf("Calling gtk_widget_add_accelerator on command: %s menu: %s key: %d mods: %d\n", g_Commands[i].m_strCommand, g_Commands[i].m_strMenu, g_Commands[i].m_nKey, mods);
3576 #endif
3577       gtk_widget_add_accelerator (GTK_WIDGET (item), "activate", accel, g_Commands[i].m_nKey,
3578                                   (GdkModifierType)mods, GTK_ACCEL_VISIBLE);
3579     } else
3580     {
3581       GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (GTK_BIN (item)->child);
3582       GString *gstring;
3583       gboolean had_mod;
3584
3585       g_free (accel_label->accel_string);
3586       accel_label->accel_string = NULL;
3587
3588       gstring = g_string_new (accel_label->accel_string);
3589       g_string_append (gstring, "   ");
3590
3591       had_mod = FALSE;
3592       if (mods & GDK_SHIFT_MASK)
3593       {
3594         g_string_append (gstring, "Shft");
3595         had_mod = TRUE;
3596       }
3597       if (mods & GDK_CONTROL_MASK)
3598       {
3599         if (had_mod)
3600           g_string_append (gstring, "+");
3601         g_string_append (gstring, "Ctl");
3602         had_mod = TRUE;
3603       }
3604       if (mods & GDK_MOD1_MASK)
3605       {
3606         if (had_mod)
3607           g_string_append (gstring, "+");
3608         g_string_append (gstring, "Alt");
3609         had_mod = TRUE;
3610       }
3611
3612       if (had_mod)
3613         g_string_append (gstring, "+");
3614       if (g_Commands[i].m_nKey < 0x80 || (g_Commands[i].m_nKey > 0x80 && g_Commands[i].m_nKey <= 0xff))
3615       {
3616         switch (g_Commands[i].m_nKey)
3617         {
3618         case ' ':
3619           g_string_append (gstring, "Space");
3620           break;
3621         case '\\':
3622           g_string_append (gstring, "Backslash");
3623           break;
3624         default:
3625           g_string_append_c (gstring, toupper (g_Commands[i].m_nKey));
3626           break;
3627         }
3628       } else
3629       {
3630         gchar *tmp;
3631
3632         tmp = gtk_accelerator_name (g_Commands[i].m_nKey, (GdkModifierType)0);
3633         if (tmp[0] != 0 && tmp[1] == 0)
3634           tmp[0] = toupper (tmp[0]);
3635         g_string_append (gstring, tmp);
3636         g_free (tmp);
3637       }
3638
3639       g_free (accel_label->accel_string);
3640       accel_label->accel_string = gstring->str;
3641       g_string_free (gstring, FALSE);
3642
3643       if (!accel_label->accel_string)
3644         accel_label->accel_string = g_strdup ("");
3645
3646       gtk_widget_queue_resize (GTK_WIDGET (accel_label));
3647     }
3648   }
3649
3650   if (iCount)
3651     Sys_Printf("%d commands not bound to a key\n", iCount);
3652 }
3653
3654 void MainFrame::CreateQEChildren()
3655 {
3656   // load the project file
3657   if (g_argc > 1)
3658   {
3659     Sys_Printf("loading project file from the command line: %s\n", g_argv[1]);
3660     if (!QE_LoadProject(g_argv[1]))
3661       Error("Unable to load project file %s\n", g_argv[1]);
3662   }
3663   else
3664   {
3665     const char* filename = NULL;
3666     char buf[PATH_MAX];
3667     const char *r;
3668     bool bTriedTemplate = false;
3669
3670     if (g_PrefsDlg.m_nLastProjectVer != 0 && g_PrefsDlg.m_nLastProjectVer != PROJECT_VERSION) {
3671       // we need to regenerate from template
3672       Sys_Printf("last project has version %d, this binary wants version %d - regenerating from the template\n", g_PrefsDlg.m_nLastProjectVer, PROJECT_VERSION);
3673       g_PrefsDlg.m_strLastProject = "";
3674     }
3675
3676     r = g_PrefsDlg.m_strLastProject.GetBuffer();
3677
3678     while(r == NULL || *r == '\0' || access(r, R_OK) != 0 || !QE_LoadProject(r))
3679     {
3680       if(!bTriedTemplate)
3681       {
3682         // try default project location
3683         bTriedTemplate = true;
3684         // for all OSes, we look for the template in the base installation (no homepath here)
3685         strcpy(buf, g_pGameDescription->mEnginePath.GetBuffer());
3686         strcat(buf, g_pGameDescription->mBaseGame.GetBuffer());
3687         strcat(buf, "/scripts/");
3688         strcat(buf, PROJECT_TEMPLATE_NAME);
3689         r = buf;
3690       }
3691       else
3692       {
3693         gtk_MessageBox (NULL, "Failed to load project file.\nPlease enter a valid project file.", "Load Project");
3694
3695         filename = file_dialog (m_pWidget, TRUE, "Choose Project File", buf, "project");
3696         if (filename != NULL)
3697           r = filename;
3698         else
3699           Error("Cannot continue without loading a project...");
3700       }
3701     }
3702   }
3703
3704   QE_Init ();
3705 }
3706
3707 void MainFrame::OnTimer()
3708 {
3709   GdkModifierType mask;
3710
3711   gdk_window_get_pointer (NULL, NULL, NULL, &mask);
3712
3713   if ((mask & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK)) == 0)
3714   {
3715     QE_CountBrushesAndUpdateStatusBar();
3716     QE_CheckAutoSave();
3717   }
3718
3719   // see MainFrame::UpdateStatusText below
3720   if (m_bNeedStatusUpdate)
3721   {
3722     for (int n = 0; n < 6; n++)
3723     {
3724       if (m_strStatus[n].GetLength() >= 0 && m_pStatusLabel[n] != NULL)
3725         gtk_label_set_text (GTK_LABEL (m_pStatusLabel[n]), m_strStatus[n]);
3726     }
3727     m_bNeedStatusUpdate = false;
3728   }
3729 }
3730
3731 void MainFrame::UpdateStatusText()
3732 {
3733   m_bNeedStatusUpdate = true;
3734 }
3735
3736 void MainFrame::SetStatusText(int nPane, const char* pText)
3737 {
3738   if (pText && nPane <= 5 && nPane >= 0)
3739   {
3740     m_strStatus[nPane] = pText;
3741     UpdateStatusText();
3742   }
3743 }
3744 void MainFrame::SetButtonMenuStates()
3745 {
3746   GtkWidget *item;
3747   g_bIgnoreCommands++;
3748
3749   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showangles"));
3750   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_angles);
3751   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_shownames"));
3752   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_names);
3753   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showcoordinates"));
3754   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_coordinates);
3755   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showoutline"));
3756   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_outline);
3757   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_selection_nooutline"));
3758   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_ZBUF));
3759   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showaxes"));
3760   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.d_savedinfo.show_axis);
3761   //item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showpath"));
3762   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3763                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) ? FALSE : TRUE);
3764   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_clusterportals"));
3765   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3766                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLUSTERPORTALS) != 0);
3767   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_lightgrid"));
3768   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3769                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTGRID) != 0);
3770   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_world"));
3771   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3772                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_WORLD) != 0);
3773   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_entities"));
3774   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3775                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_ENT) != 0);
3776   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_areaportals"));
3777   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3778                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_AREAPORTALS) != 0);
3779   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_translucent"));
3780   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3781                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_TRANSLUCENT) != 0);
3782   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_liquids"));
3783   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3784                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIQUIDS) != 0);
3785   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_caulk"));
3786   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3787                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CAULK) != 0);
3788   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_clips"));
3789   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3790                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLIP) != 0);
3791   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_botclips"));
3792   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3793                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_BOTCLIP) != 0);
3794   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_structural"));
3795   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3796                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_STRUCTURAL) != 0);
3797   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_paths"));
3798   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3799                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_PATHS) != 0);
3800   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_clusterportals"));
3801   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3802                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CLUSTERPORTALS) != 0);
3803   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_lightgrid"));
3804   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3805                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTGRID) != 0);
3806   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_lights"));
3807   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3808                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_LIGHTS) != 0);
3809   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_patches"));
3810   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3811                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_CURVES) != 0);
3812   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_details"));
3813   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3814                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_DETAILS) != 0);
3815   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_hintsskips"));
3816   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3817                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_HINTSSKIPS) != 0);
3818   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_models"));
3819   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3820                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_MODELS) != 0);
3821   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_triggers"));
3822   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
3823                                   (g_qeglobals.d_savedinfo.exclude & EXCLUDE_TRIGGERS) != 0);
3824   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_toggle_lock"));
3825   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bTextureLock) ? TRUE : FALSE);
3826   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_toggle_rotatelock"));
3827   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bRotateLock) ? TRUE : FALSE);
3828   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_cubicclipping"));
3829   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bCubicClipping) ? TRUE : FALSE);
3830   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_opengllighting"));
3831   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bGLLighting) ? TRUE : FALSE);
3832   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
3833   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (!g_PrefsDlg.m_bNoClamp) ? TRUE : FALSE);
3834
3835   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_view_cubicclipping"));
3836   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bCubicClipping) ? TRUE : FALSE);
3837   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_dontselectmodel"));
3838   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bSelectModels) ? FALSE : TRUE);
3839
3840   if (!g_pGameDescription->mNoPatch)
3841   {
3842     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_dontselectcurve"));
3843     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bSelectCurves) ? FALSE : TRUE);
3844
3845     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_showboundingbox"));
3846     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchShowBounds) ? TRUE : FALSE);
3847     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_weld"));
3848     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchWeld) ? TRUE : FALSE);
3849     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_drilldown"));
3850     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchDrillDown) ? TRUE : FALSE);
3851   }
3852
3853   int id, n = g_PrefsDlg.m_nTextureScale;
3854   switch (n)
3855   {
3856   case 10 : id = ID_TEXTURES_TEXTUREWINDOWSCALE_10; break;
3857   case 25 : id = ID_TEXTURES_TEXTUREWINDOWSCALE_25; break;
3858   case 50 : id = ID_TEXTURES_TEXTUREWINDOWSCALE_50; break;
3859   case 200 : id = ID_TEXTURES_TEXTUREWINDOWSCALE_200; break;
3860   default : id = ID_TEXTURES_TEXTUREWINDOWSCALE_100; break;
3861   }
3862   SetTextureScale (id);
3863
3864   // FIXME TTimo cleaned up .. the right place to do this in QE_LoadProject?
3865 /*
3866   if (g_qeglobals.d_project_entity)
3867   {
3868     FillTextureMenu();      // redundant but i'll clean it up later.. yeah right..
3869     FillBSPMenu();
3870   }
3871   */
3872   g_bIgnoreCommands--;
3873 }
3874
3875 void MainFrame::UpdateWindows(int nBits)
3876 {
3877   if (!g_bScreenUpdates)
3878     return;
3879 #ifdef DBG_WINDOWPOS
3880   static int bean_count = 0;
3881   char bean_buf[100];
3882   sprintf(bean_buf,"UpdateWindows %d",bean_count);
3883   CheckWatchit(bean_buf);
3884   bean_count++;
3885 #endif
3886
3887   if (nBits & (W_XY | W_XY_OVERLAY))
3888   {
3889     if (m_pXYWnd)
3890       m_pXYWnd->RedrawWindow ();
3891     if (m_pXZWnd)
3892       m_pXZWnd->RedrawWindow ();
3893     if (m_pYZWnd)
3894       m_pYZWnd->RedrawWindow ();
3895   }
3896
3897   if (nBits & W_CAMERA || ((nBits & W_CAMERA_IFON) && m_bCamPreview))
3898   {
3899     if (m_pCamWnd)
3900       m_pCamWnd->RedrawWindow ();
3901   }
3902
3903   if (nBits & (W_Z | W_Z_OVERLAY))
3904   {
3905     if (m_pZWnd)
3906       m_pZWnd->RedrawWindow ();
3907   }
3908
3909   if (nBits & W_TEXTURE)
3910   {
3911     if (m_pTexWnd)
3912       m_pTexWnd->RedrawWindow ();
3913   }
3914 #ifdef DBG_WINDOWPOS
3915   sprintf(bean_buf,"%d (end UpdateWidows)",bean_count);
3916   CheckWatchit(bean_buf);
3917 #endif
3918 }
3919
3920 void MainFrame::RoutineProcessing()
3921 {
3922 #ifdef DBG_WINDOWPOS
3923   static int bean_count = 0;
3924   char bean_buf[100];
3925   sprintf(bean_buf,"RoutineProcessing %d",bean_count);
3926   CheckWatchit(bean_buf);
3927   bean_count++;
3928 #endif
3929
3930   if (m_bDoLoop)
3931   {
3932     double time = 0.0;
3933     double oldtime = 0.0;
3934     double delta= 0.0;
3935
3936 /*    // checking KeyState works right
3937     static short a1,a2;
3938     a2 = GetKeyState(VK_MENU);
3939     if (a1!=a2)
3940     {
3941       Sys_Printf("VK_MENU: %d\n",a2);
3942       a1 = a2;
3943     }
3944     static short b1,b2;
3945     b2 = GetKeyState(VK_UP);
3946     if (b1!=b2)
3947     {
3948       Sys_Printf("VK_UP: %d\n",b2);
3949       b1 = b2;
3950     } */
3951
3952     time = Sys_DoubleTime ();
3953     delta = time - oldtime;
3954     oldtime = time;
3955     if (delta > 0.2)
3956       delta = 0.2;
3957
3958     // update the BSP process watcher
3959     if (m_pWatchBSP)
3960       m_pWatchBSP->RoutineProcessing();
3961
3962     // run time dependant behavior
3963     if (m_pCamWnd)
3964       m_pCamWnd->Cam_MouseControl(delta);
3965
3966     if (g_nUpdateBits)
3967     {
3968       int nBits = g_nUpdateBits;      // this is done to keep this routine from being
3969       g_nUpdateBits = 0;              // re-entered due to the paint process.. only
3970       UpdateWindows(nBits);           // happens in rare cases but causes a stack overflow
3971     }
3972 /*
3973     // Enable/disable the menu items
3974     GtkWidget *item;
3975
3976     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_cameraupdate"));
3977     gtk_widget_set_sensitive (item, (m_bCamPreview == false));
3978     if (!g_PrefsDlg.m_bWideToolbar)
3979     {
3980       item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_view_cameraupdate"));
3981       gtk_widget_set_sensitive (item, (m_bCamPreview == false));
3982     }
3983     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_edit_undo"));
3984     gtk_widget_set_sensitive (item, Undo_UndoAvailable());
3985     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_edit_redo"));
3986     gtk_widget_set_sensitive (item, Undo_RedoAvailable());
3987     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_file_saveregion"));
3988     gtk_widget_set_sensitive (item, region_active);
3989     g_bIgnoreCommands++;
3990     // update the toolbar before displaying the menu:
3991     // show in use check box
3992     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_showinuse"));
3993     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), !g_bShowAllShaders);
3994     // show all check box
3995     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_showall"));
3996     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_bShowAllShaders);
3997     g_bIgnoreCommands--;
3998     */
3999   }
4000 #ifdef DBG_WINDOWPOS
4001   sprintf(bean_buf,"%d (end RoutineProcessing)",bean_count);
4002   CheckWatchit(bean_buf);
4003 #endif
4004 }
4005
4006 void MainFrame::DoWatchBSP()
4007 {
4008   // network monitoring of the BSP process
4009   if (!m_pWatchBSP)
4010     m_pWatchBSP = new CWatchBSP();
4011 }
4012
4013 void MainFrame::CleanPlugInMenu()
4014 {
4015   GtkWidget *menu, *sep;
4016   GList *lst;
4017
4018   // delete everything after the separator
4019   menu = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_plugin"));
4020   sep = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_plugin_separator"));
4021   m_nNextPlugInID = ID_PLUGIN_START;
4022
4023   lst = g_list_find (gtk_container_children (GTK_CONTAINER (menu)), sep);
4024   while (lst->next)
4025   {
4026     gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (lst->next->data));
4027     lst = g_list_find (gtk_container_children (GTK_CONTAINER (menu)), sep);
4028   }
4029 }
4030
4031 void MainFrame::AddPlugInMenuItem(IPlugIn* pPlugIn)
4032 {
4033   GtkWidget *menu, *item, *parent;
4034   const char *menuText;
4035
4036   parent = gtk_menu_item_new_with_label (pPlugIn->getMenuName());
4037   gtk_widget_show (parent);
4038   gtk_container_add (GTK_CONTAINER (g_object_get_data (G_OBJECT (m_pWidget), "menu_plugin")), parent);
4039
4040   int nCount = pPlugIn->getCommandCount();
4041   if (nCount > 0)
4042   {
4043     menu = gtk_menu_new ();
4044     while (nCount > 0)
4045     {
4046       menuText = pPlugIn->getCommand(--nCount);
4047       if (menuText != NULL && strlen(menuText) > 0)
4048       {
4049         if (!strcmp(menuText, "-"))
4050         {
4051           item = gtk_menu_item_new ();
4052           gtk_widget_set_sensitive (item, FALSE);
4053         } else
4054         {
4055           item = gtk_menu_item_new_with_label (menuText);
4056           gtk_signal_connect (GTK_OBJECT (item), "activate",
4057                               GTK_SIGNAL_FUNC (HandleCommand), GINT_TO_POINTER (m_nNextPlugInID));
4058         }
4059         gtk_widget_show (item);
4060         gtk_container_add (GTK_CONTAINER (menu), item);
4061         pPlugIn->addMenuID(m_nNextPlugInID++);
4062       }
4063     }
4064     gtk_menu_item_set_submenu (GTK_MENU_ITEM (parent), menu);
4065   }
4066 }
4067
4068 void MainFrame::OnPlugIn(unsigned int nID, char* str)
4069 {
4070   m_PlugInMgr.Dispatch(nID, str);
4071 }
4072
4073 inline GtkToolbarChildType gtktoolbarchildtype_for_toolbarbuttontype(IToolbarButton::EType type)
4074 {
4075   switch(type)
4076   {
4077   case IToolbarButton::eSpace:
4078     return GTK_TOOLBAR_CHILD_SPACE;
4079   case IToolbarButton::eButton:
4080     return GTK_TOOLBAR_CHILD_BUTTON;
4081   case IToolbarButton::eToggleButton:
4082     return GTK_TOOLBAR_CHILD_TOGGLEBUTTON;
4083   case IToolbarButton::eRadioButton:
4084     return GTK_TOOLBAR_CHILD_RADIOBUTTON;
4085   }
4086   Error("invalid toolbar button type");
4087   return (GtkToolbarChildType)0;
4088 }
4089
4090 void toolbar_insert(GtkWidget *toolbar, const char* image, const char* text, const char* tooltip, IToolbarButton::EType type, GtkSignalFunc handler, gpointer data)
4091 {
4092   GtkWidget *w, *pixmap;
4093   GdkPixmap *gdkpixmap;
4094   GdkBitmap *mask;
4095
4096   load_plugin_bitmap(image, (void **)&gdkpixmap, (void **)&mask);
4097   pixmap = gtk_pixmap_new (gdkpixmap, mask);
4098   gdk_pixmap_unref (gdkpixmap);
4099   gdk_pixmap_unref (mask);
4100   w = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar), gtktoolbarchildtype_for_toolbarbuttontype(type), NULL, text, tooltip, "", GTK_WIDGET (pixmap), handler, data);
4101 }
4102
4103 void SignalToolbarButton(GtkWidget *widget, gpointer data)
4104 {
4105   const_cast<const IToolbarButton*>(reinterpret_cast<IToolbarButton*>(data))->activate();
4106 }
4107
4108 void MainFrame::AddPlugInToolbarButton(const IToolbarButton* button)
4109 {
4110   GtkWidget*const toolbar = GTK_WIDGET(g_object_get_data (G_OBJECT (m_pWidget), "toolbar_plugin"));
4111   toolbar_insert(toolbar, button->getImage(), button->getText(), button->getTooltip(), button->getType(), GTK_SIGNAL_FUNC(SignalToolbarButton), reinterpret_cast<gpointer>(const_cast<IToolbarButton*>(button)));
4112 }
4113
4114 void MainFrame::OnSelectionSelectNudgedown()
4115 {
4116   NudgeSelection(3, g_qeglobals.d_gridsize);
4117 }
4118
4119 void MainFrame::OnSelectionSelectNudgeleft()
4120 {
4121   NudgeSelection(0, g_qeglobals.d_gridsize);
4122 }
4123
4124 void MainFrame::OnSelectionSelectNudgeright()
4125 {
4126   NudgeSelection(2, g_qeglobals.d_gridsize);
4127 }
4128
4129 void MainFrame::OnSelectionSelectNudgeup()
4130 {
4131   NudgeSelection(1, g_qeglobals.d_gridsize);
4132 }
4133
4134 void MainFrame::NudgeSelection(int nDirection, float fAmount)
4135 {
4136   if (ActiveXY()->RotateMode())
4137   {
4138     int nAxis = 0;
4139     if (ActiveXY()->GetViewType() == XY)
4140     {
4141       nAxis = 2;
4142     } else
4143       if (g_pParentWnd->ActiveXY()->GetViewType() == XZ)
4144     {
4145       nAxis = 1;
4146       fAmount = -fAmount;
4147     }
4148
4149     if (nDirection == 2 || nDirection == 3)
4150     {
4151       fAmount = -fAmount;
4152     }
4153
4154     float fDeg = -fAmount;
4155     float fAdj = fAmount;
4156
4157     g_pParentWnd->ActiveXY()->Rotation()[nAxis] += fAdj;
4158     CString strStatus;
4159     strStatus.Format("Rotation x:: %.1f  y:: %.1f  z:: %.1f", g_pParentWnd->ActiveXY()->Rotation()[0],
4160                      g_pParentWnd->ActiveXY()->Rotation()[1], g_pParentWnd->ActiveXY()->Rotation()[2]);
4161     g_pParentWnd->SetStatusText(2, strStatus);
4162     Select_RotateAxis(nAxis, fDeg, false, true);
4163     Sys_UpdateWindows (W_ALL);
4164   } else
4165     if (ActiveXY()->ScaleMode())
4166   {
4167     if (nDirection == 0 || nDirection == 3)
4168     {
4169       fAmount = -fAmount;
4170     }
4171     vec3_t v;
4172     v[0] = v[1] = v[2] = 1.0;
4173     if (fAmount > 0)
4174     {
4175       v[0] = 1.1f;
4176       v[1] = 1.1f;
4177       v[2] = 1.1f;
4178     } else
4179     {
4180       v[0] = 0.9f;
4181       v[1] = 0.9f;
4182       v[2] = 0.9f;
4183     }
4184
4185     Select_Scale((g_nScaleHow & SCALE_X) ? v[0] : 1.0,
4186                  (g_nScaleHow & SCALE_Y) ? v[1] : 1.0,
4187                  (g_nScaleHow & SCALE_Z) ? v[2] : 1.0);
4188     Sys_UpdateWindows (W_ALL);
4189   } else
4190   {
4191     // 0 - left, 1 - up, 2 - right, 3 - down
4192     int nDim;
4193     if (nDirection == 0)
4194     {
4195       nDim = ActiveXY()->GetViewType() == YZ ? 1 : 0;
4196       fAmount = -fAmount;
4197     } else if (nDirection == 1)
4198     {
4199       nDim = ActiveXY()->GetViewType() == XY ? 1 : 2;
4200     } else if (nDirection == 2)
4201     {
4202       nDim = ActiveXY()->GetViewType() == YZ ? 1 : 0;
4203     } else
4204     {
4205       nDim = ActiveXY()->GetViewType() == XY ? 1 : 2;
4206       fAmount = -fAmount;
4207     }
4208     Nudge(nDim, fAmount);
4209   }
4210 }
4211
4212 void MainFrame::Nudge(int nDim, float fNudge)
4213 {
4214   vec3_t vMove;
4215   vMove[0] = vMove[1] = vMove[2] = 0;
4216   vMove[nDim] = fNudge;
4217
4218   if((g_qeglobals.d_select_mode == sel_vertex ||
4219       g_qeglobals.d_select_mode == sel_curvepoint)
4220       && g_qeglobals.d_num_move_points)
4221     Select_NudgePoint(vMove, true);
4222   else
4223     Select_Move(vMove, true);
4224   Sys_UpdateWindows (W_ALL);
4225 }
4226
4227 void MainFrame::SetGridStatus()
4228 {
4229   CString strStatus;
4230   char c1;
4231   char c2;
4232   c1 = (g_PrefsDlg.m_bTextureLock) ? 'M' : ' ';
4233   c2 = (g_PrefsDlg.m_bRotateLock) ? 'R' : ' ';
4234   strStatus.Format("G:%g R:%i C:%i L:%c%c", g_qeglobals.d_gridsize,
4235                    g_PrefsDlg.m_nRotation, g_PrefsDlg.m_nCubicScale, c1, c2);
4236   SetStatusText(4, strStatus);
4237 }
4238
4239 void MainFrame::UpdatePatchToolbarButtons()
4240 {
4241   GtkWidget *item;
4242   g_bIgnoreCommands++;
4243   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_bend"));
4244   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchBendMode) ? TRUE : FALSE);
4245 //  item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_insdel"));
4246 //  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchInsertMode) ? TRUE : FALSE);
4247   g_bIgnoreCommands--;
4248 }
4249
4250 // =============================================================================
4251 // Command handlers
4252
4253 void MainFrame::OnFileNew()
4254 {
4255   if (ConfirmModified())
4256     Map_New ();
4257 }
4258
4259 void MainFrame::OnFileOpen()
4260 {
4261   if (!ConfirmModified())
4262     return;
4263
4264   const char *str;
4265         char buf[NAME_MAX];
4266
4267   strcpy(buf, g_qeglobals.m_strHomeMaps.GetBuffer());
4268   strcat(buf, "maps/");
4269
4270   str = file_dialog (m_pWidget, TRUE, "Open Map", buf, MAP_MAJOR);
4271
4272   if (str != NULL)
4273   {
4274     strcpy(currentmap,str);
4275     MRU_AddFile (str);
4276     Map_LoadFile(str);
4277   }
4278 }
4279
4280 void MainFrame::OnFileImportmap()
4281 {
4282   const char *str;
4283         char buf[NAME_MAX];
4284
4285   strcpy(buf, g_qeglobals.m_strHomeMaps.GetBuffer());
4286   strcat(buf, "maps/");
4287
4288   str = file_dialog (m_pWidget, TRUE, "Import Map", buf, MAP_MAJOR);
4289
4290   if (str != NULL)
4291   {
4292     Map_ImportFile(str);
4293   }
4294 }
4295
4296 void MainFrame::OnFileSave()
4297 {
4298   if (!strcmp(currentmap, "unnamed.map"))
4299     OnFileSaveas();
4300   else
4301     Map_SaveFile (currentmap, false);
4302 }
4303
4304 void MainFrame::OnFileSaveas()
4305 {
4306   const char* str;
4307         char buf[NAME_MAX];
4308
4309   strcpy(buf, g_qeglobals.m_strHomeMaps.GetBuffer());
4310   strcat(buf, "maps/");
4311
4312   str = file_dialog (g_pParentWnd->m_pWidget, FALSE, "Save Map", buf, MAP_MAJOR);
4313
4314   if (str != NULL)
4315   {
4316     strcpy (currentmap, str);
4317     MRU_AddFile (str);
4318     Map_SaveFile (str, false);  // ignore region
4319   }
4320 }
4321
4322 void MainFrame::OnFileExportmap()
4323 {
4324   const char* str;
4325         char buf[NAME_MAX];
4326
4327   strcpy(buf, g_qeglobals.m_strHomeMaps.GetBuffer());
4328   strcat(buf, "maps/");
4329
4330   str = file_dialog (m_pWidget, FALSE, "Export Selection", buf, MAP_MAJOR);
4331
4332   if (str != NULL)
4333   {
4334     Map_SaveSelected (str);
4335   }
4336 }
4337
4338 void MainFrame::OnFileSaveregion()
4339 {
4340   const char* str;
4341         char buf[NAME_MAX];
4342
4343   strcpy(buf, g_qeglobals.m_strHomeMaps.GetBuffer());
4344   strcat(buf, "maps/");
4345
4346   str = file_dialog (g_pParentWnd->m_pWidget, FALSE, "Export Region", buf, MAP_MAJOR);
4347
4348   if (str != NULL)
4349   {
4350     Map_SaveFile (str, true);   // ignore region
4351   }
4352 }
4353
4354 void MainFrame::OnFileNewproject()
4355 {
4356   char* name = DoNewProjectDlg ();
4357
4358   // create a new project:
4359   // create directories and grab current project, save it in new project tree in scripts/user.qe4
4360   // on linux we create under ~/.q3a, on win32 under strEnginePath
4361   // NOTE: working on a seperate project file might be broken, never did much experiment with that..
4362   if ((name != NULL) && (strlen (name) > 0))
4363   {
4364     CString strNewBasePath;
4365
4366     // NOTE TTimo this would probably not work right on *nix
4367     strNewBasePath = g_pGameDescription->mEnginePath.GetBuffer(); // assume paths end with '/'
4368     strNewBasePath += name;
4369     strNewBasePath += "/";
4370
4371     CString strProjToLoad;
4372     CString strMapToLoad;
4373
4374     // if the dir exists, ask the user if they want to continue anyway
4375     if (Q_mkdir (strNewBasePath.GetBuffer(), 0755) != 0)
4376     {
4377       CString strMsg;
4378       strMsg.Format("The directory name %s already exists\nContinue anyway ?\n", strNewBasePath.GetBuffer ());
4379       Sys_Printf(strMsg);
4380       if (gtk_MessageBox(m_pWidget, strMsg, "Error", MB_YESNO) != IDYES)
4381       {
4382         Sys_Printf("New Project cancelled, directory already exists for project\n");
4383         free (name);
4384         return;
4385       }
4386     }
4387
4388     CString strDir;
4389     strDir = strNewBasePath;
4390     strDir += "maps/";
4391     Q_mkdir (strDir.GetBuffer(), 0755);
4392
4393     strDir = strNewBasePath;
4394     strDir += "textures/";
4395     Q_mkdir (strDir.GetBuffer(), 0755);
4396
4397     strDir = strNewBasePath;
4398     strDir += "scripts/";
4399     Q_mkdir (strDir.GetBuffer(), 0755);
4400
4401     // print a warning for total conversions, since setting the basepath when required files are
4402     // not there _will_ break things (ie; textures/radiant/notex.tga, scripts/entities.def)
4403     Sys_FPrintf(SYS_WRN, "*** Note: basepath unchanged\n");
4404
4405     SetKeyValue( g_qeglobals.d_project_entity, "gamename", name);
4406
4407     strDir = strNewBasePath;
4408     strDir += "maps/autosave.map";
4409     SetKeyValue( g_qeglobals.d_project_entity, "autosave", strDir.GetBuffer() );
4410
4411     // state that this is a user project file, no templating
4412     SetKeyValue( g_qeglobals.d_project_entity, "user_project", "1" );
4413     // create the project file
4414     strProjToLoad = strNewBasePath;
4415     strProjToLoad += "scripts/";
4416                 strProjToLoad += name;
4417                 strProjToLoad += ".";
4418                 strProjToLoad += PROJECT_FILETYPE;
4419     QE_SaveProject(strProjToLoad.GetBuffer());
4420     free (name);
4421   }
4422 }
4423
4424 void MainFrame::OnFileLoadproject()
4425 {
4426   if (ConfirmModified())
4427     ProjectDialog ();
4428 }
4429
4430 void MainFrame::OnFileProjectsettings()
4431 {
4432   DoProjectSettings();
4433 }
4434
4435 void MainFrame::OnFilePointfile()
4436 {
4437   if (g_qeglobals.d_pointfile_display_list)
4438     Pointfile_Clear ();
4439   else
4440     Pointfile_Check ();
4441 }
4442
4443 void MainFrame::OnMru(unsigned int nID)
4444 {
4445   if (ConfirmModified())
4446     MRU_Activate (nID - ID_FILE_RECENT1);
4447 }
4448
4449 void MainFrame::OnFileExit()
4450 {
4451   if (ConfirmModified())
4452   {
4453     // stop printing during shutdown
4454     // NOTE: we should cleanly release GL contexts and stuff when exiting
4455
4456     OnDelete();
4457
4458     g_qeglobals_gui.d_edit = NULL;
4459     gtk_widget_destroy (m_pWidget);
4460   }
4461 }
4462
4463 void MainFrame::OnFileCheckUpdate()
4464
4465 {
4466   // build the URL
4467   Str URL;
4468   URL = "http://www.qeradiant.com/index.php?data=dlupdate&query_dlup=1";
4469 #ifdef _WIN32
4470   URL += "&OS_dlup=1";
4471 #else
4472   URL += "&OS_dlup=2";
4473 #endif
4474   URL += "&Version_dlup=" RADIANT_VERSION;
4475   g_PrefsDlg.mGamesDialog.AddPacksURL(URL);
4476   OpenURL(URL.GetBuffer());
4477 }
4478
4479 void MainFrame::OnEditUndo()
4480 {
4481   Undo_Undo();
4482 }
4483
4484 void MainFrame::OnEditRedo()
4485 {
4486   Undo_Redo();
4487 }
4488
4489 void MainFrame::OnEditCopybrush()
4490 {
4491   Copy();
4492 }
4493
4494 void MainFrame::OnEditPastebrush()
4495 {
4496   Select_Deselect();
4497
4498   Undo_Start("paste");
4499
4500   Paste();
4501
4502   Undo_EndBrushList(&selected_brushes);
4503   Undo_End();
4504 }
4505
4506 void MainFrame::OnEditPastebrushToCamera()
4507 {
4508   Select_Deselect();
4509   if (ActiveXY())
4510   {
4511     vec3_t mid, camorigin, delta;
4512
4513     ActiveXY()->Paste();
4514
4515     // Work out the delta
4516     Select_GetMid( mid );
4517
4518         // Snap camera origin to grid
4519         VectorCopy( m_pCamWnd->Camera()->origin, camorigin );
4520         camorigin[0] = floor(camorigin[0] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
4521         camorigin[1] = floor(camorigin[1] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
4522         camorigin[2] = floor(camorigin[2] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
4523
4524     VectorSubtract( camorigin, mid, delta );
4525
4526     // Move to camera
4527     Select_Move( delta, false );
4528
4529     Undo_Start("paste to camera");
4530     Undo_EndBrushList(&selected_brushes);
4531     Undo_End();
4532   }
4533 }
4534
4535 void MainFrame::OnSelectionDelete()
4536 {
4537   brush_t *brush;
4538   //if (ActiveXY())
4539   //    ActiveXY()->UndoCopy();
4540   Undo_Start("delete");
4541   Undo_AddBrushList(&selected_brushes);
4542   //add all deleted entities to the undo
4543   for (brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next)
4544   {
4545     Undo_AddEntity(brush->owner);
4546   }
4547   // NOTE: Select_Delete does NOT delete entities
4548   Select_Delete();
4549   Undo_EndBrushList(&selected_brushes);
4550   Undo_End();
4551 }
4552
4553 void MainFrame::OnEditMapinfo()
4554 {
4555   DoMapInfo ();
4556 }
4557
4558 void MainFrame::OnEditEntityinfo()
4559 {
4560   DoEntityList ();
4561 }
4562
4563 void MainFrame::OnBrushScripts()
4564 {
4565   DoScriptsDlg ();
4566 }
4567
4568 void MainFrame::OnEditLoadprefab()
4569 {
4570   const char *filename;
4571   CString CurPath;
4572
4573   if (g_PrefsDlg.m_strPrefabPath.GetLength() > 0)
4574   {
4575     CurPath = g_PrefsDlg.m_strPrefabPath;
4576     AddSlash (CurPath);
4577   }
4578
4579   filename = file_dialog (m_pWidget, TRUE, "Import Prefab", CurPath.GetBuffer(), MAP_MAJOR);
4580
4581   if (filename != NULL)
4582   {
4583     Map_ImportFile(filename);
4584   }
4585 }
4586
4587 void MainFrame::OnEditSaveprefab()
4588 {
4589   const char *filename;
4590   CString CurPath;
4591
4592   if (g_PrefsDlg.m_strPrefabPath.GetLength() > 0)
4593   {
4594     CurPath = g_PrefsDlg.m_strPrefabPath;
4595   } else
4596   {
4597     char tmp[PATH_MAX];
4598     getcwd (tmp, PATH_MAX);
4599     CurPath = tmp;
4600   }
4601   AddSlash (CurPath);
4602
4603   filename = file_dialog (m_pWidget, FALSE, "Export Prefab", CurPath.GetBuffer(), MAP_MAJOR);
4604   if (filename != NULL)
4605   {
4606     Map_SaveSelected(filename);
4607   }
4608 }
4609
4610 void MainFrame::OnPrefs()
4611 {
4612   int nView = g_PrefsDlg.m_nView;
4613   bool bToolbar = g_PrefsDlg.m_bWideToolbar;
4614   bool bPluginToolbar = g_PrefsDlg.m_bPluginToolbar;
4615   int nShader = g_PrefsDlg.m_nShader;
4616   int nTextureQuality = g_PrefsDlg.m_nTextureQuality;
4617   int nLightRadiuses = g_PrefsDlg.m_nLightRadiuses;
4618   g_PrefsDlg.LoadPrefs();
4619
4620   if (g_PrefsDlg.DoModal() == IDOK)
4621   {
4622     if ((g_PrefsDlg.m_nLatchedView != nView) ||
4623         (g_PrefsDlg.m_bLatchedDetachableMenus != g_PrefsDlg.m_bDetachableMenus) ||
4624         (g_PrefsDlg.m_bLatchedWideToolbar != bToolbar) ||
4625         (g_PrefsDlg.m_bLatchedPatchToolbar != bToolbar) ||
4626         (g_PrefsDlg.m_bLatchedPluginToolbar != bPluginToolbar) ||
4627         (g_PrefsDlg.m_nLatchedShader != nShader) ||
4628         (g_PrefsDlg.m_nLatchedTextureQuality != nTextureQuality)
4629         || (g_PrefsDlg.m_bLatchedFloatingZ != g_PrefsDlg.m_bFloatingZ)
4630         )
4631       gtk_MessageBox(m_pWidget, "You must restart Radiant for the changes to take effect.");
4632
4633     // if the view mode was switched to floating, set the Z window on by default
4634     // this was originally intended as a bug fix, but the fix is elsewhere .. anyway making sure we force Z on each time is good
4635     // (and we simply hope there will be a SavePrefs before we die)
4636     if ((g_PrefsDlg.m_nView != nView) && ((EViewStyle)g_PrefsDlg.m_nView == (EViewStyle)eFloating))
4637     {
4638       g_PrefsDlg.m_bZVis = true;
4639     }
4640
4641     if (m_pTexWnd)
4642       m_pTexWnd->UpdatePrefs();
4643
4644     GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
4645     g_bIgnoreCommands++;
4646     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
4647                                     (!g_PrefsDlg.m_bNoClamp) ? TRUE : FALSE);
4648     g_bIgnoreCommands--;
4649   }
4650 }
4651
4652 void MainFrame::OnTogglecamera()
4653 {
4654   if (CurrentStyle() == eFloating) // floating views
4655   {
4656     if (m_pCamWnd && m_pCamWnd->m_pParent)
4657     {
4658       if (GTK_WIDGET_VISIBLE (m_pCamWnd->m_pParent))
4659         widget_delete_hide (m_pCamWnd->m_pParent);
4660       else
4661         gtk_widget_show (m_pCamWnd->m_pParent);
4662     }
4663   } else
4664   {
4665     if (GTK_WIDGET_VISIBLE (m_pCamWnd->GetWidget ()))
4666       gtk_widget_hide (m_pCamWnd->GetWidget ());
4667     else
4668       gtk_widget_show (m_pCamWnd->GetWidget ());
4669   }
4670 }
4671
4672 void MainFrame::OnToggleconsole()
4673 {
4674   if (FloatingGroupDialog()) // QE4 style
4675   {
4676     if (inspector_mode == W_CONSOLE)
4677     {
4678       if (GTK_WIDGET_VISIBLE (g_qeglobals_gui.d_entity))
4679         widget_delete_hide (g_qeglobals_gui.d_entity);
4680       else
4681         gtk_widget_show (g_qeglobals_gui.d_entity);
4682     } else
4683     {
4684       gtk_widget_show (g_qeglobals_gui.d_entity);
4685       SetInspectorMode(W_CONSOLE);
4686     }
4687   }
4688 }
4689
4690 // trigger the entity inspector on/off
4691 void MainFrame::OnViewEntity()
4692 {
4693   // make sure we're working with the current selection (bugzilla #436)
4694   if( ! GTK_WIDGET_VISIBLE (g_qeglobals_gui.d_entity))
4695     Select_Reselect();
4696
4697   if (!FloatingGroupDialog())
4698   {
4699     if (GTK_WIDGET_VISIBLE (g_qeglobals_gui.d_entity) && inspector_mode == W_ENTITY)
4700       widget_delete_hide (g_qeglobals_gui.d_entity);
4701     else
4702     {
4703       gtk_widget_show (g_qeglobals_gui.d_entity);
4704       SetInspectorMode(W_ENTITY);
4705     }
4706   } else
4707   {
4708     if (inspector_mode == W_ENTITY)
4709     {
4710       if (GTK_WIDGET_VISIBLE (g_qeglobals_gui.d_entity))
4711         widget_delete_hide (g_qeglobals_gui.d_entity);
4712       else
4713         gtk_widget_show (g_qeglobals_gui.d_entity);
4714     } else
4715     {
4716       gtk_widget_show (g_qeglobals_gui.d_entity);
4717       SetInspectorMode(W_ENTITY);
4718     }
4719   }
4720 }
4721
4722 void MainFrame::OnViewGroups()
4723 {
4724   if (!FloatingGroupDialog())
4725   {
4726     if (GTK_WIDGET_VISIBLE (g_qeglobals_gui.d_entity) && inspector_mode == W_GROUP)
4727       widget_delete_hide (g_qeglobals_gui.d_entity);
4728     else
4729     {
4730       gtk_widget_show (g_qeglobals_gui.d_entity);
4731       SetInspectorMode(W_GROUP);
4732     }
4733   } else
4734   {
4735     if (inspector_mode == W_GROUP && CurrentStyle() != MainFrame::eFloating)
4736     {
4737       if (GTK_WIDGET_VISIBLE (g_qeglobals_gui.d_entity))
4738         widget_delete_hide (g_qeglobals_gui.d_entity);
4739       else
4740         gtk_widget_show (g_qeglobals_gui.d_entity);
4741     } else
4742     {
4743       gtk_widget_show (g_qeglobals_gui.d_entity);
4744       SetInspectorMode(W_GROUP);
4745     }
4746   }
4747 }
4748
4749 void MainFrame::OnToggleview()
4750 {
4751   if (CurrentStyle() == eFloating) // QE4 style
4752   {
4753     if (m_pXYWnd && m_pXYWnd->m_pParent)
4754     {
4755       if (GTK_WIDGET_VISIBLE (m_pXYWnd->m_pParent))
4756         widget_delete_hide (m_pXYWnd->m_pParent);
4757       else
4758         gtk_widget_show (m_pXYWnd->m_pParent);
4759     }
4760   }
4761 }
4762
4763 void MainFrame::OnToggleviewXz()
4764 {
4765   if (CurrentStyle() == eFloating) // QE4 style
4766   {
4767     if (m_pXZWnd && m_pXZWnd->m_pParent)
4768     {
4769       // get windowplacement doesn't actually save this so we will here
4770       g_PrefsDlg.m_bXZVis = GTK_WIDGET_VISIBLE (m_pXZWnd->m_pParent);
4771       if (g_PrefsDlg.m_bXZVis)
4772         widget_delete_hide (m_pXZWnd->m_pParent);
4773       else
4774         gtk_widget_show (m_pXZWnd->m_pParent);
4775       g_PrefsDlg.m_bXZVis ^= 1;
4776       g_PrefsDlg.SavePrefs ();
4777     }
4778   }
4779 }
4780
4781 void MainFrame::OnToggleviewYz()
4782 {
4783   if (CurrentStyle() == eFloating) // QE4 style
4784   {
4785     if (m_pYZWnd && m_pYZWnd->m_pParent)
4786     {
4787       g_PrefsDlg.m_bYZVis = GTK_WIDGET_VISIBLE (m_pYZWnd->m_pParent);
4788       if (g_PrefsDlg.m_bYZVis)
4789         widget_delete_hide (m_pYZWnd->m_pParent);
4790       else
4791         gtk_widget_show (m_pYZWnd->m_pParent);
4792       g_PrefsDlg.m_bYZVis ^= 1;
4793       g_PrefsDlg.SavePrefs ();
4794     }
4795   }
4796 }
4797
4798 void MainFrame::OnTogglez()
4799 {
4800   if ( g_pParentWnd->FloatingGroupDialog() ) // QE4 style
4801   {
4802     if (m_pZWnd && m_pZWnd->m_pParent)
4803     {
4804       if (GTK_WIDGET_VISIBLE (m_pZWnd->m_pParent))
4805         widget_delete_hide (m_pZWnd->m_pParent);
4806       else
4807         gtk_widget_show (m_pZWnd->m_pParent);
4808       g_PrefsDlg.m_bZVis ^= 1;
4809       g_PrefsDlg.SavePrefs ();
4810     }
4811   } else {
4812     Sys_FPrintf( SYS_WRN, "Z view toggle is only valid in floating views\n" );
4813   }
4814 }
4815
4816 void MainFrame::OnViewCenter()
4817 {
4818   m_pCamWnd->Camera()->angles[ROLL] = m_pCamWnd->Camera()->angles[PITCH] = 0;
4819   m_pCamWnd->Camera()->angles[YAW] = 22.5 * floor((m_pCamWnd->Camera()->angles[YAW]+11)/22.5);
4820   Sys_UpdateWindows (W_CAMERA | W_XY_OVERLAY);
4821 }
4822
4823 void MainFrame::OnViewUpfloor()
4824 {
4825   m_pCamWnd->Cam_ChangeFloor (true);
4826 }
4827
4828 void MainFrame::OnViewDownfloor()
4829 {
4830   m_pCamWnd->Cam_ChangeFloor (false);
4831 }
4832
4833 void MainFrame::OnViewCenterview()
4834 {
4835   if(CurrentStyle() == eSplit)
4836   {
4837     GetXYWnd()->PositionView();
4838     GetXZWnd()->PositionView();
4839     GetYZWnd()->PositionView();
4840     Sys_UpdateWindows (W_XY|W_XZ|W_YZ);
4841   }
4842   else {
4843     m_pXYWnd->PositionView();
4844     Sys_UpdateWindows (W_XY);
4845   }
4846 }
4847
4848 void MainFrame::OnViewNextview()
4849 {
4850   if (CurrentStyle() == eSplit)
4851   {
4852     GetXYWnd()->PositionView();
4853     GetXZWnd()->PositionView();
4854     GetYZWnd()->PositionView();
4855     Sys_UpdateWindows (W_XY|W_XZ|W_YZ);
4856   }
4857   else {
4858     if (m_pXYWnd->GetViewType() == XY)
4859       m_pXYWnd->SetViewType(XZ);
4860     else
4861       if (m_pXYWnd->GetViewType() ==  XZ)
4862       m_pXYWnd->SetViewType(YZ);
4863     else
4864       m_pXYWnd->SetViewType(XY);
4865     m_pXYWnd->PositionView();
4866     Sys_UpdateWindows (W_XY);
4867   }
4868 }
4869
4870 void MainFrame::OnViewXy()
4871 {
4872   if(!FloatingGroupDialog())
4873   {
4874     m_pXYWnd->SetViewType(XY);
4875     m_pXYWnd->PositionView();
4876   }
4877   Sys_UpdateWindows (W_XY);
4878 }
4879
4880 void MainFrame::OnViewSide()
4881 {
4882   if (!FloatingGroupDialog())
4883   {
4884     m_pXYWnd->SetViewType(XZ);
4885     m_pXYWnd->PositionView();
4886   }
4887   Sys_UpdateWindows (W_XY);
4888 }
4889
4890 void MainFrame::OnViewFront()
4891 {
4892   if (!FloatingGroupDialog())
4893   {
4894     m_pXYWnd->SetViewType(YZ);
4895     m_pXYWnd->PositionView();
4896   }
4897   Sys_UpdateWindows (W_XY);
4898 }
4899
4900 void MainFrame::OnView100()
4901 {
4902   if (m_pXYWnd)
4903     m_pXYWnd->SetScale(1);
4904   if (m_pXZWnd)
4905     m_pXZWnd->SetScale(1);
4906   if (m_pYZWnd)
4907     m_pYZWnd->SetScale(1);
4908   Sys_UpdateWindows (W_XY|W_XY_OVERLAY);
4909 }
4910
4911 void MainFrame::OnViewZoomin()
4912 {
4913   if (m_pXYWnd && m_pXYWnd->Active())
4914   {
4915     m_pXYWnd->SetScale(m_pXYWnd->Scale() * 5.0 / 4);
4916     if (m_pXYWnd->Scale() > 30)
4917       m_pXYWnd->SetScale(30);
4918   }
4919
4920   if (m_pXZWnd && m_pXZWnd->Active())
4921   {
4922     m_pXZWnd->SetScale(m_pXZWnd->Scale() * 5.0 / 4);
4923     if (m_pXZWnd->Scale() > 30)
4924       m_pXZWnd->SetScale(30);
4925   }
4926
4927   if (m_pYZWnd && m_pYZWnd->Active())
4928   {
4929     m_pYZWnd->SetScale(m_pYZWnd->Scale() * 5.0 / 4);
4930     if (m_pYZWnd->Scale() > 30)
4931       m_pYZWnd->SetScale(30);
4932   }
4933
4934   Sys_UpdateWindows (W_XY|W_XY_OVERLAY);
4935 }
4936
4937 // NOTE: the zoom out factor is 4/5, we could think about customizing it
4938 //  we don't go below a zoom factor corresponding to 10% of the max world size
4939 //  (this has to be computed against the window size)
4940 void MainFrame::OnViewZoomout()
4941 {
4942   float min_scale;
4943   if (m_pXYWnd && m_pXYWnd->Active())
4944   {
4945     m_pXYWnd->SetScale(m_pXYWnd->Scale() * 4.0 / 5);
4946     min_scale = MIN(m_pXYWnd->Width(),m_pXYWnd->Height()) / ( 1.1 * (g_MaxWorldCoord-g_MinWorldCoord));
4947     if (m_pXYWnd->Scale() < min_scale) m_pXYWnd->SetScale (min_scale);
4948   }
4949
4950   if (m_pXZWnd && m_pXZWnd->Active())
4951   {
4952     m_pXZWnd->SetScale(m_pXZWnd->Scale() * 4.0 / 5);
4953     min_scale = MIN(m_pXZWnd->Width(),m_pXZWnd->Height()) / ( 1.1 * (g_MaxWorldCoord-g_MinWorldCoord));
4954     if (m_pXZWnd->Scale() < min_scale) m_pXZWnd->SetScale (min_scale);
4955   }
4956
4957   if (m_pYZWnd && m_pYZWnd->Active())
4958   {
4959     m_pYZWnd->SetScale(m_pYZWnd->Scale() * 4.0 / 5);
4960     min_scale = MIN(m_pYZWnd->Width(),m_pYZWnd->Height()) / ( 1.1 * (g_MaxWorldCoord-g_MinWorldCoord));
4961     if (m_pYZWnd->Scale() < min_scale) m_pYZWnd->SetScale (min_scale);
4962   }
4963   Sys_UpdateWindows (W_XY|W_XY_OVERLAY);
4964 }
4965
4966 void MainFrame::OnViewZ100()
4967 {
4968   z.scale = 1;
4969   Sys_UpdateWindows (W_Z|W_Z_OVERLAY);
4970 }
4971
4972 void MainFrame::OnViewZzoomin()
4973 {
4974   z.scale *= 5.0/4;
4975   if (z.scale > 4)
4976     z.scale = 4;
4977   Sys_UpdateWindows (W_Z|W_Z_OVERLAY);
4978 }
4979
4980 void MainFrame::OnViewZzoomout()
4981 {
4982   z.scale *= 4.0f/5;
4983   if (z.scale < 0.125)
4984     z.scale = 0.125;
4985   Sys_UpdateWindows (W_Z|W_Z_OVERLAY);
4986 }
4987
4988 void MainFrame::OnViewCubein()
4989 {
4990   g_PrefsDlg.m_nCubicScale--;
4991   if (g_PrefsDlg.m_nCubicScale < 1)
4992     g_PrefsDlg.m_nCubicScale = 1;
4993   g_PrefsDlg.SavePrefs ();
4994   Sys_UpdateWindows(W_CAMERA);
4995   SetGridStatus();
4996 }
4997
4998 void MainFrame::OnViewCubeout()
4999 {
5000   g_PrefsDlg.m_nCubicScale++;
5001   if (g_PrefsDlg.m_nCubicScale > 22)
5002     g_PrefsDlg.m_nCubicScale = 22;
5003   g_PrefsDlg.SavePrefs ();
5004   Sys_UpdateWindows(W_CAMERA);
5005   SetGridStatus();
5006 }
5007
5008 void MainFrame::OnViewShownames()
5009 {
5010   g_qeglobals.d_savedinfo.show_names = !g_qeglobals.d_savedinfo.show_names;
5011   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_shownames"));
5012   g_bIgnoreCommands++;
5013   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
5014                                   g_qeglobals.d_savedinfo.show_names ? TRUE : FALSE);
5015   g_bIgnoreCommands--;
5016   Sys_UpdateWindows (W_XY);
5017 }
5018
5019 void MainFrame::OnViewShowAngles()
5020 {
5021   g_qeglobals.d_savedinfo.show_angles = !g_qeglobals.d_savedinfo.show_angles;
5022   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showangles"));
5023   g_bIgnoreCommands++;
5024   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
5025                                   g_qeglobals.d_savedinfo.show_angles ? TRUE : FALSE);
5026   g_bIgnoreCommands--;
5027   Sys_UpdateWindows (W_XY);
5028 }
5029
5030 void MainFrame::OnViewShowblocks()
5031 {
5032   g_qeglobals.show_blocks ^= 1;
5033   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showblocks"));
5034   g_bIgnoreCommands++;
5035   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_qeglobals.show_blocks ? TRUE : FALSE);
5036   g_bIgnoreCommands--;
5037   Sys_UpdateWindows (W_XY);
5038 }
5039
5040 void MainFrame::OnViewShowcoordinates()
5041 {
5042   g_qeglobals.d_savedinfo.show_coordinates ^= 1;
5043   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showcoordinates"));
5044   g_bIgnoreCommands++;
5045   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
5046                                   g_qeglobals.d_savedinfo.show_coordinates ? TRUE : FALSE);
5047   g_bIgnoreCommands--;
5048   Sys_UpdateWindows (W_XY|W_Z);
5049 }
5050
5051 void MainFrame::OnViewShowOutline()
5052 {
5053   g_qeglobals.d_savedinfo.show_outline ^= 1;
5054   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showoutline"));
5055   g_bIgnoreCommands++;
5056   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
5057                                   g_qeglobals.d_savedinfo.show_outline ? TRUE : FALSE);
5058   g_bIgnoreCommands--;
5059   Sys_UpdateWindows (W_XY);
5060 }
5061
5062 void MainFrame::OnViewShowAxes()
5063 {
5064   g_qeglobals.d_savedinfo.show_axis ^= 1;
5065   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showaxes"));
5066   g_bIgnoreCommands++;
5067   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
5068                                   g_qeglobals.d_savedinfo.show_axis ? TRUE : FALSE);
5069   g_bIgnoreCommands--;
5070   Sys_UpdateWindows (W_XY);
5071 }
5072
5073 void MainFrame::OnViewShowWorkzone()
5074 {
5075   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_showworkzone"));
5076   g_bIgnoreCommands++;
5077   if (g_qeglobals.d_show_work)
5078   {
5079     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
5080     g_qeglobals.d_show_work = false;
5081   } else
5082   {
5083     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
5084     g_qeglobals.d_show_work = true;
5085   }
5086   g_bIgnoreCommands--;
5087   Sys_UpdateWindows (W_XY);
5088 }
5089
5090 void MainFrame::OnViewHideshowHideselected()
5091 {
5092   Select_Hide();
5093   Select_Deselect();
5094 }
5095
5096 void MainFrame::OnViewHideshowShowhidden()
5097 {
5098   Select_ShowAllHidden();
5099 }
5100
5101 /**
5102 sets the view mode for the entities
5103 called upon LoadPrefs too
5104 NOTE TTimo previous implementation had a SavePrefs call
5105   .. I don't think it is relevant, removed (the prefs are saved upon exit)
5106 NOTE TTimo we activate the menu item, this is only needed when we are called upon a prefs load
5107   (otherwise we are always called following user action on the widget)
5108 */
5109 void MainFrame::OnEntitiesSetViewAs(int mode)
5110 {
5111   gpointer item = NULL;
5112   if (mode == 0)
5113   {
5114     switch (g_PrefsDlg.m_nEntityShowState)
5115     {
5116     case ENTITY_BOX:
5117       item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_boundingbox");
5118       break;
5119     case ENTITY_WIRE:
5120       item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_wireframe");
5121       break;
5122     case ENTITY_SELECTED:
5123       item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_selectedwireframe");
5124       break;
5125     case ENTITY_SELECTED_SKIN:
5126       item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_selectedskinned");
5127       break;
5128     case ENTITY_SKINNED:
5129       item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_skinned");
5130       break;
5131     case ENTITY_SKINNED_BOXED:
5132       item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_skinnedandboxed");
5133       break;
5134     }
5135     g_bIgnoreCommands++;
5136     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
5137     g_bIgnoreCommands--;
5138     return;
5139   }
5140
5141   switch (mode)
5142   {
5143   case ID_VIEW_ENTITIESAS_BOUNDINGBOX:
5144     g_PrefsDlg.m_nEntityShowState = ENTITY_BOX;
5145     item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_boundingbox");
5146     break;
5147   case ID_VIEW_ENTITIESAS_WIREFRAME:
5148     g_PrefsDlg.m_nEntityShowState = ENTITY_WIRE;
5149     item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_wireframe");
5150     break;
5151   case ID_VIEW_ENTITIESAS_SELECTEDWIREFRAME:
5152     g_PrefsDlg.m_nEntityShowState = ENTITY_SELECTED;
5153     item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_selectedwireframe");
5154     break;
5155   case ID_VIEW_ENTITIESAS_SELECTEDSKINNED:
5156     g_PrefsDlg.m_nEntityShowState = ENTITY_SELECTED_SKIN;
5157     item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_selectedskinned");
5158     break;
5159   case ID_VIEW_ENTITIESAS_SKINNED:
5160     g_PrefsDlg.m_nEntityShowState = ENTITY_SKINNED;
5161     item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_skinned");
5162     break;
5163   case ID_VIEW_ENTITIESAS_SKINNEDANDBOXED:
5164     g_PrefsDlg.m_nEntityShowState = ENTITY_SKINNED_BOXED;
5165     item = g_object_get_data (G_OBJECT (g_pParentWnd->m_pWidget), "menu_view_entitiesas_skinnedandboxed");
5166     break;
5167   default:
5168     Sys_FPrintf(SYS_ERR, "Entity mode ID_ not found in MainFrame::Entities_SetViewAs\n");
5169     return;
5170   }
5171
5172   if (!item)
5173   {
5174     Sys_FPrintf(SYS_ERR, "menu not found in MainFrame::Entities_SetViewAs\n");
5175     return;
5176   }
5177
5178   g_bIgnoreCommands++;
5179   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
5180   g_bIgnoreCommands--;
5181
5182   Sys_UpdateWindows(W_ALL);
5183 }
5184
5185 void MainFrame::OnViewCubicclipping()
5186 {
5187   GtkWidget *w;
5188
5189   g_PrefsDlg.m_bCubicClipping ^= 1;
5190   g_bIgnoreCommands++;
5191   w = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_cubicclipping"));
5192   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (w), g_PrefsDlg.m_bCubicClipping ? TRUE : FALSE);
5193   w = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_view_cubicclipping"));
5194   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), g_PrefsDlg.m_bCubicClipping ? TRUE : FALSE);
5195   g_bIgnoreCommands--;
5196   g_PrefsDlg.SavePrefs ();
5197   //Map_BuildBrushData ();
5198   Sys_UpdateWindows(W_CAMERA);
5199 }
5200
5201 void MainFrame::OnViewOpengllighting()
5202 {
5203   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_opengllighting"));
5204   g_PrefsDlg.m_bGLLighting ^= 1;
5205   g_PrefsDlg.SavePrefs ();
5206   g_bIgnoreCommands++;
5207   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bGLLighting ? TRUE : FALSE);
5208   Sys_UpdateWindows (W_XY|W_CAMERA);
5209   g_bIgnoreCommands--;
5210 }
5211
5212 void MainFrame::OnSelectionDragedges()
5213 {
5214   if (g_qeglobals.d_select_mode == sel_edge)
5215   {
5216     g_qeglobals.d_select_mode = sel_brush;
5217     Sys_UpdateWindows (W_ALL);
5218   } else
5219   {
5220     SetupVertexSelection ();
5221     if (g_qeglobals.d_numpoints)
5222       g_qeglobals.d_select_mode = sel_edge;
5223     Sys_UpdateWindows (W_ALL);
5224   }
5225 }
5226
5227 void MainFrame::OnSelectionDragvertecies()
5228 {
5229   if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_curvepoint)
5230   {
5231     g_qeglobals.d_select_mode = sel_brush;
5232     Sys_UpdateWindows (W_ALL);
5233   } else
5234   {
5235     //--if (QE_SingleBrush() && selected_brushes.next->patchBrush)
5236     if (OnlyPatchesSelected())
5237     {
5238       Patch_EditPatch();
5239     } else //if (!AnyPatchesSelected()) // allows vertex mode when patches are selected
5240     {
5241       SetupVertexSelection ();
5242       if (g_qeglobals.d_numpoints)
5243         g_qeglobals.d_select_mode = sel_vertex;
5244     }
5245     Sys_UpdateWindows (W_ALL);
5246   }
5247 }
5248
5249 void MainFrame::OnSelectionClone()
5250 {
5251   Select_Clone();
5252 }
5253
5254 // called when the escape key is used (either on the main window or on an inspector)
5255 void MainFrame::OnSelectionDeselect()
5256 {
5257   if (g_bClipMode)
5258     OnViewClipper();
5259   else
5260     if (g_bRotateMode)
5261     OnSelectMouserotate();
5262   else
5263     if (g_bScaleMode)
5264     OnSelectMousescale();
5265   else
5266     if (g_bPathMode)
5267   {
5268     if (ActiveXY())
5269       ActiveXY()->KillPathMode();
5270   } else
5271   {
5272     if (g_qeglobals.d_select_mode == sel_curvepoint && g_qeglobals.d_num_move_points > 0)
5273     {
5274       g_qeglobals.d_num_move_points = 0;
5275       Sys_UpdateWindows(W_ALL);
5276     } else
5277     {
5278       Select_Deselect ();
5279       SetStatusText(2, " ");
5280     }
5281   }
5282 }
5283
5284 void MainFrame::OnBrushFlipx()
5285 {
5286   Undo_Start("flip X");
5287   Undo_AddBrushList(&selected_brushes);
5288
5289   Select_FlipAxis (0);
5290   // spog - this does not work - it's a rotate not a flip
5291   /*
5292   for (brush_t *b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
5293   {
5294     if(b->owner->eclass->fixedsize)
5295     {
5296       char buf[16];
5297       float a = FloatForKey(b->owner, "angle");
5298       a = div ((int)(180 - a), 180).rem;
5299       sprintf (buf, "%d", (int)a);
5300       SetKeyValue(b->owner, "angle", buf);
5301       Brush_Build(b,true,true,false,false); // don't filter
5302     }
5303   }
5304   */
5305   Undo_EndBrushList(&selected_brushes);
5306   Undo_End();
5307 }
5308
5309 void MainFrame::OnBrushFlipy()
5310 {
5311   Undo_Start("flip Y");
5312   Undo_AddBrushList(&selected_brushes);
5313
5314   Select_FlipAxis (1);
5315   // spog - this does not work - it's a rotate not a flip
5316   /*
5317   for (brush_t *b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
5318   {
5319     if(b->owner->eclass->fixedsize)
5320     {
5321       float a = FloatForKey(b->owner, "angle");
5322       if (a == 0 || a == 180 || a == 360)
5323   continue;
5324       if ( a == 90 || a == 270)
5325       {
5326   a += 180;
5327       }
5328       else if (a > 270)
5329   a += 90;
5330       else if (a > 180)
5331   a -= 90;
5332       else if (a > 90)
5333   a += 90;
5334       else
5335   a -= 90;
5336       a = (int)a % 360;
5337       char buf[16];
5338       sprintf (buf, "%d", (int)a);
5339       SetKeyValue(b->owner, "angle", buf);
5340       Brush_Build(b,true,true,false,false); // don't filter
5341     }
5342
5343   }
5344   */
5345   Undo_EndBrushList(&selected_brushes);
5346   Undo_End();
5347 }
5348
5349 void MainFrame::OnBrushFlipz()
5350 {
5351   Undo_Start("flip Z");
5352   Undo_AddBrushList(&selected_brushes);
5353   Select_FlipAxis (2);
5354   Undo_EndBrushList(&selected_brushes);
5355   Undo_End();
5356 }
5357
5358 void MainFrame::OnBrushRotatex()
5359 {
5360   Undo_Start("rotate X");
5361   Undo_AddBrushList(&selected_brushes);
5362   Select_RotateAxis (0, 90);
5363   Undo_EndBrushList(&selected_brushes);
5364   Undo_End();
5365 }
5366
5367 void MainFrame::OnBrushRotatey()
5368 {
5369   Undo_Start("rotate Y");
5370   Undo_AddBrushList(&selected_brushes);
5371   Select_RotateAxis (1, 90);
5372   Undo_EndBrushList(&selected_brushes);
5373   Undo_End();
5374 }
5375
5376 void MainFrame::OnBrushRotatez()
5377 {
5378   Undo_Start("rotate Z");
5379   Undo_AddBrushList(&selected_brushes);
5380   Select_RotateAxis (2, 90);
5381   Undo_EndBrushList(&selected_brushes);
5382   Undo_End();
5383 }
5384
5385 void MainFrame::OnSelectionArbitraryrotation()
5386 {
5387   Undo_Start("arbitrary rotation");
5388   Undo_AddBrushList(&selected_brushes);
5389
5390   DoRotateDlg ();
5391
5392   Undo_EndBrushList(&selected_brushes);
5393   Undo_End();
5394 }
5395
5396 void MainFrame::OnSelectScale()
5397 {
5398   Undo_Start("scale");
5399   Undo_AddBrushList(&selected_brushes);
5400   DoScaleDlg ();
5401   Undo_EndBrushList(&selected_brushes);
5402   Undo_End();
5403 }
5404
5405 void MainFrame::OnSelectionMakehollow()
5406 {
5407   //if (ActiveXY())
5408   //    ActiveXY()->UndoCopy();
5409   Undo_Start("hollow");
5410   Undo_AddBrushList(&selected_brushes);
5411   CSG_MakeHollow ();
5412   Undo_EndBrushList(&selected_brushes);
5413   Undo_End();
5414 }
5415
5416 void MainFrame::OnSelectionCsgsubtract()
5417 {
5418   Undo_Start("CSG subtract");
5419   CSG_Subtract();
5420   Undo_End();
5421 }
5422
5423 void MainFrame::OnSelectionCsgmerge()
5424 {
5425   Undo_Start("CSG merge");
5426   Undo_AddBrushList(&selected_brushes);
5427   CSG_Merge();
5428   Undo_EndBrushList(&selected_brushes);
5429   Undo_End();
5430 }
5431
5432 void MainFrame::OnSelectionNoOutline()
5433 {
5434   //g_qeglobals.d_savedinfo.bNoSelectedOutlines ^= 1;
5435   g_qeglobals.d_savedinfo.iSelectedOutlinesStyle = (g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_ZBUF) ^ OUTLINE_ZBUF;
5436   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_selection_nooutline"));
5437   g_bIgnoreCommands++;
5438   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_ZBUF));
5439   g_bIgnoreCommands--;
5440   Sys_UpdateWindows (W_CAMERA);
5441 }
5442
5443 void MainFrame::OnSelectionOutlineStyle()
5444 {
5445   if ((g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_ZBUF) && (g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_BSEL))
5446     g_qeglobals.d_savedinfo.iSelectedOutlinesStyle &= ~OUTLINE_ZBUF;
5447   else if (g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_BSEL)
5448     g_qeglobals.d_savedinfo.iSelectedOutlinesStyle &= ~OUTLINE_BSEL;
5449   else if (g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_ZBUF)
5450     g_qeglobals.d_savedinfo.iSelectedOutlinesStyle |= OUTLINE_BSEL;
5451   else
5452     g_qeglobals.d_savedinfo.iSelectedOutlinesStyle |= OUTLINE_ZBUF;
5453   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_selection_nooutline"));
5454   g_bIgnoreCommands++;
5455   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_qeglobals.d_savedinfo.iSelectedOutlinesStyle & OUTLINE_ZBUF));
5456   g_bIgnoreCommands--;
5457   Sys_UpdateWindows (W_CAMERA);
5458 }
5459
5460 void MainFrame::OnSelectionSelectcompletetall()
5461 {
5462   if (ActiveXY())
5463     ActiveXY()->UndoCopy();
5464   Select_CompleteTall ();
5465 }
5466
5467 void MainFrame::OnSelectionSelecttouching()
5468 {
5469   Select_Touching();
5470 }
5471
5472 void MainFrame::OnSelectionSelectpartialtall()
5473 {
5474   Select_PartialTall();
5475 }
5476
5477 void MainFrame::OnSelectionSelectinside()
5478 {
5479   Select_Inside ();
5480 }
5481
5482 void MainFrame::OnViewClipper()
5483 {
5484   GtkWidget *w = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_view_clipper"));
5485   g_bIgnoreCommands++;
5486
5487   if (ActiveXY())
5488   {
5489     if (ActiveXY()->ClipMode())
5490     {
5491       ActiveXY()->SetClipMode(false);
5492       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE);
5493     } else
5494     {
5495       if (ActiveXY()->RotateMode())
5496         OnSelectMouserotate();
5497       ActiveXY()->SetClipMode(true);
5498       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
5499     }
5500   }
5501   g_bIgnoreCommands--;
5502 }
5503
5504 void MainFrame::OnClipSelected()
5505 {
5506   if (m_pActiveXY && m_pActiveXY->ClipMode())
5507   {
5508     Undo_Start("clip selected");
5509     Undo_AddBrushList(&selected_brushes);
5510     m_pActiveXY->Clip();
5511     Undo_EndBrushList(&selected_brushes);
5512     Undo_End();
5513   } else
5514   {
5515     if (g_bPatchBendMode)
5516       Patch_BendHandleENTER();
5517 //    else if (g_bPatchBendMode)
5518 //      Patch_InsDelHandleENTER();
5519   }
5520 }
5521
5522 void MainFrame::OnSplitSelected()
5523 {
5524   if (m_pActiveXY)
5525   {
5526     Undo_Start("split selected");
5527     Undo_AddBrushList(&selected_brushes);
5528     m_pActiveXY->SplitClip();
5529     Undo_EndBrushList(&selected_brushes);
5530     Undo_End();
5531   }
5532 }
5533
5534 void MainFrame::OnFlipClip()
5535 {
5536   if (m_pActiveXY)
5537     m_pActiveXY->FlipClip();
5538 }
5539
5540 void MainFrame::OnSelectionConnect()
5541 {
5542   Undo_Start("connect selected entities");
5543   Undo_AddBrushList(&selected_brushes);
5544   ConnectEntities();
5545   Undo_EndBrushList(&selected_brushes);
5546   Undo_End();
5547 }
5548
5549 void MainFrame::OnSelectionUngroupentity()
5550 {
5551   Undo_Start("ungroup selected entities");
5552   Undo_AddBrushList(&selected_brushes);
5553   Select_Ungroup();
5554   Undo_EndBrushList(&selected_brushes);
5555   Undo_End();
5556 }
5557
5558 void MainFrame::OnSelectionMergeentity()
5559 {
5560   Undo_Start("merge entity");
5561   Undo_AddBrushList(&selected_brushes);
5562   Select_MergeEntity();
5563   Undo_EndBrushList(&selected_brushes);
5564   Undo_End();
5565 }
5566
5567 void MainFrame::OnSelectionGroupworld()
5568 {
5569   Undo_Start("group world");
5570   Undo_AddBrushList(&selected_brushes);
5571   Select_GroupEntity(world_entity);
5572   Undo_EndBrushList(&selected_brushes);
5573   Undo_End();
5574 }
5575
5576 void MainFrame::OnSelectionMakeDetail()
5577 {
5578   Undo_Start("make detail");
5579   Undo_AddBrushList(&selected_brushes);
5580   Select_MakeDetail ();
5581   Undo_EndBrushList(&selected_brushes);
5582   Undo_End();
5583 }
5584
5585 void MainFrame::OnSelectionMakeStructural()
5586 {
5587   Undo_Start("make structural");
5588   Undo_AddBrushList(&selected_brushes);
5589   Select_MakeStructural ();
5590   Undo_EndBrushList(&selected_brushes);
5591   Undo_End();
5592 }
5593
5594 void MainFrame::OnBspCommand (unsigned int nID)
5595 {
5596   // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=503
5597   // make sure we don't attempt to region compile a map with the camera outside the region
5598   if (region_active)
5599   {
5600     vec3_t vOrig;
5601     VectorSet(vOrig,
5602       (int)g_pParentWnd->GetCamWnd()->Camera()->origin[0],
5603       (int)g_pParentWnd->GetCamWnd()->Camera()->origin[1],
5604       (int)g_pParentWnd->GetCamWnd()->Camera()->origin[2]);
5605
5606     int i;
5607     for (i=0 ; i<3 ; i++)
5608     {
5609       if (vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i])
5610       {
5611         Sys_FPrintf(SYS_ERR, "The camera must be in the region to start a region compile.\n");
5612         return;
5613       }
5614     }
5615   }
5616
5617   // if the map has not been saved yet we need to handle it now before we start processing the BSP commands
5618   if (stricmp( currentmap, "unnamed.map") == 0)
5619   {
5620     OnFileSaveas();
5621   }
5622
5623   if (g_PrefsDlg.m_bSnapShots && (stricmp (currentmap, "unnamed.map") != 0))
5624     Map_Snapshot();
5625
5626   if (g_qeglobals.bBSPFrontendPlugin)
5627   {
5628     char *cmd = (char*)g_slist_nth_data (g_BSPFrontendCommands, nID-CMD_BSPCOMMAND);
5629     g_BSPFrontendTable.m_pfnDispatchBSPCommand (cmd);
5630   } else
5631   {
5632     RunBsp (bsp_commands[nID-CMD_BSPCOMMAND]);
5633   }
5634 }
5635
5636 void MainFrame::OnGrid (unsigned int nID)
5637 {
5638   if (nID == ID_GRID_025)
5639   {
5640     g_qeglobals.d_gridsize = 0.25f;
5641     g_qeglobals.d_bSmallGrid = true;
5642   } else if (nID == ID_GRID_05)
5643   {
5644     g_qeglobals.d_gridsize = 0.5f;
5645     g_qeglobals.d_bSmallGrid = true;
5646   } else
5647   {
5648     switch (nID)
5649     {
5650     case ID_GRID_1: g_qeglobals.d_gridsize = 0; break;
5651     case ID_GRID_2: g_qeglobals.d_gridsize = 1; break;
5652     case ID_GRID_4: g_qeglobals.d_gridsize = 2; break;
5653     case ID_GRID_8: g_qeglobals.d_gridsize = 3; break;
5654     case ID_GRID_16: g_qeglobals.d_gridsize = 4; break;
5655     case ID_GRID_32: g_qeglobals.d_gridsize = 5; break;
5656     case ID_GRID_64: g_qeglobals.d_gridsize = 6; break;
5657     case ID_GRID_128: g_qeglobals.d_gridsize = 7; break;
5658     case ID_GRID_256: g_qeglobals.d_gridsize = 8; break;
5659     }
5660     g_qeglobals.d_gridsize = 1 << (int)g_qeglobals.d_gridsize;
5661     g_qeglobals.d_bSmallGrid = false;
5662   }
5663
5664   SetGridStatus();
5665
5666   // SnapTToGrid option: need to check everywhere the grid size is changed
5667   // this is a bit clumsy, have to do in OnGrid OnGridPrev and OnGridNext
5668   if (g_PrefsDlg.m_bSnapTToGrid)
5669     DoSnapTToGrid();
5670
5671   Sys_UpdateWindows (W_XY|W_Z);
5672 }
5673
5674 void MainFrame::OnSnaptogrid()
5675 {
5676   g_PrefsDlg.m_bNoClamp ^= 1;
5677   g_PrefsDlg.SavePrefs ();
5678
5679   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
5680   g_bIgnoreCommands++;
5681   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bNoClamp ? FALSE : TRUE);
5682   g_bIgnoreCommands--;
5683 }
5684
5685 void MainFrame::OnTexturesShowinuse()
5686 {
5687   Sys_BeginWait ();
5688   Texture_ShowInuse ();
5689 #ifdef _DEBUG
5690   if (!g_bShowAllShaders)
5691     Sys_Printf("Already showing only in-use textures.\n");
5692 #endif
5693   Sys_UpdateWindows( W_TEXTURE );
5694   Sys_EndWait ();
5695 }
5696
5697 void MainFrame::OnTexturesShowall()
5698 {
5699   Texture_ShowAll();
5700 }
5701
5702 // do some triggering on/off, if the inspector is already up then hide it
5703 void MainFrame::OnTexturesInspector()
5704 {
5705   ToggleSurface();
5706 }
5707
5708 void MainFrame::OnViewNearest(unsigned int nID)
5709 {
5710   Texture_SetMode(nID);
5711 }
5712
5713 void MainFrame::OnTextureReplaceall()
5714 {
5715   FindTextureDialog::show();
5716 }
5717
5718 void MainFrame::OnToggleLock()
5719 {
5720   g_PrefsDlg.m_bTextureLock = !g_PrefsDlg.m_bTextureLock;
5721
5722   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_toggle_lock"));
5723   g_bIgnoreCommands++;
5724   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bTextureLock ? TRUE : FALSE);
5725   g_bIgnoreCommands--;
5726   g_PrefsDlg.SavePrefs ();
5727   SetGridStatus();
5728 }
5729
5730 void MainFrame::OnToggleRotatelock()
5731 {
5732   g_PrefsDlg.m_bRotateLock ^= 1;
5733
5734   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_toggle_rotatelock"));
5735   g_bIgnoreCommands++;
5736   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bRotateLock ? TRUE : FALSE);
5737   g_bIgnoreCommands--;
5738   g_PrefsDlg.SavePrefs ();
5739   SetGridStatus();
5740 }
5741
5742 // use a dialog for direct selection of a texture menu
5743 // the API is a bit crappy, we need to set texture_directory to the directory name in <basepath>/textures/
5744 void MainFrame::OnTexturesLoad()
5745 {
5746   char def_path[NAME_MAX];
5747
5748         // FIXME
5749         // check if that works with fs_game (I suspect some more design is needed)
5750         // see how this is done in 1.2?
5751         // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=507
5752   strcpy (def_path, g_pGameDescription->mEnginePath.GetBuffer());
5753   strcat (def_path, g_pGameDescription->mBaseGame.GetBuffer());
5754   strcat (def_path, "/");
5755
5756   char *dir = dir_dialog (m_pWidget, "Load textures from path", def_path);
5757
5758   if (dir != NULL)
5759   {
5760     // very uncertain task, let's hope the guy pointed to somewhere below the dir we gave him
5761     Sys_Printf("user select: '%s'\n", dir);
5762     // remove a potential trailing slash?
5763     if (dir[strlen(dir)-1]=='/' || dir[strlen(dir)-1]=='\\')
5764       dir[strlen(dir)-1] = '\0';
5765     char *pouic = MAX(strrchr(dir, '/'),strrchr(dir, '\\'));
5766     if (pouic)
5767     {
5768       strcpy(texture_directory, pouic+1);
5769       Sys_Printf("Loading '%s'\n", texture_directory);
5770       Texture_ShowDirectory();
5771     }
5772     else
5773       Sys_FPrintf(SYS_WRN, "Failed to extract the directory\n");
5774     g_free(dir);
5775   }
5776   else
5777     Sys_FPrintf(SYS_WRN, "texture load dialog cancelled\n");
5778 }
5779
5780 void MainFrame::OnTexturesReloadshaders()
5781 {
5782   Sys_BeginWait ();
5783   QERApp_ReloadShaders();
5784   // current shader
5785   // NOTE: we are kinda making it loop on itself, it will update the pShader and scroll the texture window
5786   Texture_SetTexture (&g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, NULL, false);
5787   Sys_UpdateWindows (W_ALL);
5788   Sys_EndWait();
5789 }
5790
5791 void MainFrame::OnTexturesShadersShow()
5792 {
5793   g_PrefsDlg.m_bShowShaders ^= 1;
5794   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_shaders_show"));
5795   g_bIgnoreCommands++;
5796   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bShowShaders ? TRUE : FALSE);
5797   g_bIgnoreCommands--;
5798   Sys_UpdateWindows(W_TEXTURE);
5799 }
5800
5801 void MainFrame::SetTextureScale(int id)
5802 {
5803   GtkWidget *item;
5804
5805   switch (id)
5806   {
5807   case ID_TEXTURES_TEXTUREWINDOWSCALE_10:
5808     g_PrefsDlg.m_nTextureScale = 10;
5809     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_texturewindowscale_10"));
5810     break;
5811   case ID_TEXTURES_TEXTUREWINDOWSCALE_25:
5812     g_PrefsDlg.m_nTextureScale = 25;
5813     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_texturewindowscale_25"));
5814     break;
5815   case ID_TEXTURES_TEXTUREWINDOWSCALE_50:
5816     g_PrefsDlg.m_nTextureScale = 50;
5817     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_texturewindowscale_50"));
5818     break;
5819   case ID_TEXTURES_TEXTUREWINDOWSCALE_200:
5820     g_PrefsDlg.m_nTextureScale = 200;
5821     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_texturewindowscale_200"));
5822     break;
5823   default:
5824     g_PrefsDlg.m_nTextureScale = 100;
5825     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_textures_texturewindowscale_100"));
5826     break;
5827   }
5828
5829   g_bIgnoreCommands++;
5830   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
5831   g_bIgnoreCommands--;
5832
5833   Texture_ResetPosition();
5834 }
5835
5836 void MainFrame::OnTexturewindowScaleup()
5837 {
5838   switch(g_PrefsDlg.m_nTextureScale) {
5839   // 200, all the way in, don't do anything
5840   case 100:
5841     SetTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_200);
5842     break;
5843   case 50:
5844     SetTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_100);
5845     break;
5846   case 25:
5847     SetTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_50);
5848     break;
5849   case 10:
5850     SetTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_25);
5851     break;
5852   }
5853 }
5854
5855 void MainFrame::OnTexturewindowScaledown()
5856 {
5857   switch(g_PrefsDlg.m_nTextureScale) {
5858   case 200:
5859     SetTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_100);
5860     break;
5861   case 100:
5862     SetTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_50);
5863     break;
5864   case 50:
5865     SetTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_25);
5866     break;
5867   case 25:
5868     SetTextureScale(ID_TEXTURES_TEXTUREWINDOWSCALE_10);
5869     break;
5870   // 10, all the way out, don't do anything
5871   }
5872 }
5873
5874 void MainFrame::OnTexturesLoadlist()
5875 {
5876   DoTextureListDlg ();
5877 }
5878
5879 void MainFrame::OnTexturesShaderlistonly()
5880 {
5881   g_PrefsDlg.m_bTexturesShaderlistOnly ^= 1;
5882   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget),"menu_textures_shaderlistonly"));
5883   g_bIgnoreCommands++;
5884   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bTexturesShaderlistOnly ? TRUE : FALSE);
5885   g_bIgnoreCommands--;
5886   FillTextureMenu();
5887 }
5888
5889 void MainFrame::OnTextureWad(unsigned int nID)
5890 {
5891   Sys_BeginWait ();
5892   Texture_ShowDirectory (nID);
5893   Sys_UpdateWindows (W_ALL);
5894   Sys_EndWait ();
5895 }
5896
5897 void MainFrame::OnMiscBenchmark()
5898 {
5899   m_pCamWnd->BenchMark();
5900 }
5901
5902 void MainFrame::OnColorSetoriginal()
5903 {
5904   for (int i=0 ; i<3 ; i++)
5905   {
5906     g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.25f;
5907     g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 1.0f;
5908     g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.75f;
5909     g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.5f;
5910     g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25f;
5911   }
5912
5913   //djbob
5914   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR_ALT][0] = 0.5f;
5915   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR_ALT][1] = 0.0f;
5916   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR_ALT][2] = 0.0f;
5917
5918   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR_ALT][0] = 1.0f;
5919   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR_ALT][1] = 0.0f;
5920   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR_ALT][2] = 0.0f;
5921   //-djbob
5922
5923   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 0.0f;
5924   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 0.0f;
5925   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0f;
5926
5927   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0f;
5928   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0f;
5929   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0f;
5930
5931   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f;
5932   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0f;
5933   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0f;
5934
5935   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0f;
5936   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0f;
5937   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0f;
5938
5939   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0f;
5940   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0f;
5941   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0f;
5942
5943   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5f;
5944   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0f;
5945   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.75f;
5946
5947   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][0] = 1.0f;
5948   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][1] = 0.0f;
5949   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][2] = 0.0f;
5950
5951   Sys_UpdateWindows (W_ALL);
5952 }
5953
5954 void MainFrame::OnColorSetqer()
5955 {
5956   for (int i=0 ; i<3 ; i++)
5957   {
5958     g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.25f;
5959     g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 1.0f;
5960     g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 1.0f;
5961     g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.5f;
5962     g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25f;
5963   }
5964
5965   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 0.0f;
5966   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 0.0f;
5967   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0f;
5968
5969   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0f;
5970   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0f;
5971   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0f;
5972
5973   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f;
5974   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0f;
5975   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0f;
5976
5977   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0f;
5978   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0f;
5979   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0f;
5980
5981   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0f;
5982   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0f;
5983   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0f;
5984
5985   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5f;
5986   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0f;
5987   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.75f;
5988
5989   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][0] = 1.0f;
5990   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][1] = 0.0f;
5991   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][2] = 0.0f;
5992
5993   Sys_UpdateWindows (W_ALL);
5994 }
5995
5996 void MainFrame::OnColorSetblack()
5997 {
5998   for (int i=0 ; i<3 ; i++)
5999   {
6000     g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.25f;
6001     g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 0.0f;
6002     g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.2f;
6003     g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25f;
6004   }
6005
6006   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][0] = 0.3f;
6007   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][1] = 0.5f;
6008   g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][2] = 0.5f;
6009
6010   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 0.0f;
6011   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 0.0f;
6012   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0f;
6013
6014   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 1.0f;
6015   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 1.0f;
6016   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 1.0f;
6017
6018   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f;
6019   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0f;
6020   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0f;
6021
6022   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0f;
6023   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0f;
6024   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0f;
6025
6026   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 1.0f;
6027   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 1.0f;
6028   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 1.0f;
6029
6030   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.7f;
6031   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.7f;
6032   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.0f;
6033
6034   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][0] = 1.0f;
6035   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][1] = 0.0f;
6036   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][2] = 0.0f;
6037
6038   Sys_UpdateWindows (W_ALL);
6039 }
6040
6041 /* ydnar: to emulate maya/max/lightwave color schemes */
6042 void MainFrame::OnColorSetydnar()
6043 {
6044   for (int i=0 ; i<3 ; i++)
6045   {
6046     g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][i] = 0.25f;
6047     g_qeglobals.d_savedinfo.colors[COLOR_GRIDBACK][i] = 0.77f;
6048     g_qeglobals.d_savedinfo.colors[COLOR_GRIDMINOR][i] = 0.83f;
6049     g_qeglobals.d_savedinfo.colors[COLOR_GRIDMAJOR][i] = 0.89f;
6050     g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][i] = 0.25f;
6051   }
6052
6053   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][0] = 1.0f;
6054   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][1] = 1.0f;
6055   g_qeglobals.d_savedinfo.colors[COLOR_GRIDBLOCK][2] = 1.0f;
6056
6057   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][0] = 0.0f;
6058   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][1] = 0.0f;
6059   g_qeglobals.d_savedinfo.colors[COLOR_GRIDTEXT][2] = 0.0f;
6060
6061   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][0] = 1.0f;
6062   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][1] = 0.0f;
6063   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES][2] = 0.0f;
6064
6065   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][0] = 0.0f;
6066   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][1] = 0.0f;
6067   g_qeglobals.d_savedinfo.colors[COLOR_CLIPPER][2] = 1.0f;
6068
6069   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][0] = 0.0f;
6070   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][1] = 0.0f;
6071   g_qeglobals.d_savedinfo.colors[COLOR_BRUSHES][2] = 0.0f;
6072
6073   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][0] = 0.5f;
6074   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][1] = 0.0f;
6075   g_qeglobals.d_savedinfo.colors[COLOR_VIEWNAME][2] = 0.75f;
6076
6077   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][0] = 1.0f;
6078   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][1] = 0.0f;
6079   g_qeglobals.d_savedinfo.colors[COLOR_SELBRUSHES3D][2] = 0.0f;
6080
6081   Sys_UpdateWindows (W_ALL);
6082 }
6083
6084 void MainFrame::OnTexturebk()
6085 {
6086   DoColor(COLOR_TEXTUREBACK);
6087   Sys_UpdateWindows (W_ALL);
6088 }
6089
6090 void MainFrame::OnColorsXybk()
6091 {
6092   DoColor(COLOR_GRIDBACK);
6093   Sys_UpdateWindows (W_ALL);
6094 }
6095
6096 void MainFrame::OnColorsMajor()
6097 {
6098   DoColor(COLOR_GRIDMAJOR);
6099   Sys_UpdateWindows (W_ALL);
6100 }
6101
6102 void MainFrame::OnColorsMinor()
6103 {
6104   DoColor(COLOR_GRIDMINOR);
6105   Sys_UpdateWindows (W_ALL);
6106 }
6107
6108 void MainFrame::OnColorsMajor_Alt()
6109 {
6110   DoColor(COLOR_GRIDMAJOR_ALT);
6111   Sys_UpdateWindows (W_ALL);
6112 }
6113
6114 void MainFrame::OnColorsMinor_Alt()
6115 {
6116   DoColor(COLOR_GRIDMINOR_ALT);
6117   Sys_UpdateWindows (W_ALL);
6118 }
6119
6120 void MainFrame::OnColorsGridtext()
6121 {
6122   DoColor(COLOR_GRIDTEXT);
6123   Sys_UpdateWindows (W_ALL);
6124 }
6125
6126 void MainFrame::OnColorsGridblock()
6127 {
6128   DoColor(COLOR_GRIDBLOCK);
6129   Sys_UpdateWindows (W_ALL);
6130 }
6131
6132 void MainFrame::OnColorsCameraBack()
6133 {
6134   DoColor(COLOR_CAMERABACK);
6135   Sys_UpdateWindows (W_ALL);
6136 }
6137
6138 void MainFrame::OnColorsBrush()
6139 {
6140   DoColor(COLOR_BRUSHES);
6141   Sys_UpdateWindows (W_ALL);
6142 }
6143
6144 void MainFrame::OnColorsSelectedbrush()
6145 {
6146   DoColor(COLOR_SELBRUSHES);
6147   Sys_UpdateWindows (W_ALL);
6148 }
6149
6150 void MainFrame::OnColorsSelectedbrush3D()
6151 {
6152   DoColor(COLOR_SELBRUSHES3D);
6153   Sys_UpdateWindows (W_ALL);
6154 }
6155
6156 void MainFrame::OnColorsClipper()
6157 {
6158   DoColor(COLOR_CLIPPER);
6159   Sys_UpdateWindows (W_ALL);
6160 }
6161
6162 void MainFrame::OnColorsViewname()
6163 {
6164   DoColor(COLOR_VIEWNAME);
6165   Sys_UpdateWindows (W_ALL);
6166 }
6167
6168 void MainFrame::OnMiscGamma()
6169 {
6170   float fSave = g_qeglobals.d_savedinfo.fGamma;
6171   DoGamma();
6172   if (fSave != g_qeglobals.d_savedinfo.fGamma)
6173   {
6174     gtk_MessageBox(m_pWidget, "You must restart Radiant for Gamma settings to take effect.");
6175   }
6176 }
6177 void MainFrame::OnMiscFindbrush()
6178 {
6179   DoFind();
6180 }
6181
6182 void MainFrame::OnMiscNextleakspot()
6183 {
6184   Pointfile_Next();
6185 }
6186
6187 void MainFrame::OnMiscPreviousleakspot()
6188 {
6189   Pointfile_Prev();
6190 }
6191
6192 void MainFrame::OnMiscPrintxy()
6193 {
6194 //  WXY_Print();
6195 }
6196
6197 void MainFrame::OnMiscSelectentitycolor()
6198 {
6199   if (edit_entity)
6200   {
6201     CString strColor = ValueForKey(edit_entity, "_color");
6202     if (strColor.GetLength() > 0)
6203     {
6204       float fR, fG, fB;
6205       int n = sscanf(strColor,"%f %f %f", &fR, &fG, &fB);
6206       if (n == 3)
6207       {
6208         g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][0] = fR;
6209         g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][1] = fG;
6210         g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][2] = fB;
6211       }
6212     }
6213
6214     if (inspector_mode == W_ENTITY && (DoColor(COLOR_ENTITY)))
6215     {
6216       char buffer[100];
6217       sprintf(buffer, "%f %f %f", g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][0],
6218               g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][1],
6219               g_qeglobals.d_savedinfo.colors[COLOR_ENTITY][2]);
6220
6221       gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntValueField]), buffer);
6222       gtk_entry_set_text (GTK_ENTRY (EntWidgets[EntKeyField]), "_color");
6223       AddProp();
6224       //DK - SOF change to get color to entity quickly
6225       //--::SetWindowText( hwndEnt[EntValueField], buffer );
6226       //--::SetWindowText( hwndEnt[EntKeyField], "color" );
6227       //--AddProp();
6228     }
6229     Sys_UpdateWindows( W_ALL );
6230   }
6231 }
6232
6233 void MainFrame::OnConvertcurves()
6234 {
6235 #if 0
6236   Select_Deselect();
6237   for (brush_t* pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next)
6238   {
6239     if (pb->curveBrush)
6240     {
6241       for (face_t* f = pb->brush_faces ; f ; f=f->next)
6242       {
6243         if (f->texdef.contents & CONTENTS_LADDER)
6244         {
6245           f->texdef.contents &= ~CONTENTS_LADDER;
6246           f->texdef.contents |= CONTENTS_NEGATIVE_CURVE;
6247         }
6248       }
6249     }
6250   }
6251   Map_BuildBrushData();
6252 #endif
6253 }
6254
6255 void MainFrame::OnRegionOff()
6256 {
6257   Map_RegionOff ();
6258 }
6259
6260 void MainFrame::OnRegionSetxy()
6261 {
6262   Map_RegionXY ();
6263 }
6264
6265 void MainFrame::OnRegionSettallbrush()
6266 {
6267   Map_RegionTallBrush ();
6268 }
6269
6270 void MainFrame::OnRegionSetbrush()
6271 {
6272   Map_RegionBrush ();
6273 }
6274
6275 void MainFrame::OnRegionSetselection()
6276 {
6277   Map_RegionSelectedBrushes ();
6278 }
6279
6280 void MainFrame::OnBrush3sided()
6281 {
6282   Undo_Start("3 sided");
6283   Undo_AddBrushList(&selected_brushes);
6284   Brush_MakeSided(3);
6285   Undo_EndBrushList(&selected_brushes);
6286   Undo_End();
6287 }
6288
6289 void MainFrame::OnBrush4sided()
6290 {
6291   Undo_Start("4 sided");
6292   Undo_AddBrushList(&selected_brushes);
6293   Brush_MakeSided(4);
6294   Undo_EndBrushList(&selected_brushes);
6295   Undo_End();
6296 }
6297
6298 void MainFrame::OnBrush5sided()
6299 {
6300   Undo_Start("5 sided");
6301   Undo_AddBrushList(&selected_brushes);
6302   Brush_MakeSided(5);
6303   Undo_EndBrushList(&selected_brushes);
6304   Undo_End();
6305 }
6306
6307 void MainFrame::OnBrush6sided()
6308 {
6309   Undo_Start("6 sided");
6310   Undo_AddBrushList(&selected_brushes);
6311   Brush_MakeSided(6);
6312   Undo_EndBrushList(&selected_brushes);
6313   Undo_End();
6314 }
6315
6316 void MainFrame::OnBrush7sided()
6317 {
6318   Undo_Start("7 sided");
6319   Undo_AddBrushList(&selected_brushes);
6320   Brush_MakeSided(7);
6321   Undo_EndBrushList(&selected_brushes);
6322   Undo_End();
6323 }
6324
6325 void MainFrame::OnBrush8sided()
6326 {
6327   Undo_Start("8 sided");
6328   Undo_AddBrushList(&selected_brushes);
6329   Brush_MakeSided(8);
6330   Undo_EndBrushList(&selected_brushes);
6331   Undo_End();
6332 }
6333
6334 void MainFrame::OnBrush9sided()
6335 {
6336   Undo_Start("9 sided");
6337   Undo_AddBrushList(&selected_brushes);
6338   Brush_MakeSided(9);
6339   Undo_EndBrushList(&selected_brushes);
6340   Undo_End();
6341 }
6342
6343 void MainFrame::OnBrushArbitrarysided()
6344 {
6345   Undo_Start("arbitrary sided");
6346   Undo_AddBrushList(&selected_brushes);
6347   DoSides();
6348   Undo_EndBrushList(&selected_brushes);
6349   Undo_End();
6350 }
6351
6352 void MainFrame::OnBrushMakecone()
6353 {
6354   Undo_Start("make cone");
6355   Undo_AddBrushList(&selected_brushes);
6356   DoSides(true);
6357   Undo_EndBrushList(&selected_brushes);
6358   Undo_End();
6359 }
6360
6361 void MainFrame::OnBrushPrimitivesSphere()
6362 {
6363   Undo_Start("make sphere");
6364   Undo_AddBrushList(&selected_brushes);
6365
6366   DoSides(false, true);
6367
6368   Undo_EndBrushList(&selected_brushes);
6369   Undo_End();
6370 }
6371
6372 void MainFrame::OnCurvePatchtube()
6373 {
6374   Undo_Start("make curve cylinder");
6375   Undo_AddBrushList(&selected_brushes);
6376   Patch_BrushToMesh(false);
6377   Sys_UpdateWindows (W_ALL);
6378   Undo_EndBrushList(&selected_brushes);
6379   Undo_End();
6380 }
6381
6382 void MainFrame::OnCurvePatchdensetube()
6383 {
6384   Undo_Start("dense cylinder");
6385   Undo_AddBrushList(&selected_brushes);
6386
6387   Patch_BrushToMesh(false);
6388   OnCurveInsertAddrow();
6389   Sys_UpdateWindows (W_ALL);
6390
6391   Undo_EndBrushList(&selected_brushes);
6392   Undo_End();
6393 }
6394
6395 void MainFrame::OnCurvePatchverydensetube()
6396 {
6397   Undo_Start("very dense cylinder");
6398   Undo_AddBrushList(&selected_brushes);
6399
6400   Patch_BrushToMesh(false);
6401   OnCurveInsertAddrow();
6402   OnCurveInsertInsertrow();
6403   OnCurveInsertAddrow();
6404   Sys_UpdateWindows (W_ALL);
6405
6406   Undo_EndBrushList(&selected_brushes);
6407   Undo_End();
6408 }
6409
6410 void MainFrame::OnCurvePatchsquare()
6411 {
6412   Undo_Start("square cylinder");
6413   Undo_AddBrushList(&selected_brushes);
6414
6415   Patch_BrushToMesh(false, false, false, true);
6416   Sys_UpdateWindows (W_ALL);
6417
6418   Undo_EndBrushList(&selected_brushes);
6419   Undo_End();
6420 }
6421
6422 void MainFrame::OnCurvePatchendcap()
6423 {
6424   Undo_Start("make end cap");
6425   Undo_AddBrushList(&selected_brushes);
6426   Patch_BrushToMesh(false, false, true);
6427   Sys_UpdateWindows (W_ALL);
6428   Undo_EndBrushList(&selected_brushes);
6429   Undo_End();
6430 }
6431
6432 void MainFrame::OnCurvePatchbevel()
6433 {
6434   Undo_Start("make bevel");
6435   Undo_AddBrushList(&selected_brushes);
6436   Patch_BrushToMesh(false, true, false);
6437   Sys_UpdateWindows (W_ALL);
6438   Undo_EndBrushList(&selected_brushes);
6439   Undo_End();
6440 }
6441
6442 void MainFrame::OnCurveMoreendcapsbevelsSquarebevel()
6443 {
6444   Undo_Start("square bevel");
6445   Undo_AddBrushList(&selected_brushes);
6446
6447   Patch_BrushToMesh(false, true, false, true);
6448   Sys_UpdateWindows (W_ALL);
6449
6450   Undo_EndBrushList(&selected_brushes);
6451   Undo_End();
6452 }
6453
6454 void MainFrame::OnCurveMoreendcapsbevelsSquareendcap()
6455 {
6456   Undo_Start("square endcap");
6457   Undo_AddBrushList(&selected_brushes);
6458
6459   Patch_BrushToMesh(false, false, true, true);
6460   Sys_UpdateWindows (W_ALL);
6461
6462   Undo_EndBrushList(&selected_brushes);
6463   Undo_End();
6464 }
6465
6466 void MainFrame::OnCurvePatchcone()
6467 {
6468   Undo_Start("make curve cone");
6469   Undo_AddBrushList(&selected_brushes);
6470   Patch_BrushToMesh(true);
6471   Sys_UpdateWindows (W_ALL);
6472   Undo_EndBrushList(&selected_brushes);
6473   Undo_End();
6474 }
6475
6476 void MainFrame::OnCurveSimplepatchmesh()
6477 {
6478   Undo_Start("make simpe patch mesh");
6479   Undo_AddBrushList(&selected_brushes);
6480   DoNewPatchDlg ();
6481   Undo_EndBrushList(&selected_brushes);
6482   Undo_End();
6483 }
6484
6485 void MainFrame::OnCurveInsertInsertcolumn()
6486 {
6487   Undo_Start("insert (2) columns");
6488   Undo_AddBrushList(&selected_brushes);
6489   Patch_AdjustSelected(true, true, false);
6490   Sys_UpdateWindows(W_ALL);
6491   Undo_EndBrushList(&selected_brushes);
6492   Undo_End();
6493 }
6494
6495 void MainFrame::OnCurveInsertAddcolumn()
6496 {
6497   Undo_Start("add (2) columns");
6498   Undo_AddBrushList(&selected_brushes);
6499   Patch_AdjustSelected(true, true, true);
6500   Sys_UpdateWindows(W_ALL);
6501   Undo_EndBrushList(&selected_brushes);
6502   Undo_End();
6503 }
6504
6505 void MainFrame::OnCurveInsertInsertrow()
6506 {
6507   Undo_Start("insert (2) rows");
6508   Undo_AddBrushList(&selected_brushes);
6509   Patch_AdjustSelected(true, false, false);
6510   Sys_UpdateWindows(W_ALL);
6511   Undo_EndBrushList(&selected_brushes);
6512   Undo_End();
6513 }
6514
6515 void MainFrame::OnCurveInsertAddrow()
6516 {
6517   Undo_Start("add (2) rows");
6518   Undo_AddBrushList(&selected_brushes);
6519   Patch_AdjustSelected(true, false, true);
6520   Sys_UpdateWindows(W_ALL);
6521   Undo_EndBrushList(&selected_brushes);
6522   Undo_End();
6523 }
6524
6525 void MainFrame::OnCurveDeleteFirstcolumn()
6526 {
6527   Undo_Start("delete first (2) columns");
6528   Undo_AddBrushList(&selected_brushes);
6529   Patch_AdjustSelected(false, true, true);
6530   Sys_UpdateWindows(W_ALL);
6531   Undo_EndBrushList(&selected_brushes);
6532   Undo_End();
6533 }
6534
6535 void MainFrame::OnCurveDeleteLastcolumn()
6536 {
6537   Undo_Start("delete last (2) columns");
6538   Undo_AddBrushList(&selected_brushes);
6539   Patch_AdjustSelected(false, true, false);
6540   Sys_UpdateWindows(W_ALL);
6541   Undo_EndBrushList(&selected_brushes);
6542   Undo_End();
6543 }
6544
6545 void MainFrame::OnCurveDeleteFirstrow()
6546 {
6547   Undo_Start("delete first (2) rows");
6548   Undo_AddBrushList(&selected_brushes);
6549   Patch_AdjustSelected(false, false, true);
6550   Sys_UpdateWindows(W_ALL);
6551   Undo_EndBrushList(&selected_brushes);
6552   Undo_End();
6553 }
6554
6555 void MainFrame::OnCurveDeleteLastrow()
6556 {
6557   Undo_Start("delete last (2) rows");
6558   Undo_AddBrushList(&selected_brushes);
6559   Patch_AdjustSelected(false, false, false);
6560   Sys_UpdateWindows(W_ALL);
6561   Undo_EndBrushList(&selected_brushes);
6562   Undo_End();
6563 }
6564
6565 void MainFrame::OnCurveNegative()
6566 {
6567   Patch_ToggleInverted();
6568   //Sys_UpdateWindows(W_ALL);
6569 }
6570
6571 void MainFrame::OnCurveRedisperseRows()
6572 {
6573   Undo_Start("redisperse rows");
6574   Undo_AddBrushList(&selected_brushes);
6575   Patch_DisperseRows();
6576   Sys_UpdateWindows (W_ALL);
6577   Undo_EndBrushList(&selected_brushes);
6578   Undo_End();
6579 }
6580
6581 void MainFrame::OnCurveRedisperseIntermediateCols()
6582 {
6583   Undo_Start("redisperse im cols");
6584   Undo_AddBrushList(&selected_brushes);
6585   Patch_DisperseIntermediateColumns();
6586   Sys_UpdateWindows (W_ALL);
6587   Undo_EndBrushList(&selected_brushes);
6588   Undo_End();
6589 }
6590
6591 void MainFrame::OnCurveRedisperseIntermediateRows()
6592 {
6593   Undo_Start("redisperse im rows");
6594   Undo_AddBrushList(&selected_brushes);
6595   Patch_DisperseIntermediateRows();
6596   Sys_UpdateWindows (W_ALL);
6597   Undo_EndBrushList(&selected_brushes);
6598   Undo_End();
6599 }
6600
6601 void MainFrame::OnCurveMatrixTranspose()
6602 {
6603   Patch_Transpose();
6604   Sys_UpdateWindows (W_ALL);
6605 }
6606
6607 void MainFrame::OnCurveCap()
6608 {
6609   Patch_CapCurrent();
6610   Sys_UpdateWindows (W_ALL);
6611 }
6612
6613 void MainFrame::OnCurveCyclecap()
6614 {
6615   Patch_CycleCapSelected();
6616   Sys_UpdateWindows (W_ALL);
6617 }
6618
6619 void MainFrame::OnCurveOverlaySet()
6620 {
6621   Patch_SetOverlays();
6622   Sys_UpdateWindows(W_ALL);
6623 }
6624
6625 void MainFrame::OnCurveOverlayClear()
6626 {
6627   Patch_ClearOverlays();
6628   Sys_UpdateWindows(W_ALL);
6629 }
6630
6631 void MainFrame::OnCurveThicken()
6632 {
6633   Undo_Start("curve thicken");
6634   Undo_AddBrushList(&selected_brushes);
6635   DoThickenDlg ();
6636   Undo_EndBrushList(&selected_brushes);
6637   Undo_End();
6638 }
6639
6640 /*!
6641 this can no longer be trigger manually from the menu
6642 happens only once at startup
6643 */
6644 void MainFrame::OnPluginsRefresh()
6645 {
6646   CleanPlugInMenu();
6647   m_PlugInMgr.Init();
6648 }
6649
6650 // open the Q3Rad manual
6651 void MainFrame::OnHelp()
6652 {
6653   // at least on win32, g_strGameToolsPath + "Q3Rad_Manual/index.htm"
6654   Str help;
6655   help = g_strAppPath;
6656   help += "Q3Rad_Manual/index.htm";
6657   OpenURL(help.GetBuffer());
6658 }
6659
6660 // FIXME: we'll go towards a unified help thing soon
6661 void MainFrame::OnHelpLinks()
6662 {
6663   Str link;
6664   link = g_strAppPath;
6665   link += "links.htm";
6666   OpenURL(link.GetBuffer());
6667 }
6668
6669 void MainFrame::OnHelpBugreport()
6670 {
6671   OpenURL("http://www.qeradiant.com/faq/fom-serve/cache/138.html");
6672 }
6673
6674 void MainFrame::OnHelpCommandlist()
6675 {
6676   DoCommandListDlg ();
6677 }
6678
6679 void MainFrame::OnHelpAbout()
6680 {
6681   DoAbout();
6682 }
6683
6684 void MainFrame::OnPopupSelection()
6685 {
6686   GtkWidget *menu, *item;
6687   const gchar *labels[] = { _("Select Complete Tall"), _("Select Touching"), _("Select Partial Tall"), _("Select Inside")};
6688   int ids[] = { ID_SELECTION_SELECTCOMPLETETALL, ID_SELECTION_SELECTTOUCHING,
6689     ID_SELECTION_SELECTPARTIALTALL, ID_SELECTION_SELECTINSIDE};
6690
6691   menu = gtk_menu_new ();
6692
6693   for (int i = 0; i < 4; i++)
6694   {
6695     item = gtk_menu_item_new_with_label (labels[i]);
6696     gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (HandleCommand),
6697                         GINT_TO_POINTER (ids[i]));
6698     gtk_widget_show (item);
6699     gtk_menu_append (GTK_MENU (menu), item);
6700   }
6701
6702   gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME);
6703 }
6704
6705 void MainFrame::OnViewChange()
6706 {
6707   OnViewNextview();
6708   //HandlePopup(this, IDR_POPUP_VIEW);
6709 }
6710
6711 void MainFrame::OnTexturesPopup()
6712 {
6713   gpointer item = g_object_get_data (G_OBJECT (m_pWidget), "render_quality_menu");
6714   gtk_menu_popup (GTK_MENU (item), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME);
6715 }
6716
6717 void MainFrame::ToggleCamera()
6718 {
6719   if (m_bCamPreview)
6720     m_bCamPreview = false;
6721   else
6722     m_bCamPreview = true;
6723 }
6724
6725 void MainFrame::OnViewCameraupdate()
6726 {
6727   Sys_UpdateWindows(W_CAMERA);
6728 }
6729
6730 void MainFrame::OnSelectMouserotate()
6731 {
6732   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_select_mouserotate"));
6733   g_bIgnoreCommands++;
6734
6735   if (ActiveXY())
6736   {
6737     if (ActiveXY()->ClipMode())
6738       OnViewClipper();
6739     if (ActiveXY()->RotateMode())
6740     {
6741       // SetRotateMode(false) always works
6742       ActiveXY()->SetRotateMode(false);
6743       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), FALSE);
6744     } else
6745     {
6746       // may not work if no brush selected, see return value
6747       if (ActiveXY()->SetRotateMode(true))
6748         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), TRUE);
6749       else
6750         // if MFC called, we need to set back to FALSE ourselves
6751         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), FALSE);
6752     }
6753   }
6754   g_bIgnoreCommands--;
6755 }
6756
6757 void MainFrame::OnSelectMousescale()
6758 {
6759   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_select_mousescale"));
6760   g_bIgnoreCommands++;
6761
6762   if (ActiveXY())
6763   {
6764     if (ActiveXY()->ClipMode())
6765       OnViewClipper();
6766     if (ActiveXY()->RotateMode())
6767     {
6768       // SetRotateMode(false) always works
6769       ActiveXY()->SetRotateMode(false);
6770       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), FALSE);
6771     }
6772     if (ActiveXY()->ScaleMode())
6773     {
6774       ActiveXY()->SetScaleMode(false);
6775       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), FALSE);
6776     } else
6777     {
6778       ActiveXY()->SetScaleMode(true);
6779       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), TRUE);
6780     }
6781   }
6782   g_bIgnoreCommands--;
6783 }
6784
6785 void MainFrame::OnScalelockx()
6786 {
6787   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_scalelockx"));
6788   g_bIgnoreCommands++;
6789
6790   if (g_nScaleHow & SCALE_X)
6791   {
6792     g_nScaleHow ^= SCALE_X;
6793     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), FALSE);
6794   } else
6795   {
6796     g_nScaleHow |= SCALE_X;
6797     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), TRUE);
6798   }
6799   g_bIgnoreCommands--;
6800 }
6801
6802 void MainFrame::OnScalelocky()
6803 {
6804   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_scalelocky"));
6805   g_bIgnoreCommands++;
6806
6807   if (g_nScaleHow & SCALE_Y)
6808   {
6809     g_nScaleHow ^= SCALE_Y;
6810     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), FALSE);
6811   } else
6812   {
6813     g_nScaleHow |= SCALE_Y;
6814     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), TRUE);
6815   }
6816   g_bIgnoreCommands--;
6817 }
6818
6819 void MainFrame::OnScalelockz()
6820 {
6821   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_scalelockz"));
6822   g_bIgnoreCommands++;
6823
6824   if (g_nScaleHow & SCALE_Z)
6825   {
6826     g_nScaleHow ^= SCALE_Z;
6827     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), FALSE);
6828   } else
6829   {
6830     g_nScaleHow |= SCALE_Z;
6831     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), TRUE);
6832   }
6833   g_bIgnoreCommands--;
6834 }
6835
6836 void MainFrame::OnDontselectcurve()
6837 {
6838   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_dontselectcurve"));
6839   g_bIgnoreCommands++;
6840   g_PrefsDlg.m_bSelectCurves ^= 1;
6841   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bSelectCurves) ? FALSE : TRUE);
6842   g_bIgnoreCommands--;
6843 }
6844
6845 void MainFrame::OnPatchToggleBox()
6846 {
6847   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_showboundingbox"));
6848   g_bIgnoreCommands++;
6849   g_bPatchShowBounds ^= 1;
6850   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchShowBounds) ? TRUE : FALSE);
6851   g_bIgnoreCommands--;
6852   Sys_UpdateWindows(W_ALL);
6853 }
6854
6855 void MainFrame::OnPatchWireframe()
6856 {
6857   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_wireframe"));
6858   g_bIgnoreCommands++;
6859   g_bPatchWireFrame ^= 1;
6860   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchWireFrame) ? TRUE : FALSE);
6861   g_bIgnoreCommands--;
6862   Sys_UpdateWindows(W_ALL);
6863 }
6864
6865 void MainFrame::OnPatchBend()
6866 {
6867   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_bend"));
6868   g_bIgnoreCommands++;
6869   Patch_BendToggle();
6870   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchBendMode) ? TRUE : FALSE);
6871   g_bIgnoreCommands--;
6872   Sys_UpdateWindows(W_ALL);
6873 }
6874
6875 void MainFrame::OnPatchWeld()
6876 {
6877   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_weld"));
6878   g_bIgnoreCommands++;
6879   g_bPatchWeld ^= 1;
6880   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchWeld) ? TRUE : FALSE);
6881   g_bIgnoreCommands--;
6882   Sys_UpdateWindows(W_ALL);
6883 }
6884
6885 void MainFrame::OnPatchDrilldown()
6886 {
6887   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_patch_drilldown"));
6888   g_bIgnoreCommands++;
6889   g_bPatchDrillDown ^= 1;
6890   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_bPatchDrillDown) ? TRUE : FALSE);
6891   g_bIgnoreCommands--;
6892   Sys_UpdateWindows(W_ALL);
6893 }
6894
6895 void MainFrame::OnShowEntities()
6896 {
6897   gpointer item = g_object_get_data (G_OBJECT (m_pWidget), "view_entitiesas_menu"); // use pointer to existing menu object
6898   gtk_menu_popup (GTK_MENU (item), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME);
6899 }
6900
6901 void MainFrame::OnDropGroupName()
6902 {
6903   /*
6904   char* name = DoNameDlg ("Name Selection");
6905
6906   if (name != NULL)
6907   {
6908     Select_Name (name);
6909     Sys_UpdateWindows (W_ALL);
6910     free (name);
6911   }
6912   */
6913 }
6914
6915 void MainFrame::OnDropGroupNewgroup()
6916 {
6917
6918 }
6919
6920 void MainFrame::OnDropGroupRemove()
6921 {
6922   /*
6923   Select_AddToGroup("World");
6924   Sys_UpdateWindows (W_ALL);
6925   */
6926 }
6927
6928 // NOTE: it's called OnFaceFit() but we want to process everything here, faces and patches
6929 void MainFrame::OnFaceFit()
6930 {
6931   SurfaceDlgFitAll();
6932 }
6933
6934 void MainFrame::OnDontselectmodel()
6935 {
6936   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_dontselectmodel"));
6937   g_bIgnoreCommands++;
6938   g_PrefsDlg.m_bSelectModels ^= 1;
6939   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bSelectModels) ? FALSE : TRUE);
6940   g_bIgnoreCommands--;
6941 }
6942
6943 void MainFrame::OnViewTexture()
6944 {
6945   if (FloatingGroupDialog()) // QE4 style
6946   {
6947     if (inspector_mode == W_TEXTURE)
6948     {
6949       if (GTK_WIDGET_VISIBLE (g_qeglobals_gui.d_entity))
6950         widget_delete_hide (g_qeglobals_gui.d_entity);
6951       else
6952         gtk_widget_show (g_qeglobals_gui.d_entity);
6953     } else
6954     {
6955       gtk_widget_show (g_qeglobals_gui.d_entity);
6956       SetInspectorMode (W_TEXTURE);
6957     }
6958   }
6959 }
6960
6961 void MainFrame::OnPatchInspector()
6962 {
6963   TogglePatchInspector();
6964 }
6965
6966 void MainFrame::OnCurveNegativeTextureX()
6967 {
6968   Patch_InvertTexture(false);
6969   //Sys_UpdateWindows(W_ALL);
6970 }
6971
6972 void MainFrame::OnCurveNegativeTextureY()
6973 {
6974   Patch_InvertTexture(true);
6975   //Sys_UpdateWindows(W_ALL);
6976 }
6977
6978 void MainFrame::OnCurveInsertcolumn()
6979 {
6980   if (&selected_brushes == selected_brushes.next)
6981     return;
6982   Undo_Start("insert colum");
6983   Undo_AddBrushList(&selected_brushes);
6984   //Patch_AdjustSelectedRowCols(0, 2);
6985   Patch_AdjustSelected(true, true, true);
6986   Sys_UpdateWindows(W_ALL);
6987   Undo_EndBrushList(&selected_brushes);
6988   Undo_End();
6989 }
6990
6991 void MainFrame::OnCurveInsertrow()
6992 {
6993   if (&selected_brushes == selected_brushes.next)
6994     return;
6995   Undo_Start("insert row");
6996   Undo_AddBrushList(&selected_brushes);
6997   //Patch_AdjustSelectedRowCols(2, 0);
6998   Patch_AdjustSelected(true, false, true);
6999   Sys_UpdateWindows(W_ALL);
7000   Undo_EndBrushList(&selected_brushes);
7001   Undo_End();
7002 }
7003
7004 void MainFrame::OnCurveDeletecolumn()
7005 {
7006   if (&selected_brushes == selected_brushes.next)
7007     return;
7008   Undo_Start("delete column");
7009   Undo_AddBrushList(&selected_brushes);
7010   Patch_AdjustSelected(false, true, true);
7011   Sys_UpdateWindows(W_ALL);
7012   Undo_EndBrushList(&selected_brushes);
7013   Undo_End();
7014 }
7015
7016 void MainFrame::OnCurveDeleterow()
7017 {
7018   if (&selected_brushes == selected_brushes.next)
7019     return;
7020   Undo_Start("delete row");
7021   Undo_AddBrushList(&selected_brushes);
7022   Patch_AdjustSelected(false, false, true);
7023   Sys_UpdateWindows(W_ALL);
7024   Undo_EndBrushList(&selected_brushes);
7025   Undo_End();
7026 }
7027
7028 void MainFrame::OnPatchTab()
7029 {
7030   if (g_bPatchBendMode)
7031     Patch_BendHandleTAB();
7032 //  else if (g_bPatchInsertMode)
7033 //    Patch_InsDelHandleTAB();
7034   else
7035   {
7036     // check to see if the selected brush is part of a func group
7037     // if it is, deselect everything and reselect the next brush
7038     // in the group
7039     brush_t *b2, *b = selected_brushes.next;
7040     entity_t * e;
7041     if (b != &selected_brushes)
7042     {
7043       if (strcmpi(b->owner->eclass->name, "worldspawn") != 0)
7044       {
7045         e = b->owner;
7046         Select_Deselect();
7047         for (b2 = e->brushes.onext ; b2 != &e->brushes ; b2 = b2->onext)
7048         {
7049           if (b == b2)
7050           {
7051             b2 = b2->onext;
7052             break;
7053           }
7054         }
7055         if (b2 == &e->brushes)
7056           b2 = b2->onext;
7057
7058         Select_Brush(b2, false);
7059         Sys_UpdateWindows(W_ALL);
7060       }
7061     }
7062   }
7063 }
7064
7065 void MainFrame::OnCameraForward(bool keydown)
7066 {
7067   if (g_PrefsDlg.m_bCamDiscrete && (m_pCamWnd && !m_pCamWnd->m_bFreeMove) )
7068   {
7069     if(keydown)
7070     {
7071       VectorMA (m_pCamWnd->Camera()->origin, SPEED_MOVE, m_pCamWnd->Camera()->forward, m_pCamWnd->Camera()->origin);
7072       int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA);
7073       Sys_UpdateWindows (nUpdate);
7074     }
7075   }
7076   else {
7077     if (keydown)
7078       m_pCamWnd->Camera()->movementflags |= MOVE_FORWARD;
7079     else
7080       m_pCamWnd->Camera()->movementflags &= ~MOVE_FORWARD;
7081   }
7082 }
7083
7084 void MainFrame::OnCameraBack(bool keydown)
7085 {
7086   if (g_PrefsDlg.m_bCamDiscrete && (m_pCamWnd && !m_pCamWnd->m_bFreeMove) )
7087   {
7088     if(keydown)
7089     {
7090       VectorMA (m_pCamWnd->Camera()->origin, -SPEED_MOVE, m_pCamWnd->Camera()->forward, m_pCamWnd->Camera()->origin);
7091       int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA);
7092       Sys_UpdateWindows (nUpdate);
7093     }
7094   }
7095   else {
7096     if (keydown)
7097       m_pCamWnd->Camera()->movementflags |= MOVE_BACK;
7098     else
7099       m_pCamWnd->Camera()->movementflags &= ~MOVE_BACK;
7100   }
7101 }
7102
7103 void MainFrame::OnCameraLeft(bool keydown)
7104 {
7105   if (m_pCamWnd)
7106   {
7107     if (m_pCamWnd->m_bFreeMove)
7108     {
7109       OnCameraStrafeleft(keydown);
7110       return;
7111     }
7112   }
7113
7114   if (g_PrefsDlg.m_bCamDiscrete)
7115   {
7116     if(keydown)
7117     {
7118       m_pCamWnd->Camera()->angles[1] += SPEED_TURN;
7119       int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA);
7120       Sys_UpdateWindows (nUpdate);
7121     }
7122   }
7123   else {
7124     if (keydown)
7125       m_pCamWnd->Camera()->movementflags |= MOVE_ROTLEFT;
7126     else
7127       m_pCamWnd->Camera()->movementflags &= ~MOVE_ROTLEFT;
7128   }
7129 }
7130
7131 void MainFrame::OnCameraRight(bool keydown)
7132 {
7133   if (m_pCamWnd)
7134   {
7135     if (m_pCamWnd->m_bFreeMove)
7136     {
7137       OnCameraStraferight(keydown);
7138       return;
7139     }
7140   }
7141
7142   if (g_PrefsDlg.m_bCamDiscrete)
7143   {
7144     if(keydown)
7145     {
7146       m_pCamWnd->Camera()->angles[1] -= SPEED_TURN;
7147       int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA);
7148       Sys_UpdateWindows (nUpdate);
7149     }
7150   }
7151   else {
7152     if (keydown)
7153       m_pCamWnd->Camera()->movementflags |= MOVE_ROTRIGHT;
7154     else
7155       m_pCamWnd->Camera()->movementflags &= ~MOVE_ROTRIGHT;
7156   }
7157 }
7158
7159 void MainFrame::OnCameraUp()
7160 {
7161   m_pCamWnd->Camera()->origin[2] += SPEED_MOVE;
7162   int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY | W_Z) : (W_CAMERA);
7163   Sys_UpdateWindows (nUpdate);
7164 }
7165
7166 void MainFrame::OnCameraDown()
7167 {
7168   m_pCamWnd->Camera()->origin[2] -= SPEED_MOVE;
7169   int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY | W_Z) : (W_CAMERA);
7170   Sys_UpdateWindows (nUpdate);
7171 }
7172
7173 void MainFrame::OnCameraAngleup()
7174 {
7175   m_pCamWnd->Camera()->angles[0] += SPEED_TURN;
7176   if (m_pCamWnd->Camera()->angles[0] > 85)
7177     m_pCamWnd->Camera()->angles[0] = 85;
7178   Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
7179 }
7180
7181 void MainFrame::OnCameraAngledown()
7182 {
7183   m_pCamWnd->Camera()->angles[0] -= SPEED_TURN;
7184   if (m_pCamWnd->Camera()->angles[0] < -85)
7185     m_pCamWnd->Camera()->angles[0] = -85;
7186   Sys_UpdateWindows (W_CAMERA|W_XY_OVERLAY);
7187 }
7188
7189 void MainFrame::OnCameraStrafeleft(bool keydown)
7190 {
7191   // FIXME: as soon as gtk supports proper keyup/down support, remove this bit
7192   if (m_pCamWnd)
7193   {
7194     if (!m_pCamWnd->m_bFreeMove)
7195     {
7196       if(keydown)
7197       {
7198         VectorMA (m_pCamWnd->Camera()->origin, -SPEED_MOVE, m_pCamWnd->Camera()->right, m_pCamWnd->Camera()->origin);
7199         int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA);
7200         Sys_UpdateWindows (nUpdate);
7201       }
7202       return;
7203     }
7204   }
7205
7206   if (keydown)
7207     m_pCamWnd->Camera()->movementflags |= MOVE_STRAFELEFT;
7208   else
7209     m_pCamWnd->Camera()->movementflags &= ~MOVE_STRAFELEFT;
7210 }
7211
7212 void MainFrame::OnCameraStraferight(bool keydown)
7213 {
7214   // FIXME: as soon as gtk supports proper keyup/down support, remove this bit
7215   if (m_pCamWnd)
7216   {
7217     if (!m_pCamWnd->m_bFreeMove)
7218     {
7219       if(keydown)
7220       {
7221         VectorMA (m_pCamWnd->Camera()->origin, SPEED_MOVE, m_pCamWnd->Camera()->right, m_pCamWnd->Camera()->origin);
7222         int nUpdate = (g_PrefsDlg.m_bCamXYUpdate) ? (W_CAMERA | W_XY) : (W_CAMERA);
7223         Sys_UpdateWindows (nUpdate);
7224       }
7225       return;
7226     }
7227   }
7228
7229   if (keydown)
7230     m_pCamWnd->Camera()->movementflags |= MOVE_STRAFERIGHT;
7231   else
7232     m_pCamWnd->Camera()->movementflags &= ~MOVE_STRAFERIGHT;
7233 }
7234
7235 void MainFrame::OnGridToggle()
7236 {
7237   g_qeglobals.d_showgrid = !g_qeglobals.d_showgrid;
7238   Sys_UpdateWindows (W_XY|W_Z);
7239 }
7240
7241 void MainFrame::OnViewCrosshair()
7242 {
7243   g_bCrossHairs ^= 1;
7244   Sys_UpdateWindows (W_XY);
7245 }
7246
7247 void MainFrame::OnSelectionTextureRotateclock()
7248 {
7249   Select_RotateTexture(abs(g_PrefsDlg.m_nRotation));
7250 }
7251
7252 void MainFrame::OnSelectionTextureRotatecounter()
7253 {
7254   Select_RotateTexture(-abs(g_PrefsDlg.m_nRotation));
7255 }
7256
7257 void MainFrame::OnSelectionTextureScaleup()
7258 {
7259   Select_ScaleTexture(0, g_qeglobals.d_savedinfo.m_SIIncrement.scale[1]);
7260 }
7261
7262 void MainFrame::OnSelectionTextureScaledown()
7263 {
7264   Select_ScaleTexture(0, -g_qeglobals.d_savedinfo.m_SIIncrement.scale[1]);
7265 }
7266
7267 void MainFrame::OnSelectionTextureScaleLeft()
7268 {
7269   Select_ScaleTexture(-g_qeglobals.d_savedinfo.m_SIIncrement.scale[0],0);
7270 }
7271
7272 void MainFrame::OnSelectionTextureScaleRight()
7273 {
7274   Select_ScaleTexture(g_qeglobals.d_savedinfo.m_SIIncrement.scale[0],0);
7275 }
7276
7277 void MainFrame::OnSelectionTextureShiftleft()
7278 {
7279   Select_ShiftTexture((int)-g_qeglobals.d_savedinfo.m_SIIncrement.shift[0], 0);
7280 }
7281
7282 void MainFrame::OnSelectionTextureShiftright()
7283 {
7284   Select_ShiftTexture((int)g_qeglobals.d_savedinfo.m_SIIncrement.shift[0], 0);
7285 }
7286
7287 void MainFrame::OnSelectionTextureShiftup()
7288 {
7289   Select_ShiftTexture(0, (int)g_qeglobals.d_savedinfo.m_SIIncrement.shift[1]);
7290 }
7291
7292 void MainFrame::OnSelectionTextureShiftdown()
7293 {
7294   Select_ShiftTexture(0, (int)-g_qeglobals.d_savedinfo.m_SIIncrement.shift[1]);
7295 }
7296
7297 void MainFrame::OnGridPrev()
7298 {
7299   GtkWidget *item;
7300   if (g_qeglobals.d_gridsize == 1)
7301   {
7302     g_qeglobals.d_gridsize = 0.5;
7303     g_qeglobals.d_bSmallGrid = true;
7304     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_05"));
7305   } else if (g_qeglobals.d_gridsize == 0.5)
7306   {
7307     g_qeglobals.d_gridsize = 0.25;
7308     g_qeglobals.d_bSmallGrid = true;
7309     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_025"));
7310   } else if (g_qeglobals.d_gridsize > 1)
7311   {
7312     g_qeglobals.d_gridsize = (int)g_qeglobals.d_gridsize >> 1;
7313     g_qeglobals.d_bSmallGrid = false;
7314
7315     switch ((int)g_qeglobals.d_gridsize)
7316     {
7317     case  1: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_1")); break;
7318     case  2: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_2")); break;
7319     case  4: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_4")); break;
7320     case  8: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_8")); break;
7321     case  16: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_16")); break;
7322     case  32: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_32")); break;
7323     case  64: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_64")); break;
7324     case 128: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_128")); break;
7325     case 256: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_256")); break;
7326     }
7327
7328   } else
7329     return;
7330
7331   // SnapTToGrid option: need to check everywhere the grid size is changed
7332   // this is a bit clumsy, have to do in OnGrid OnGridPrev and OnGridNext
7333   if (g_PrefsDlg.m_bSnapTToGrid)
7334     DoSnapTToGrid();
7335
7336   SetGridStatus();
7337   g_bIgnoreCommands++;
7338   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7339   g_bIgnoreCommands--;
7340
7341   Sys_UpdateWindows(W_XY | W_Z);
7342 }
7343
7344 void MainFrame::OnGridNext()
7345 {
7346   GtkWidget *item;
7347   if (g_qeglobals.d_gridsize == 0.25)
7348   {
7349     g_qeglobals.d_gridsize = 0.5;
7350     g_qeglobals.d_bSmallGrid = true;
7351     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_05"));
7352   } else if (g_qeglobals.d_gridsize == 0.5)
7353   {
7354     g_qeglobals.d_gridsize = 1;
7355     g_qeglobals.d_bSmallGrid = false;
7356     item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_1"));
7357   } else if (g_qeglobals.d_gridsize < 256)
7358   {
7359     g_qeglobals.d_gridsize = (int)g_qeglobals.d_gridsize << 1;
7360     g_qeglobals.d_bSmallGrid = false;
7361
7362     switch ((int)g_qeglobals.d_gridsize)
7363     {
7364     case  1: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_1")); break;
7365     case  2: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_2")); break;
7366     case  4: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_4")); break;
7367     case  8: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_8")); break;
7368     case  16: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_16")); break;
7369     case  32: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_32")); break;
7370     case  64: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_64")); break;
7371     case 128: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_128")); break;
7372     case 256: item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_grid_256")); break;
7373         default:  item = NULL;
7374     }
7375
7376   } else
7377     return;
7378
7379   // SnapTToGrid option: need to check everywhere the grid size is changed
7380   // this is a bit clumsy, have to do in OnGrid OnGridPrev and OnGridNext
7381   if (g_PrefsDlg.m_bSnapTToGrid)
7382     DoSnapTToGrid();
7383
7384   SetGridStatus();
7385   g_bIgnoreCommands++;
7386   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7387   g_bIgnoreCommands--;
7388
7389   Sys_UpdateWindows(W_XY | W_Z);
7390 }
7391
7392 void MainFrame::OnSelectionMovedown()
7393 {
7394   if (&selected_brushes == selected_brushes.next)
7395     return;
7396   Undo_Start("move down");
7397   Undo_AddBrushList(&selected_brushes);
7398
7399   vec3_t vAmt;
7400   vAmt[0] = vAmt[1] = 0.0;
7401   vAmt[2] = -g_qeglobals.d_gridsize;
7402   Select_Move (vAmt);
7403   Sys_UpdateWindows(W_CAMERA | W_XY | W_Z);
7404
7405   Undo_EndBrushList(&selected_brushes);
7406   Undo_End();
7407 }
7408
7409 void MainFrame::OnSelectionMoveup()
7410 {
7411   if (&selected_brushes == selected_brushes.next)
7412     return;
7413   Undo_Start("move up");
7414   Undo_AddBrushList(&selected_brushes);
7415
7416   vec3_t vAmt;
7417   vAmt[0] = vAmt[1] = 0.0;
7418   vAmt[2] = g_qeglobals.d_gridsize;
7419   Select_Move (vAmt);
7420   Sys_UpdateWindows(W_CAMERA | W_XY | W_Z);
7421
7422   Undo_EndBrushList(&selected_brushes);
7423   Undo_End();
7424 }
7425
7426 void MainFrame::OnSelectionPrint()
7427 {
7428   for (brush_t* b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
7429     Brush_Print(b);
7430 }
7431
7432 void MainFrame::OnSelectionTogglesizepaint()
7433 {
7434   g_PrefsDlg.m_bSizePaint = !g_PrefsDlg.m_bSizePaint;
7435   Sys_UpdateWindows(W_XY);
7436 }
7437
7438 void MainFrame::OnPatchNaturalize()
7439 {
7440   Patch_NaturalizeSelected();
7441   Sys_UpdateWindows (W_ALL);
7442 }
7443
7444 void MainFrame::OnSnapToGrid()
7445 {
7446   if (&selected_brushes == selected_brushes.next)
7447     return;
7448   Undo_Start("snap selection to grid");
7449   Undo_AddBrushList(&selected_brushes);
7450   //Select_SnapToGrid();
7451   for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next)
7452   {
7453     if (pb->patchBrush)
7454       Patch_SnapToGrid(pb->pPatch);
7455     else
7456       Brush_SnapToGrid(pb);
7457   }
7458   Sys_UpdateWindows (W_ALL);
7459   Undo_EndBrushList(&selected_brushes);
7460   Undo_End();
7461 }
7462
7463 void MainFrame::OnSelectAll()
7464 {
7465   Select_AllOfType();
7466 }
7467
7468 void MainFrame::OnSelectionInvert()
7469 {
7470   Select_Invert();
7471   Sys_UpdateWindows(W_XY | W_Z | W_CAMERA);
7472 }
7473
7474
7475 void PerformFiltering ()
7476 {
7477   brush_t *brush;
7478
7479   // mattn - this should be removed - otherwise the filters from the
7480   // plugins are wiped away with each update
7481 #if 0
7482   // spog - deletes old filters list and creates new one when
7483   // g_qeglobals.d_savedinfo.exclude is updated
7484   g_qeglobals.d_savedinfo.filters = FilterListDelete(g_qeglobals.d_savedinfo.filters);
7485   g_qeglobals.d_savedinfo.filters = FilterUpdate(g_qeglobals.d_savedinfo.filters);
7486 #endif
7487
7488   for ( brush = active_brushes.next; brush != &active_brushes; brush = brush->next )
7489     brush->bFiltered = FilterBrush( brush );
7490
7491   for ( brush = selected_brushes.next; brush != &selected_brushes; brush = brush->next )
7492     brush->bFiltered = FilterBrush( brush );
7493 }
7494
7495 void MainFrame::OnFilterAreaportals()
7496 {
7497   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_areaportals"));
7498   g_bIgnoreCommands++;
7499   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_AREAPORTALS) & EXCLUDE_AREAPORTALS)
7500     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7501   else
7502     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7503   g_bIgnoreCommands--;
7504   PerformFiltering();
7505   Sys_UpdateWindows (W_XY|W_CAMERA);
7506 }
7507
7508 void MainFrame::OnFilterCaulk()
7509 {
7510   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_caulk"));
7511   g_bIgnoreCommands++;
7512   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CAULK) & EXCLUDE_CAULK)
7513     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7514   else
7515     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7516   g_bIgnoreCommands--;
7517   PerformFiltering();
7518   Sys_UpdateWindows (W_XY|W_CAMERA);
7519 }
7520
7521 void MainFrame::OnFilterClips()
7522 {
7523   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_clips"));
7524   g_bIgnoreCommands++;
7525   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CLIP) & EXCLUDE_CLIP)
7526     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7527   else
7528     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7529   g_bIgnoreCommands--;
7530   PerformFiltering();
7531   Sys_UpdateWindows (W_XY|W_CAMERA);
7532 }
7533
7534 void MainFrame::OnFilterBotClips()
7535 {
7536   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_botclips"));
7537   g_bIgnoreCommands++;
7538   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_BOTCLIP) & EXCLUDE_BOTCLIP)
7539     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7540   else
7541     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7542   g_bIgnoreCommands--;
7543   PerformFiltering();
7544   Sys_UpdateWindows (W_XY|W_CAMERA);
7545 }
7546
7547 void MainFrame::OnFilterStructural()
7548 {
7549   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_structural"));
7550   g_bIgnoreCommands++;
7551   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_STRUCTURAL) & EXCLUDE_STRUCTURAL)
7552     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7553   else
7554     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7555   g_bIgnoreCommands--;
7556   PerformFiltering();
7557   Sys_UpdateWindows (W_XY|W_CAMERA);
7558 }
7559
7560 void MainFrame::OnFilterDetails()
7561 {
7562   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_details"));
7563   g_bIgnoreCommands++;
7564   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_DETAILS) & EXCLUDE_DETAILS)
7565     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7566   else
7567     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7568   g_bIgnoreCommands--;
7569   PerformFiltering();
7570   Sys_UpdateWindows (W_XY|W_CAMERA);
7571 }
7572
7573 void MainFrame::OnFilterEntities()
7574 {
7575   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_entities"));
7576   g_bIgnoreCommands++;
7577   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_ENT) & EXCLUDE_ENT)
7578     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7579   else
7580     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7581   g_bIgnoreCommands--;
7582   PerformFiltering();
7583   Sys_UpdateWindows (W_XY|W_CAMERA);
7584 }
7585
7586 void MainFrame::OnFilterHintsskips()
7587 {
7588   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_hintsskips"));
7589   g_bIgnoreCommands++;
7590   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_HINTSSKIPS) & EXCLUDE_HINTSSKIPS)
7591     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7592   else
7593     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7594   g_bIgnoreCommands--;
7595   PerformFiltering();
7596   Sys_UpdateWindows (W_XY|W_CAMERA);
7597 }
7598
7599 void MainFrame::OnFilterLights()
7600 {
7601   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_lights"));
7602   g_bIgnoreCommands++;
7603   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_LIGHTS) & EXCLUDE_LIGHTS)
7604     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7605   else
7606     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7607   g_bIgnoreCommands--;
7608   PerformFiltering();
7609   Sys_UpdateWindows (W_XY|W_CAMERA);
7610 }
7611
7612 void MainFrame::OnFilterLiquids()
7613 {
7614   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_liquids"));
7615   g_bIgnoreCommands++;
7616   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_LIQUIDS) & EXCLUDE_LIQUIDS)
7617     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7618   else
7619     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7620   g_bIgnoreCommands--;
7621   PerformFiltering();
7622   Sys_UpdateWindows (W_XY|W_CAMERA);
7623 }
7624
7625 void MainFrame::OnFilterModels()
7626 {
7627   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_models"));
7628   g_bIgnoreCommands++;
7629   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_MODELS) & EXCLUDE_MODELS)
7630     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7631   else
7632     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7633   g_bIgnoreCommands--;
7634   PerformFiltering();
7635   Sys_UpdateWindows (W_XY|W_CAMERA);
7636 }
7637
7638 void MainFrame::OnFilterPatches()
7639 {
7640   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_patches"));
7641   g_bIgnoreCommands++;
7642   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CURVES) & EXCLUDE_CURVES)
7643     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7644   else
7645     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7646   g_bIgnoreCommands--;
7647   PerformFiltering();
7648   Sys_UpdateWindows (W_XY|W_CAMERA);
7649 }
7650
7651 void MainFrame::OnFilterPaths()
7652 {
7653   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_paths"));
7654   g_bIgnoreCommands++;
7655   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_PATHS) & EXCLUDE_PATHS)
7656     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7657   else
7658     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7659   g_bIgnoreCommands--;
7660   PerformFiltering();
7661   Sys_UpdateWindows (W_XY|W_CAMERA);
7662 }
7663
7664 void MainFrame::OnFilterClusterportals()
7665 {
7666   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_clusterportals"));
7667   g_bIgnoreCommands++;
7668   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_CLUSTERPORTALS) & EXCLUDE_CLUSTERPORTALS)
7669     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7670   else
7671     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7672   g_bIgnoreCommands--;
7673   PerformFiltering();
7674   Sys_UpdateWindows (W_XY|W_CAMERA);
7675 }
7676
7677 void MainFrame::OnFilterLightgrid()
7678 {
7679   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_lightgrid"));
7680   g_bIgnoreCommands++;
7681   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_LIGHTGRID) & EXCLUDE_LIGHTGRID)
7682     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7683   else
7684     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7685   g_bIgnoreCommands--;
7686   PerformFiltering();
7687   Sys_UpdateWindows (W_XY|W_CAMERA);
7688 }
7689
7690 void MainFrame::OnFilterTranslucent()
7691 {
7692   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_translucent"));
7693   g_bIgnoreCommands++;
7694   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_TRANSLUCENT) & EXCLUDE_TRANSLUCENT)
7695     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7696   else
7697     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7698   g_bIgnoreCommands--;
7699   PerformFiltering();
7700   Sys_UpdateWindows (W_XY|W_CAMERA);
7701 }
7702
7703 void MainFrame::OnFilterTriggers()
7704 {
7705   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_triggers"));
7706   g_bIgnoreCommands++;
7707   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_TRIGGERS) & EXCLUDE_TRIGGERS)
7708     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7709   else
7710     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7711   g_bIgnoreCommands--;
7712   PerformFiltering();
7713   Sys_UpdateWindows (W_XY|W_CAMERA);
7714 }
7715
7716 void MainFrame::OnFilterWorld()
7717 {
7718   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_filter_world"));
7719   g_bIgnoreCommands++;
7720   if ((g_qeglobals.d_savedinfo.exclude ^= EXCLUDE_WORLD) & EXCLUDE_WORLD)
7721     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
7722   else
7723     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), FALSE);
7724   g_bIgnoreCommands--;
7725   PerformFiltering();
7726   Sys_UpdateWindows (W_XY|W_CAMERA);
7727 }
7728
7729
7730
7731
7732
7733
7734
7735
7736 // =============================================================================
7737 // leo: Unused functions, not called anywhere from the code (need to check)
7738
7739 void MainFrame::OnViewConsole()
7740 {
7741   if (FloatingGroupDialog()) // QE4 style
7742   {
7743     if (inspector_mode == W_CONSOLE && CurrentStyle() != MainFrame::eFloating) // are we in console mode already?
7744     {
7745       if (GTK_WIDGET_VISIBLE (g_qeglobals_gui.d_entity))
7746         widget_delete_hide (g_qeglobals_gui.d_entity);
7747       else
7748         gtk_widget_show (g_qeglobals_gui.d_entity);
7749     } else
7750     {
7751       gtk_widget_show (g_qeglobals_gui.d_entity);
7752       SetInspectorMode(W_CONSOLE);
7753     }
7754   }
7755 }
7756
7757 void MainFrame::OnCurveFreeze()
7758 {
7759   Patch_Freeze();
7760 }
7761
7762 void MainFrame::OnCurveUnFreeze()
7763 {
7764   Patch_UnFreeze(false);
7765 }
7766
7767 void MainFrame::OnCurveUnFreezeAll()
7768 {
7769   Patch_UnFreeze(true);
7770 }
7771
7772 void MainFrame::OnSelectReselect()
7773 {
7774   Select_Reselect();
7775 }
7776
7777 void MainFrame::OnSelectionTextureFit()
7778 {
7779   // TODO: Add your command handler code here
7780 }
7781
7782 void MainFrame::OnPatchEnter()
7783 {
7784
7785 }
7786
7787 void MainFrame::OnDropGroupAddtoWorld()
7788 {
7789   /*
7790   Select_AddToGroup("World");
7791   Sys_UpdateWindows (W_ALL);
7792   */
7793 }